0910 UPDATE

新增控件集参数化,相同测试步骤的Android/iOS可共用一份测试用例

不同测试步骤的用例还需要单独写

0904 UPDATE

优化Android log及crsahinfo相关输出路径

新增iOS crashreport解析

新增内容:

适配iOS

提取android crash信息

优化report(增加自动填充包名,app名称,版本,bundleId等信息)

简介

采用python3+appium1.8,基于PageObject框架的UI自动化测试持续集成。

unittest参数化

PageObject分层管理

用例编写基于yaml配置多关键字驱动

自动生成excel测试报告

同时支持Android/iOS

支持多设备执行

支持Windows/Mac OS (iOS必须使用Mac OS)

目录结构

1.app

待测apk/ipa 安装包路径

uiautomator2等安装包路径

2.Base

Android 测试相关:

BaseAdb.py

BaseAndroidPhone.py

BaseApk.py

BaseLog.py

BaseLogcat.py

iOS 测试相关:

BaseIosPhone.py

BaseIpa.py

BaseIosLog.py

数据处理相关:

BaseConfig.py

BaseExcel.py

BaseFile.py

BasePickle.py

BaseYaml.py

BaseOperate.py

BaseReplace.py

测试执行相关:

BaseAppiumServer.py

BaseInit.py

BaseRunner.py

BaseElements.py

报告相关:

BaseStatisics.py

BaseError.py

BaseEmail.py

3. iOSCrashAnalysis

iOS crash report  解析相关:

BaseIosCrash.py 解析脚本

FileOperate.py 文件操作相关

symbolicatecrash xCode自带的解析工具,获取方式:find /Applications/Xcode.app -name symbolicatecrash -type f,复制过来就行了

4.Log

设备日志及持久化数据

操作日志,失败截图

crash解析结果

5.PageObject

操作的封装及测试结果统计

测试用例模块分级

6.其他

../Report =====测试报告

../Runner =====执行文件

../TestCase =====测试用例集

../yamls =====用例管理

主要功能

1.基础测试类及方法

获取apk/ipa安装包信息

获取Android/iOS设备信息

自动分配端口并启动appiumserver

设备日志及crashlog分析

失败重试

失败截图

报告统计及输出

邮件发送

case管理

常用操作封装

其他

2.yaml编写说明

testinfo: 表示用例介绍

- id: 用例id

- title: 用例标题

- info: 前置条件

testcase: 用例的执行步骤

- element_info: //XCUIElementTypeStaticText[@name="剪辑"] 元素

- find_type: id 元素类型

- id

- xpath

- name

- text

- ids 需要增加index

- index 和ids/xpaths/texts等配合

- class_name

- ios_id

- predicate

- operate_type: click 操作

- click

- swipe_down

- swipe_up

- get_value

- set_value

- screen_tap

- swipe_left

- swipe_right

- msg 传给set_value关键字

- adb_tab 使用adb中的tab命令点击元素,元素必须可识别,应用于悬浮层场景

- get_content_desc 无法切换到webview时,用此关键字

- press_key_code 键盘触发事件,需要传code

- code 传给press_key_code关键字

- is_webview:1 为1表示切换到webview,为2表示切换到原生

- 其他关键字 用于定制一些特殊业务

- is_time: 3 自定义暂停3秒

- info: 点击动态列表第一条数据 操作步骤介绍

- check: 检查点,支持多检查点

- element_info: //XCUIElementTypeStaticText[@name="剪辑"]

- find_type: ids

- index: 0

- operate_type:

- contrary" 相反检查点,表示如果检查元素存在就说明失败,如删除后,此元素依然存在

- contrary_getval 检查点关键字contrary_getval: 相反值检查点,如果对比成功,说明失败

- default_check 默认检查点,就是查找页面元素

- compare 历史数据和实际数据对比

- toast toast检查

- info: 查找是否存在历史记录

3.yaml实例

==========================================================

testinfo:

- id: home_test_001

title: 启动app并进入gallery

info: 打开app并点击高级编辑

testcase:

- element_info: camerta_n

find_type: ios_id

operate_type: click

info: 点击创作中心主按钮

- element_info: //XCUIElementTypeStaticText[@name="剪辑"]

find_type: xpath

operate_type: click

info: 点击剪辑按钮

- element_info: 跳过

find_type: name

operate_type: click

info: 跳过升级页面

- element_info: //XCUIElementTypeStaticText[@name="剪辑"]

find_type: xpath

operate_type: click

info: 点击剪辑按钮

