Code Monkey home page Code Monkey logo

atx-test's Introduction

基于ATX-Server的UI自动化测试框架,可以实现多设备的并行测试,并生成统一的测试报告

更新说明 20210309

  1. 支持失败重试 Drivers().run(devices, cases, apk_info,retry=3,save_last_try=True)中 retry 为失败重试次数 save_last_try为是否只展示最后一次运行结果

  2. 支持运行视频录制 (需要提前下载好依赖 pip3 install -U "uiautomator2[image]" -i https://pypi.doubanio.com/simple)

    在报告中展示 需要 basepage().startscreenrecord() basepage().stopscreenrecord() 组合操作 中间脚本执行的操作录屏视频结果会在报告中展示,建议直接放在setUp和tearDown中

  3. watcher 替换为了watch_context 需要在开始的时候实例化ctx=basepage().watch_device('XXXX')

    停止的时候 再调用basepage().unwatch_device(ctx)把监听关掉

已经支持atx-server2

android:修改Public下的config下的Server地址为atx-server2的Url,token填写正确后,就可以正常运行了

ios:在设备接入到atx-server2之后, 可以参照demo下的wda_demo.py可以运行简单的网易云音乐的脚本操作.

atxserver2的部署请参照大佬的帖子: atxserver2 手机设备管理平台 重装上阵

Python版本说明

python2不支持 需要在python3上运行 本人python版本 3.8.7

前置条件

Android设备需要通过uiautomator2 init 初始化完成,确认可以正常连接 ,或者init 接入atx-server uiautomator版本需 Version: 0.1.3.dev5 及以后

需要依赖的python第三方库 tinydb、uiautomator2、selenium、jinja2、psutil

相关的基础链接如下

小白入门篇:python uiautomator2 的代码示例

浅谈自动化测试工具 python-uiautomator2

atx 安卓集群管理 安装运行及自动化的实践

ATX-uiautomator2 实现 webview 的操作

先行声明:

1.下面展示的内容多源于TesterHome各位前辈的经验总结,我只是按照我的想法进行了简单拼接(基于ATX-uiautomator2的android自动化测试)

2.主要参考了hualin (王华林) 老师的https://testerhome.com/topics/7550 ,并在此基础上结合uiautomator2实现

3.所用语言为Python,测试报告模板借用了https://github.com/Gelomen/HTMLTestReportCN-ScreenShot ,并进行了简单的修改以方便截图

4.使用了macaca的bootstrap app作为demo演示

工程介绍

工程目录如下

atx-1

主体结构和hualin (王华林) 老师的https://testerhome.com/topics/7550 的一致,主要修改了Pubilc下一些东西,并增加了一些东西

Public:

  • Devices_new.py 获取atx-server上特定设备(get_online_devices())、或config.ini下devices IP列表的在线设备(get_devices())、有线连接电脑的设备自动连接u2(connect_devices())
  • BasePage.py 用于设备的初始化 u2.connect 已经一些公共模块的封装
  • chromedriver.py 和Ports.py 结合使用,启动chromedriver以便实现u2的webview操作(目前还没做到根据设备的chromeversion 启动指定版本的chromedriver)
  • Casestrategy.py 获取指定路径下的testcases
  • Decorator.py 有*@*testcase*@*teststep这样的装饰器用例执行日志打印、错误后的处理(截图)
  • Report.py 对生成的报告的一些操作,备份Testreport的报告到TestReport_backup下、多设备统一报告的生成、报告的文件夹压缩
  • Test_data.py 在执行测试前的测试数据的生成,会在Plubic下生成data.json,测试执行的时候各个设设备更具自己的serial获取对应的测试数据
  • Drivers.py 设备的获取,初始化准备,测试执行都是在这里完成的
  • RunCases.py 存放测试报告/日志/截图的路径的生成,以及最终通过HTMLTestRunner来执行用例
  • config.ini 一些需要用到的数据,atx-server地址、测试设备的ip、测试数据等

下面介绍一下流程:

1、通过run_cases .py或者run_all_cases.py开始执行测试

if __name__ == '__main__':
    # back up old report dir 备份旧的测试报告文件夹到TestReport_backup下
    backup_report()

    cs = CaseStrategy()
    cases = cs.collect_cases(suite=False)
    Drivers().run(cases)

    # Generate zip_report file  压缩测试报告文件
    # zip_report()

​ 1.首先会将Testreport目录剪切到TestReport_backup目录下,备份旧的测试报告

​ 2.通过CaseStrategy获取到需要执的测试用例

​ 3.Drivers().run(cases)开始执行测试

​ 4.执行完成之后打包压缩,没啥用 注释掉了

2、run(cases)执行测试

def run(self, cases):
    # 根据method 获取android设备
    method = ReadConfig().get_method().strip()
    if method == 'SERVER':
        # get ATX-Server Online devices
        # devices = ATX_Server(ReadConfig().get_server_url()).online_devices()
        print('Checking available online devices from ATX-Server...')
        devices = get_online_devices()
        print('\nThere has %s online devices in ATX-Server' % len(devices))
    elif method == 'IP':
        # get  devices from config devices list
        print('Checking available IP devices from config... ')
        devices = get_devices()
        print('\nThere has %s  devices alive in config IP list' % len(devices))
    elif method == 'USB':
        # get  devices connected PC with USB
        print('Checking available USB devices connected on PC... ')
        devices = connect_devices()
        print('\nThere has %s  USB devices alive ' % len(devices))

    else:
        raise Exception('Config.ini method illegal:method =%s' % method)

    if not devices:
        print('There is no device found,test over.')
        return

    # generate test data data.json 准备测试数据
    generate_test_data(devices)

    print('Starting Run test >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
    runs = []
    for i in range(len(devices)):
        runs.append(RunCases(devices[i]))

    # run on every device 开始执行测试
    pool = Pool(processes=len(runs))
    for run in runs:
        pool.apply_async(self._run_cases,
                         args=(run, cases,))
    print('Waiting for all runs done........ ')
    pool.close()
    pool.join()
    print('All runs done........ ')
    ChromeDriver.kill()

    #  Generate statistics report  生成统计测试报告 将所有设备的报告在一个HTML中展示
    create_statistics_report(runs)

​ 1.首先根据config.ini中method的值来判断从atx-serve获取online的设备 还是从config.ini中的ip来获取在线的设备

​ 2.在获取到设备之后,根据设备生产data.json测试数据

​ 3.并行多设备执行测试

​ 4.测试完之后,杀掉执行过程中打开的所有的chromedriver进程

​ 5.最后在TestReport下生成统计测试报告(自动化测试报告.html)

结果展示

生成的测试报告路径结构如下

atx-2

每个设备的测试结果及报告或存放在单独的文件夹下

在Testreport目录下会有一个统计测试报告(自动化测试报告.html)会将所有设备的报告统一在一个页面展示

报告展示:

atx-3

atx-test's People

Contributors

pengchenglin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

atx-test's Issues

运行的时候

C:\Python37\python.exe C:/Users/Administrator/PycharmProjects/ATX-Test/TestSuite_demo/run_cases.py
Backup TestReport dir success
Checking available USB devices connected on PC...
Start check 1 devices connected on PC:
[2019-02-13 17:29:15] uiautomator is starting ...
[2019-02-13 17:29:16] uiautomator is starting ...
[2019-02-13 17:29:17] uiautomator is starting ...
[2019-02-13 17:29:18] uiautomator is starting ...
uiautomator back to normal

There has 1 USB devices alive
B2NGAC6842303956-a0:28:ed:aa:0c:9b-Nokia_7_plus
Test data data.json generated success
Starting Run test >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Waiting for all runs done........
2019-02-13 17:29:21,499 - Nokia 7 plus - INFO - udid: B2NGAC6842303956-a0:28:ed:aa:0c:9b-Nokia_7_plus
udid: %s B2NGAC6842303956-a0:28:ed:aa:0c:9b-Nokia_7_plus
2019-02-13 17:29:21,870 - Nokia 7 plus - DEBUG - --> apk_install.setUpClass
2019-02-13 17:29:22,196 - Nokia 7 plus - DEBUG - <-- apk_install.setUpClass, Success

2019-02-13 17:29:22,196 - Nokia 7 plus - DEBUG - --> apk_install.test_01_install_apk
2019-02-13 17:29:29,390 - Nokia 7 plus - INFO - --> login_page.wait_page
2019-02-13 17:29:45,182 - Nokia 7 plus - ERROR - Exception, Not in LoginPage
2019-02-13 17:29:45,182 - Nokia 7 plus - ERROR - <-- login_page.wait_page, Exception, Error
2019-02-13 17:29:45,593 - Nokia 7 plus - ERROR - Exception, IMAGE:login_page.wait_page-20190213172945.PNG
2019-02-13 17:29:45,593 - Nokia 7 plus - ERROR - <-- apk_install.test_01_install_apk, Exception, Error

Error test_01_install_apk (test_01_install.apk_install)

2019-02-13 17:29:45,594 - Nokia 7 plus - DEBUG - --> apk_install.test_02_fail
2019-02-13 17:30:05,879 - Nokia 7 plus - ERROR - Exception, -32002 Client error: <> data: , method: None
2019-02-13 17:30:05,880 - Nokia 7 plus - ERROR - <-- apk_install.test_02_fail, Exception, Error

Error test_02_fail (test_01_install.apk_install)

2019-02-13 17:30:06,306 - Nokia 7 plus - DEBUG - --> apk_install.test_03_screenshot
2019-02-13 17:30:07,720 - Nokia 7 plus - DEBUG - <-- apk_install.test_03_screenshot, Success

Success test_03_screenshot (test_01_install.apk_install)

2019-02-13 17:30:07,720 - Nokia 7 plus - DEBUG - --> apk_install.test_04_error
2019-02-13 17:30:07,720 - Nokia 7 plus - ERROR - Exception, 手动ERROR!!!!!!!
2019-02-13 17:30:07,720 - Nokia 7 plus - ERROR - <-- apk_install.test_04_error, Exception, Error

Error test_04_error (test_01_install.apk_install)

2019-02-13 17:30:08,115 - Nokia 7 plus - DEBUG - --> apk_install.tearDownClass
2019-02-13 17:30:08,191 - Nokia 7 plus - DEBUG - <-- apk_install.tearDownClass, Success

2019-02-13 17:30:08,191 - Nokia 7 plus - DEBUG - --> TestBootStrap.setUpClass
2019-02-13 17:30:08,601 - Nokia 7 plus - DEBUG - <-- TestBootStrap.setUpClass, Success

2019-02-13 17:30:08,601 - Nokia 7 plus - DEBUG - --> TestBootStrap.test_01_login
2019-02-13 17:30:08,601 - Nokia 7 plus - INFO - --> login_page.wait_page
2019-02-13 17:30:23,844 - Nokia 7 plus - ERROR - Exception, Not in LoginPage
2019-02-13 17:30:23,844 - Nokia 7 plus - ERROR - <-- login_page.wait_page, Exception, Error
2019-02-13 17:30:24,282 - Nokia 7 plus - ERROR - Exception, IMAGE:login_page.wait_page-20190213173023.PNG
2019-02-13 17:30:24,282 - Nokia 7 plus - ERROR - <-- TestBootStrap.test_01_login, Exception, Error

Error test_01_login (test_02_bootstrap.TestBootStrap)

2019-02-13 17:30:24,283 - Nokia 7 plus - DEBUG - --> TestBootStrap.test_02_show_toast

下面不知道什么错误

--------------------- 测试结束 ---------------------
------------- 合计耗时: 0:01:28.935292 -------------
All runs done........
Traceback (most recent call last):
File "D:/ATX-Test-master/TestSuite_demo/run_cases.py", line 19, in
Drivers().run(cases)
File "D:\ATX-Test-master\Public\Drivers.py", line 142, in run
ChromeDriver.kill()
File "D:\ATX-Test-master\Public\chromedriver.py", line 84, in kill
pid = getPidByName('chromedriver.exe')
File "D:\ATX-Test-master\Public\chromedriver.py", line 30, in getPidByName
if pid.name() == Str:
File "C:\Python37\lib\site-packages\psutil_init_.py", line 609, in name
name = self._proc.name()
File "C:\Python37\lib\site-packages\psutil_pswindows.py", line 635, in wrapper
return fun(self, *args, **kwargs)
File "C:\Python37\lib\site-packages\psutil_pswindows.py", line 687, in name
return py2_strencode(os.path.basename(self.exe()))
File "C:\Python37\lib\site-packages\psutil_pswindows.py", line 635, in wrapper
return fun(self, *args, **kwargs)
File "C:\Python37\lib\site-packages\psutil_pswindows.py", line 701, in exe
return py2_strencode(convert_dos_path(cext.proc_exe(self.pid)))
OSError: [WinError 0] 操作成功完成。

Process finished with exit code 1

casestrategy报错

请问在执行 run_all_cases.py 时,报了以下错误,是不是有路径配置问题?

[I 210119 19:51:12 devices_new:145]
There has 2 USB devices alive
Traceback (most recent call last):
File "/Users/xxx/Documents/xxx/pythonWorkspaces/ATX-Test/Demo/run_all_cases.py", line 30, in
cases = cs.collect_cases(suite=True)
File "/Users/xxx/Documents/xxx/pythonWorkspaces/ATX-Test/Public/casestrategy.py", line 40, in collect_cases
self._collect_cases(cases, top_dir=test_suite)
File "/Users/xxx/Documents/xxx/pythonWorkspaces/ATX-Test/Public/casestrategy.py", line 16, in _collect_cases
suites = unittest.defaultTestLoader.discover(self.case_path, pattern=self.case_pattern, top_level_dir=top_dir)
File "/usr/local/Cellar/[email protected]/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8/unittest/loader.py", line 306, in discover
os.path.dirname((the_module.file)))
File "/usr/local/Cellar/[email protected]/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8/posixpath.py", line 152, in dirname
p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not NoneType
['TestSuite_demo']
/Users/xxx/Documents/xxx/pythonWorkspaces/ATX-Test/Demo/TestCase

Process finished with exit code 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.