Damn!After uninstall pytest-appium,everything works well。
独立出来执行这部分代码:
import time
from appium import webdriver
from appium.webdriver.webdriver import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy
appium_options = AppiumOptions()
desired_caps ={
"platformName": "Android",
"newCommonTimeout": 7200,
"skipServerInstallation": True,
"automationName": "UiAutomator2",
"systemPort": 8200,
# "noReset": True,
# "fullReset": False,
"deviceName": "62b6aca8",
"platformVersion": "10",
"appPackage": "com.xkw.client",
"appActivity": "com.zxxk.page.main.LauncherActivity"
}
appium_options.load_capabilities(desired_caps)
driver = webdriver.Remote('http://127.0.0.1:4723', options=appium_options)
print(f"Session ID: ({driver.session_id})")
time.sleep(6)
agree = driver.find_element(AppiumBy.ID, "com.xkw.client:id/agree_yes")
agree.click()
time.sleep(10)
mine = driver.find_element(AppiumBy.ID, "com.xkw.client:id/mine_text")
mine.click()
driver.quit()
运行结果如下:
C:\Python312\python.exe F:/workspace/MobileAppTestFramework/sample_test.py
Session ID: (8a9fc17d-b4da-467f-bff6-43516e0f13b8)
Process finished with exit code 0
APP GUI 页面点击 OK,说明 driver 初始化是 OK 的
不是很确定你的具体状况了,是否并没有获取到值,所以才展示为 null,是否可以付个初始值,如果没获取到就展示你的初始值,这样方便你定位问题
Email 里是无法正常展示 html link 的,这个是 email 自身基于安全考量做的限制的。
如果你想展示,建议在 jenkins 的 email 模板下,放自定义的 email 模板,在模板中将要展示的 link,最好是 link 到具体的图片,这样这个图片是可以正常在 email 里展示的,而这些图片,jenkins allure report 中是有的
我是这么展示的:
在 Email 中增加解析处理 allure 生成的文件,将处理的结果在 email 里展示,同时将历史趋势那个图,也放在 email 里发出去,这个图实际是一个 link,link 到 Jenkins server 对应 project 的 allure
试试:
set timeout 120
set password [lindex $argv 0]
expect {
"(yes/no)?" { send "yes\r"; exp_continue}
"password:" { send "$password\r" }
}
expect eof
建议 debug,吐出稍微详细一些的 stdout、stderr
Summary 一下 Allure Summary Email using Email-ext Jenkins Plugin,具体操作如下:
Jenkins 在发送邮件时,在设置 E-mail 触发里,有一个 Content,在 Content 对应地方,填写如下内容:${SCRIPT, template="allure-report.groovy"}, 如下图所示:
allure-report.groovy 脚本放在哪儿呢? 放在 $JENKINS_HOME/email-templates 目录下,我当前 Jenkins 环境存放路径如下:
jenkins@ubuntu-16:~/email-templates$ ls -l
total 20
-rw-rw-r-- 1 jenkins jenkins 5697 Mar 27 16:30 allure-report.groovy
-rw-rw-r-- 1 jenkins jenkins 10764 Jun 17 2019 email-template.groovy
jenkins@ubuntu-16:~/email-templates$ pwd
/var/lib/jenkins/email-templates
jenkins@ubuntu-16:~/email-templates$
email-template.groovy 应该是 Robot Framework 某个插件生成的(我猜测的,vi 里面看到很多关于 RF 的,正好当前 Jenkins 里也有 RF 的 project 在跑)。
allure-report.groovy 脚本内容如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<style type="text/css">
/*base css*/
body
{
margin: 0px;
padding: 15px;
}
body, td, th
{
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Tahoma, sans-serif;
font-size: 10pt;
}
th
{
text-align: left;
}
h1
{
margin-top: 0px;
}
a
{
color:#4a72af
}
/*div styles*/
.status{background-color:<%=
build.result.toString() == "SUCCESS" ? 'green' : 'red' %>;font-size:28px;font-weight:bold;color:white;width:720px;height:52px;margin-bottom:18px;text-align:center;vertical-align:middle;border-collapse:collapse;background-repeat:no-repeat}
.status .info{color:white!important;text-shadow:0 -1px 0 rgba(0,0,0,0.3);font-size:32px;line-height:36px;padding:8px 0}
</style>
<body>
<div class="content round_border">
<div class="status">
<p class="info">pytest automation build <%= build.result.toString().toLowerCase() %></p>
</div>
<!-- status -->
<table>
<tbody>
<tr>
<th>Project:</th>
<td>${project.name}</td>
</tr>
<tr>
<th>Build ${build.displayName}:</th>
<td><a
href="${rooturl}${build.url}">${rooturl}${build.url}</a></td>
</tr>
<tr>
<th>Product Version:</th>
<td><%=build.environment['PRODUCT_VERSION']%></td>
</tr>
<tr>
<th>Date of build:</th>
<td>${it.timestampString}</td>
</tr>
<tr>
<th>Build duration:</th>
<td>${build.durationString}</td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
</tbody>
</table>
<!-- main -->
<% def artifacts = build.artifacts
if(artifacts != null && artifacts.size() > 0) { %>
<b>Build Artifacts:</b>
<ul>
<% artifacts.each() { f -> %>
<li><a href="${rooturl}${build.url}artifact/${f}">${f}</a></li>
<% } %>
</ul>
<% } %>
<!-- artifacts -->
<%
lastAllureReportBuildAction = build.getAction(ru.yandex.qatools.allure.jenkins.AllureReportBuildAction.class)
lastAllureBuildAction = build.getAction(ru.yandex.qatools.allure.jenkins.AllureBuildAction.class)
if (lastAllureReportBuildAction) {
allureResultsUrl = "${rooturl}${build.url}allure"
allureLastBuildSuccessRate = String.format("%.2f", lastAllureReportBuildAction.getPassedCount() * 100f / lastAllureReportBuildAction.getTotalCount())
}
%>
<% if (lastAllureReportBuildAction) { %>
<h2>Allure Results</h2>
<table>
<tbody>
<tr>
<th>Total Allure tests run:</th>
<td><a href="${allureResultsUrl}">${lastAllureReportBuildAction.getTotalCount()}</a></td>
</tr>
<tr>
<th><span style="color: #000000; background-color: #ffff00;">Failed:</span></th>
<td><span style="color: #000000; background-color: #ffff00;">${lastAllureReportBuildAction.getFailedCount()} </span></td>
</tr>
<tr>
<th><span style="color: #000000; background-color: #008000;">Passed:</span></th>
<td><span style="color: #000000; background-color: #008000;">${lastAllureReportBuildAction.getPassedCount()} </span></td>
</tr>
<tr>
<th><span style="color: #000000; background-color: #3366ff;">Skipped:</span></th>
<td><span style="color: #000000; background-color: #3366ff;">${lastAllureReportBuildAction.getSkipCount()} </span></td>
</tr>
<tr>
<th><span style="color: #000000; background-color: #ff0000;">Broken:</span></th>
<td><span style="color: #000000; background-color: #ff0000;">${lastAllureReportBuildAction.getBrokenCount()} </span></td>
</tr>
<tr>
<th>Success rate: </th>
<td>${allureLastBuildSuccessRate}% </td>
</tr>
</tbody>
</table>
<img lazymap="${allureResultsUrl}/graphMap" src="${allureResultsUrl}/graph" alt="Allure results trend"/>
<% } %>
<!-- content -->
<!-- bottom message -->
</body>
注意:
脚本内容中有一个 PRODUCT_VERSION 变量,这个是我私有变量,可以通过 ‘Inject environment vairables’ 来定义:
最终邮件效果图如下:
Jenkins 发的 Email 是含有具体的测试结果的,展示了 build 环境信息以及 total、pass、fail、broken 等数据,但我更想在这些数据之下,把 Jenkins 对应 build 的 Allure 所展示的 web 界面信息,也体现在邮件里
放弃这种思路,邮箱基于安全考虑(防止挂马),不支持 mail 中展示 iframe
我以为用 iframe 能解决,单独打开 jenkins 里的 email(拷贝内容后命名为 show_allure_in_jenkins_mail.html)是 OK 的,但是从邮件(使用过 Outlook 和 foxmail)打开,就不展示了,对应的 iframe 显示一片空白区域。。。
问题已经,在 pytest.ini 文件中,增加了 log_format && log_data_format
log_format = %(asctime) s [%(filename) s:%(lineno)-4s] [%(levelname) 5s] %(message) s
log_date_format=%Y-%m-%d %H:%M:%S
没有单独写一个 log 模块,使用的 pytest.ini,在里面定义了 log 格式:
[pytest]
log_cli = true
log_level = NOTSET
log_file = ../report/xxx.log
log_file_format = [%(filename)s:%(lineno)-4s] [%(levelname)5s] %(asctime)s %(message)s
log_file_date_format=%Y-%m-%d %H:%M:%S
log_cli_level = INFO
log_cli_format = %(asctime)s [%(filename)s:%(lineno)-4s] [%(levelname)5s] %(message)s
log_cli_date_format=%Y-%m-%d %H:%M:%S
没有达到预期的效果。。。。
估计更多的可能是使用上的问题,解释如下:
allure 使用了两种方式来渲染页面,分别是 allure open 和 allure serve。前者用于在本地渲染和查看结果,后者用于在本地渲染后对外展示结果,所以要想查看有数据的 html 内容,需要使用 allure open。运行命令 allure open allure-report 即可自动打开浏览器(耐心等待一下)展示渲染好的结果,其中 allure-report 为 allure generate 生成的结果所在目录。
使用 Fiddler 吧
我的测试报告,python 的,应该美观点
感谢大家,其实只需要 web 界面推送一点点东西,也就是一个任务吧,其他的 app 端功能都齐备。 我就临时使用 selenium 解决了 web 推送任务到 app 这个问题,毕竟就一个用例(一个创建然后发布的动作就 OK 了)。
#3 楼 @xuxiujin 是不是开发人员没有在 UI 界面中增加元素信息? 实在获取不到,可以通过获取图片所在的坐标,然后进行点击操作,以达到你想要的操作效果。
先获取屏幕分辨率,然后再设置坐标
##获取手机屏幕分辨率
x = self.driver.get_window_size()['width']
y = self.driver.get_window_size()['height']
x = int(x*0.1)
y = int(y*0.1)
self.driver.tap([(x,y),])
其中 x/y 为你的 UI 界面上想要点击的图片对应的坐标。
如果想获取坐标数据,安卓手机,可以在开发者选项中打开指针位置。
#13 楼 @sophia_sun1191 楼上正解,我在一楼回复的时候就贴了 tap 的 usage 方法:driver.tap([(100, 20), (100, 60), (100, 100)], 500),表示模拟 3 个坐标(也就是 3 个手指),持续时间 500 毫秒
def test_someActions(self):
sleep(8)
buttons = self.driver.find_elements_by_class_name("android.widget.Button")
buttons[1].click()
self.driver.tap([(65,10),])
#11 楼 @sophia_sun1191 你报的是 python 的语法错误,int 类型没有 id 这个属性,是你代码上的问题,语法有问题了,莫抱怨 tap 的问题。
#6 楼 @sophia_sun1191 他的意思是给了你 java 语言实现点击操作的参考,用的是 tap 方法,而不是要你去使用 python 语言去实现这个功能。
贴出代码与更详细的日志,别人才能帮你的吧。贴吧,骚年
你可以在开发者选项中打开指针位置,这样就很容易去获取界面上各个图标的具体位置了。建议是先获取手机分辨率,然后根据分辨率去计算要点击的位置。
点击操作 driver 有 click() 方法,如果没有 className 或者 resource-id,使用 swipe 方法,参考如下:
## 获取手机屏幕分辨率
x = self.driver.get_window_size()['width']
y = self.driver.get_window_size()['height']
x = int(x*0.1)
y = int(y*0.1)
self.driver.swipe(x, y, x, y,1)
# 这里的 xy 就是你 UI 界面上图标对应的坐标,时间非常短,1 毫秒,模拟点击了。
如果别人有更好的方法,你就用别人的,仅供参考。
当然 tap 也可以,doc如下:
"""Taps on an particular place with up to five fingers, holding
for a
certain time
:Args:
- positions - an array of tuples representing the x/y
coordinates of
the fingers to tap. Length can be up to five.
- duration - (optional) length of time to tap, in ms
:Usage:
driver.tap([(100, 20), (100, 60), (100, 100)], 500)
"""
感谢大家的答复,如大家所言,的确是个 bug,先降级使用 appium,等问题解决了,后面再升级回来。