- element_info: 好

find_type: name

operate_type: click

info: 授权存储

- element_info: 好

find_type: name

operate_type: click

info: 授权相册

check:

- element_info: //XCUIElementTypeButton[@name="下一步"]

find_type: xpath

check: default_check

info: 进入'Gallery'页面成功

4.某个用例的page层

from PageObject import Pages

class PageOperate:

def __init__(self, kwargs):

_init = {"driver": kwargs["driver"], "test_msg": getYam(kwargs["path"]), "device": kwargs["device"],

"logTest": kwargs["logTest"], "platformName": kwargs["platformName"],"caseName": kwargs["caseName"]}

self.page = Pages.PagesObjects(_init)

def operate(self): # 操作步骤

self.page.operate()

def checkPoint(self): # 检查点

self.page.checkPoint()

5.testcase层调用page层

tc_temp = PATH("../yamls/temp.yaml")

el_android = PATH("../yamls/el_android.yaml")

el_iOS = PATH("../yamls/el_iOS.yaml")

class HomeTest(ParametrizedTestCase):

def repalce(self, tc, tc_temp):#用了最笨的替换字符串方法,输出一个临时temp.yaml文件,测试完成后再删除

if self.platformName == 'android':

ReplaceYaml(tc, tc_temp, el_android)

elif self.platformName == 'iOS':

ReplaceYaml(tc, tc_temp, el_iOS)

def testFirstOpen(self):

tc = PATH("../yamls/home/firstOpen.yaml")

self.repalce(tc, tc_temp)

app = {"logTest": self.logTest, "driver": self.driver, "path": tc_temp,

"device": self.udid, "platformName": self.platformName, "caseName": sys._getframe().f_code.co_name}

page = PageOperate(app)

page.operate()

page.checkPoint()

def testSecondOpen(self):

tc = PATH("../yamls/home/secondOpen.yaml")

self.repalce(tc, tc_temp)

app = {"logTest": self.logTest, "driver": self.driver, "path": tc_temp,

"device": self.udid, "platformName": self.platformName, "caseName": sys._getframe().f_code.co_name}

page = PageOperate(app)

page.operate()

page.checkPoint()

6.Case入口

def runnerCaseApp(devices):

starttime = datetime.now()

suite = unittest.TestSuite()

suite.addTest(ParametrizedTestCase.parametrize(HomeTest, param=devices))

# suite.addTest(ParametrizedTestCase.parametrize(HomeTest, param=devices)) #加入测试类

unittest.TextTestRunner(verbosity=2).run(suite)

endtime = datetime.now()

countDate(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), str((endtime - starttime).seconds) + "秒")

7.实时日志展示

testFirstOpen (TestCase.HomeTest.HomeTest) ... ==操作步骤:com.quvideo.xiaoying:id/xiaoying_alert_dialog_positive_click ==

==操作步骤:com.android.packageinstaller:id/permission_allow_button_click ==

==操作步骤:com.android.packageinstaller:id/permission_allow_button_click ==

==操作步骤:com.quvideo.xiaoying:id/wel_skip_click ==

==操作步骤:com.quvideo.xiaoying:id/layout_fragment_creation_click ==

==操作步骤:com.quvideo.xiaoying:id/icon1_click ==

==操作步骤:text("跳过")_click ==

==操作步骤:com.quvideo.xiaoying:id/icon1_click ==

==操作步骤:text("其他相册")_ ==

Platform: android

Device: 4ed397ac

==用例_启动app并进入gallery检查点成功==

ok

8.操作日志输出展示

2018-08-23 11:51:08,390 - INFO - ---- home_test_001_启动app并进入gallery_com.quvideo.xiaoying:id/xiaoying_alert_dialog_positive_click ----

2018-08-23 11:51:09,711 - INFO - ---- home_test_001_启动app并进入gallery_com.android.packageinstaller:id/permission_allow_button_click ----

2018-08-23 11:51:10,583 - INFO - ---- home_test_001_启动app并进入gallery_com.android.packageinstaller:id/permission_allow_button_click ----

2018-08-23 11:51:19,866 - INFO - ---- home_test_001_启动app并进入gallery_com.quvideo.xiaoying:id/wel_skip_click ----

2018-08-23 11:51:23,644 - INFO - ---- home_test_001_启动app并进入gallery_com.quvideo.xiaoying:id/layout_fragment_creation_click ----

2018-08-23 11:51:29,023 - INFO - ---- home_test_001_启动app并进入gallery_com.quvideo.xiaoying:id/icon1_click ----

2018-08-23 11:51:30,361 - INFO - ---- home_test_001_启动app并进入gallery_text("跳过")_click ----

2018-08-23 11:51:33,660 - INFO - ---- home_test_001_启动app并进入gallery_com.quvideo.xiaoying:id/icon1_click ----

2018-08-23 11:51:35,636 - INFO - ---- home_test_001_启动app并进入gallery_text("其他相册")_ ----

2018-08-23 11:51:35,698 - INFO - [CheckPoint_1]: testFirstOpen_ : OK

2018-08-23 11:51:52,341 - INFO - ---- home_test_002_进入拍摄页面_com.quvideo.xiaoying:id/img_creation_click ----

2018-08-23 11:51:54,148 - INFO - ---- home_test_002_进入拍摄页面_com.quvideo.xiaoying:id/icon2_click ----

2018-08-23 11:51:55,116 - INFO - ---- home_test_002_进入拍摄页面_text("允许")_click ----

2018-08-23 11:51:56,704 - INFO - ---- home_test_002_进入拍摄页面_text("总是允许")_click ----

2018-08-23 11:51:57,834 - INFO - ---- home_test_002_进入拍摄页面_text("总是允许")_click ----

2018-08-23 11:52:01,559 - INFO - ---- home_test_002_进入拍摄页面_text("高清相机")_ ----

2018-08-23 11:52:01,647 - INFO - [CheckPoint_2]: testSecondOpen_ : OK

9.crash解析-android

=========================crash================================

06-20 13:41:06.165 7638 7638 E AndroidRuntime: Process: com.quvideo.xiaoying, PID: 7638

06-20 13:41:06.165 7638 7638 E AndroidRuntime: java.lang.NullPointerException: Attempt to read from field 'int com.quvideo.xiaoying.datacenter.social.publish.PublishTaskInfo.step' on a null object reference

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.d.a.aI(SourceFile:67)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.d.a.aK(SourceFile:123)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.d.a.a(SourceFile:151)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.SocialPublishBaseActivity.da(SourceFile:1531)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.SocialPublishBaseActivity.aaM(SourceFile:1565)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.c.b$1.acg(SourceFile:312)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.videoeditor.j.a.a$4.m(SourceFile:650)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.ui.dialog.c.onClick(SourceFile:165)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.view.View.performClick(View.java:6291)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:24931)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:808)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:101)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.os.Looper.loop(Looper.java:166)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7425)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

06-20 13:41:06.367 732 732 E wificond: Failed to get NL80211_RATE_INFO_NOISE

06-20 13:41:06.367 732 732 E wificond: Failed to get NL80211_RATE_INFO_SNR

06-20 13:41:06.367 732 732 E wificond: Failed to get NL80211_STA_INFO_CNAHLOAD

06-20 13:41:07.841 1157 1174 I chatty : uid=1000(system) android.ui expire 3 lines

06-20 13:41:07.851 1448 1780 I HwNetworkPolicyManager: getHwUidPolicy uid = 10063 policy = 0

06-20 13:41:07.878 1157 2823 I chatty : uid=1000(system) Binder:1157_F expire 1 line

06-20 13:41:07.879 1157 1350 I chatty : uid=1000(system) ConnectivitySer expire 14 lines

06-20 13:41:07.879 1157 8282 I chatty : uid=1000(system) Binder:1157_1B expire 10 lines

06-20 13:41:07.893 1157 8281 I chatty : uid=1000(system) Binder:1157_1A expire 12 lines

06-20 13:41:07.900 17940 17940 I ActivityThread: Removing dead content provider:android.content.ContentProviderProxy@b3b0cdb

06-20 13:41:07.911 1157 14597 I chatty : uid=1000(system) Binder:1157_1F expire 9 lines

06-20 13:41:07.936 1157 1167 I chatty : uid=1000(system) Binder:1157_1 expire 14 lines

=========================crash=========================

06-20 13:41:06.165 7638 7638 E AndroidRuntime: Process: com.quvideo.xiaoying, PID: 7638

06-20 13:41:06.165 7638 7638 E AndroidRuntime: java.lang.NullPointerException: Attempt to read from field 'int com.quvideo.xiaoying.datacenter.social.publish.PublishTaskInfo.step' on a null object reference

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.d.a.aI(SourceFile:67)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.d.a.aK(SourceFile:123)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.d.a.a(SourceFile:151)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.SocialPublishBaseActivity.da(SourceFile:1531)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.SocialPublishBaseActivity.aaM(SourceFile:1565)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.app.publish.c.b$1.acg(SourceFile:312)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.videoeditor.j.a.a$4.m(SourceFile:650)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.quvideo.xiaoying.ui.dialog.c.onClick(SourceFile:165)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.view.View.performClick(View.java:6291)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:24931)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:808)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:101)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.os.Looper.loop(Looper.java:166)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7425)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)

06-20 13:41:06.165 7638 7638 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

06-20 13:41:06.367 732 732 E wificond: Failed to get NL80211_RATE_INFO_NOISE

06-20 13:41:06.367 732 732 E wificond: Failed to get NL80211_RATE_INFO_SNR

06-20 13:41:06.367 732 732 E wificond: Failed to get NL80211_STA_INFO_CNAHLOAD

06-20 13:41:07.841 1157 1174 I chatty : uid=1000(system) android.ui expire 3 lines

06-20 13:41:07.851 1448 1780 I HwNetworkPolicyManager: getHwUidPolicy uid = 10063 policy = 0

06-20 13:41:07.878 1157 2823 I chatty : uid=1000(system) Binder:1157_F expire 1 line

06-20 13:41:07.879 1157 1350 I chatty : uid=1000(system) ConnectivitySer expire 14 lines

06-20 13:41:07.879 1157 8282 I chatty : uid=1000(system) Binder:1157_1B expire 10 lines

06-20 13:41:07.893 1157 8281 I chatty : uid=1000(system) Binder:1157_1A expire 12 lines

06-20 13:41:07.900 17940 17940 I ActivityThread: Removing dead content provider:android.content.ContentProviderProxy@b3b0cdb

06-20 13:41:07.911 1157 14597 I chatty : uid=1000(system) Binder:1157_1F expire 9 lines

06-20 13:41:07.936 1157 1167 I chatty : uid=1000(system) Binder:1157_1 expire 14 lines

06-20 13:41:07.942 1157 1367 I chatty : uid=1000(system) CallbackHandler expire 2 lines

06-20 13:41:07.958 1157 1182 I chatty : uid=1000(system) android.display expire 1 line

10. crash解析-iOS

============开始导出crashreport==========

idevicecrashreport -u 5214866ccb9342f87f4c2aab093c25f7e252fd85 /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/

Move: WiFi/WiFiManager/wifi-buf-05-23-2018__18:35:55.107.log

Move: WiFi/WiFiManager/wifi-buf-08-12-2018__02:40:07.213.log

Move: WiFi/WiFiManager/wifi-buf-05-06-2018__21:15:54.957.log

Move: WiFi/WiFiManager/wifi-buf-06-19-2018__05:16:04.564.log

Move: WiFi/WiFiManager/wifi-buf-06-16-2018__10:05:31.097.log

Move: WiFi/WiFiManager/wifi-buf-11-04-2017__14:36:48.log

Move: WiFi/WiFiManager/wifi-buf-12-03-2017__14:31:53.log

Move: WiFi/WiFiManager/wifi-buf-11-14-2017__22:41:35.log

Move: WiFi/WiFiManager/wifi-buf-05-13-2018__23:07:34.084.log

Move: WiFi/WiFiManager/wifi-buf-06-19-2018__08:05:54.196.log

Move: WiFi/WiFiManager/wifi-buf-01-23-2018__23:50:53.018.log

Move: WiFi/WiFiManager/wifi-buf-12-03-2017__15:54:45.log

Move: WiFi/WiFiManager/wifi-buf-04-10-2018__14:33:15.105.log

Move: WiFi/WiFiManager/wifi-buf-08-12-2018__20:34:03.165.log

Move: WiFi/WiFiManager/wifi-buf-08-24-2018__02:50:49.140.log

.....

.....

Move: XiaoYing-2018-07-30-114612.ips

Move: XiaoYing-2018-07-30-162434.ips

Move: XiaoYing-2018-07-28-123234.ips

Move: XiaoYing-2018-09-04-102545.ips

Move: XiaoYing-2018-07-31-095526.ips

Move: XiaoYing-2018-07-31-151350.ips

Move: XiaoYing-2018-09-04-102545.ips

Move: XiaoYing-2018-07-30-113126.ips

Move: XiaoYing-2018-07-30-114612.ips

Move: com.apple.appstored/appstored.log

Done.

============开始解析待测app相关crashreport==========

输入的文件为: /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-07-30-114612.ips

输出的文件为:

0x100c24000 - 0x102ff3fff XiaoYing arm64 <2deaa9887c173bb0a9f4b051e47f04a3> /var/containers/Bundle/Application/170BDC50-F0D3-4973-9781-D414532E21CD/XiaoYing.app/XiaoYing

2DEAA988-7C17-3BB0-A9F4-B051E47F04A3

'/dSYMs/XiaoYing.app.dSYM'

输入的文件为: /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-07-30-162434.ips

输出的文件为:

0x100290000 - 0x10265ffff XiaoYing arm64 <2deaa9887c173bb0a9f4b051e47f04a3> /var/containers/Bundle/Application/C5855F55-13D0-49FE-ADC2-7C82565237D0/XiaoYing.app/XiaoYing

2DEAA988-7C17-3BB0-A9F4-B051E47F04A3

'/dSYMs/XiaoYing.app.dSYM'

......

......

============crashreport解析完成==========

============删除所有解析之前的crash文件==========

/Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/JetsamEvent-2018-09-04-104135.ips was removed!

Directory: /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/JetsamEvent-2018-09-04-104135.ips was removed!

Directory: /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/WiFi was removed!

/Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-07-30-114612.ips was removed!

Directory: /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-07-30-114612.ips was removed!

/Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-07-30-162434.ips was removed!

Directory: /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-07-30-162434.ips was removed!

/Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-09-04-102545.ips was removed!

Directory: /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-09-04-102545.ips was removed!

Directory: /Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/com.apple.appstored was removed!

/Users/zhulixin/Desktop/python-appium/Log/CrashInfo/iOS/Before/XiaoYing-2018-07-30-184609.ips was removed!

......

......

Process finished with exit code 0

11.最终log输出信息及路径

12.报告输出

1.Android

2.iOS

运行环境

Windows 7及以上 / OSX

Android SDK的执行环境

python3.x

Appium 1.7.x及以上

代码获取

最新的稳定代码会推送到github上,直接clone即可使用。

git@github.com:Lemonzhulixin/python-appium.git

执行注意事项

1.安装包路径指定:Base.BaseInit

apkPath = PATH("../app/VivaVideo_7.2.5.apk") # 测试的app路径

ipaPath = PATH("../app/xiaoying.ipa") # 测试的app路径

2.为了避免同一台PC上同时连接android和iOS设备时,获取设备问题,将runner文件两个平台分开处理

Android执行: python3 ../Runner/runner.py

iOS执行:python3 ../Runner/runner_iOS.py

3.在过滤待测app crashreport时,记得在runner_iOS.py中修改待测app crashreport文件关键字

find_str = 'XiaoYing-' # 待测app crashreport文件关键字

4.过滤待测app系统日志,修改待测app关键字,如此处的'XiaoYing'

#获取系统日志,过滤当前app的log,如不需要获取系统日志,注掉即可

syslog_path = os.path.join(PATH("../Log/CrashInfo/iOS/"), "syslog.log")

sys_cmd = 'idevicesyslog -u ' + get_phone["udid"] + " |grep 'XiaoYing' > %s" % (syslog_path)

os.popen(sys_cmd)

目前的遗留问题

email邮件发送尚未调试

多设备执行还有点问题

当遇到有些用例比较麻烦,必须单独写page层

因为对python的map方法不是很懂,所以控件集参数化用了最原始,最笨的字符串替换,输出一个临时temp.yaml文件,测试完成后再删除;如果有对map熟悉的同学,欢迎帮忙写个方法来处理,感谢!

后续计划

测试数据DB存储

结果集分析

appiumpython框架实例_GitHub - feiyangzhu/python-appium: 基于PageObject UI自动化测试框架,支持Android/iOS...相关推荐

  1. appium python框架结构,GitHub - wyybingo/python-appium: 基于PageObject UI自动化测试框架,支持Android/iOS...

    0910 UPDATE 新增控件集参数化,相同测试步骤的Android/iOS可共用一份测试用例 不同测试步骤的用例还需要单独写 0904 UPDATE 优化Android log及crsahinfo ...

  2. pythonwebview自动化测试_GitHub - githubwzg/python-appium: 基于PageObject UI自动化测试框架,支持Android/iOS...

    0910 UPDATE 新增控件集参数化,相同测试步骤的Android/iOS可共用一份测试用例 不同测试步骤的用例还需要单独写 0904 UPDATE 优化Android log及crsahinfo ...

  3. python ui自动化测试框架_基于python语言下的UI自动化测试框架搭建(一)

    最近在搭一个UI自动化测试框架,想把整个搭建过程分享出来,如果有不对的地方,希望大家能够指正,首先创建一个名称为,antomation_framework_demo的工程文件, pycharm中工程及 ...

  4. Appium PO模式UI自动化测试框架——设计与实践

    阅读目录 1. 目的 2. 意义 3. 设计理念 4. PO模式 5. 框架设计 5.1 目录结构 5.2 实现步骤 5.3 具体实现 5.3.1 base部分 5.3.2 po部分 5.3.3 te ...

  5. Python Appium移动端app自动化测试框架

    最近有时间把前面写的Python UI自动化脚本转换成了适用于App的测试,整体架构没多少变化,先看整体架构 先从入口说起: (1)config.ini:运行前进行基本的配置,配置文件,由于是借鉴的U ...

  6. 基于python语言下的UI自动化测试框架搭建(四)

    testsuits:案例执行 创建baidu_search1.py文件,这里会展示两种执行方式,一种是直接调用base_page中封装好的常用操作方法,另外一种是先调用baidu_homepage.p ...

  7. 测试开发 - 十年磨一剑(五)UI自动化测试框架与分层结构

    一.UI自动化测试框架 Selenium是自动化工具,工具,工具!面试的时候不想再听到谁说用的测试框架是Selenium. 构成框架的组件,最起码应该具备以下的功能,才能够称为一个完整的自动化测试框架 ...

  8. python3.7界面设计_基于selenium+Python3.7+yaml+Robot Framework的UI自动化测试框架

    前端自动化测试框架 项目说明 本框架是一套基于selenium+Python3.7+yaml+Robot Framework而设计的数据驱动UI自动化测试框架,Robot Framework 作为执行 ...

  9. python开源自动化测试平台_Airtest:网易游戏开源的跨平台 UI 自动化测试框架

    Airtest 跨平台的UI自动化测试框架,适用于游戏和App 快速开始 Airtest是一个跨平台的UI自动化测试框架,适用于游戏和App.目前支持Windows和Android平台,iOS支持正在 ...

  10. 设计自己的基于Selenium 的自动化测试框架-Java版(3) - 给框架分分层

    设计自己的基于Selenium 的自动化测试框架-Java版(3) - 给框架分分层 给我们的框架分为3层,分别是叫逻辑层,数据层,对象层. 这三层的存储格式都用xml来表示. 1.逻辑层 (test ...

最新文章

  1. python教学视频下载-董付国老师Python精品教学,视频教程下载
  2. 接收不到其他机器发来的报文_大厂真实案例:线上四台机器同一时间全部 OOM......
  3. python基础知识点制作图片
  4. Android开始中的OOM异常
  5. 10-300-020-简介-架构-简介
  6. 电商Sass平台-商城运营后台原型-仓储管理-订单管理-店铺运营-采购管理-数据分析-交易分析-留存分析-客户管理-用户运营-围栏管理-商品管理-流量分析-电商erp后台管理-用户权限-销量分析
  7. Linux系统基础开发应用及Linux-C用户手册
  8. Python argv小结
  9. Permute 3 for mac(全能媒体格式转换器)
  10. 鸿蒙系统官网电脑版,华为鸿蒙系统官网下载-华为鸿蒙系统下载pc版v2.0 电脑版下载-955游戏网...
  11. 机器学习算法一之基于K均值聚类算法实现数据聚类及二维图像像素分割
  12. 做一名「技术掮客」去变现自己的技术
  13. Android知识体系思维导图
  14. 【Linux云计算架构:第二阶段-Linux必会的20多种服务】第22章——-源码编译安装LAMP
  15. 微信公众号推送功能代码及详解
  16. OpenStack实操用到的网络知识
  17. 【转】GitHub 优秀的 Android 开源项目
  18. 值得收藏的22个搜索下载免费PDF电子书的网站
  19. 泛微校招群面经历(一日游?)
  20. [附源码]java毕业设计医院档案管理系统

热门文章

  1. xcode 9.0 iOS 11
  2. 常见shader原理及实现(三)边缘查找,锐化,浮雕
  3. 使用Objective-C的+(void)initialize初始化static变量
  4. PHP cookie和session的分析
  5. [DELPHI] 使用mod函数换行
  6. Linux学习笔记:Jenkins的使用
  7. Open***服务器端配置文件server.conf的说明
  8. 【思路】Gym - 101173F - Free Figurines
  9. 《Metasploit渗透测试手册》—第3章3.5节在Windows 2003 Server上进行渗透测试
  10. SSH集成项目,使用注解方式,竟然还有这样的问题!!