学习笔记——测试进阶之路 工作笔记:AIRTEST 批量执行用例,并生成聚合报告

大海 · 2021年07月27日 · 最后由 Jerrygu 回复于 2025年11月04日 · 12517 次阅读

聚合报告

Airtest Report

结构目录

首先我们要准备一个合适的 Python 环境,大于 Python3,小于等于 Python3.9 均可。

然后就在这里 Python 环境里面,像安装其它 Python 第三方库一样,安装我们的自动化测试框架:

安装 Airtest 框架

pip install airtest

安装 Poco 框架;编写了 Poco 语句就需要安装

pip install pocoui

安装 airtest-selenium 框架;编写了 airtest-selenium 语句就需要安装

pip install airtest-selenium
如安装第三方库过程中,出现报错或者超时,请先确保自己的 Python 版本是在支持范围之内的,然后再 使用清华源或者其它国内源安装 :

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple airtest
成功安装之后,我们可以使用 pip list 命令,查看我们的安装情况及框架版本信息.
(PS: 不能同时安装 poco 与 pocoui,俩者会产生冲突!)

接下来,我们就可以在这个环境里面运行我们编写好的自动化脚本

用例代码


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@File    : Test01_客找找_线索池.py
@Time    : 2021/07/06
"""


import datetime
from airtest.core.api import *
from airtest.cli.parser import cli_setup
from airtest.report.report import simple_report
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
from poco.exceptions import *



poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

if not cli_setup():
    auto_setup(__file__, logdir=r"D:/QCC_AIRTEST_PROJECTS/log/Test01_客找找_线索池", project_root=r"D:/QCC_AIRTEST_PROJECTS", devices=[
            "android://127.0.0.1:5037/NDF0217B10002156?cap_method=JAVACAP&&ori_method=MINICAPORI&&touch_method=MINITOUCH",
    ])


# script content
print("start...")



########################################################################################
# 回归测试
# 线索池:筛选、排序、搜索
###################################################3####################################

print("**************************** 开始唤醒屏幕 *************************")
try:
    shell("input keyevent 224")
    time.sleep(2.0)
except Exception as e:
    log("唤醒屏幕失败", snapshot=True)

if poco(text="上滑解锁", name="com.android.systemui:id/hw_keyguard_indication_text",
        type="android.widget.TextView").exists():
    assert_equal(poco(text="上滑解锁", name="com.android.systemui:id/hw_keyguard_indication_text",
                      type="android.widget.TextView").get_text(),
                 "上滑解锁", msg="屏幕锁定:上滑解锁")

    print("***************************** 开始解锁屏幕 ****************************")
    shell("input keyevent 82")
    time.sleep(2.0)

print("----------------------------------- 开始打开应用 ------------------------------------")
try:
    start_app("com.android.icredit")
except Exception as e:
    log(e, snapshot=True)


print("----------------------------------- 切换到客找找按钮 ------------------------------------")
try:
    time.sleep(5.0)
    if poco(text="找客户", name="com.android.icredit:id/beo", type="android.widget.TextView").exists():
        poco(text="找客户", name="com.android.icredit:id/beo", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1628779545053.png", record_pos=(-0.4, -0.044), resolution=(1440, 2560)))
except Exception as e:
    log(e, snapshot=True)


print("----------------------------------- 切换到CRM ----------------------------------- ")
try:
    time.sleep(6.0)
    if assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625554739120.png", record_pos=(0.124, 0.822),
                              resolution=(1440, 2560)), "切换到CRM"):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625554739120.png", record_pos=(0.124, 0.822),
                       resolution=(1440, 2560)))
    else:
        touch((900, 2450))
    # time.sleep(2.0)
    # # 往上滑动一部分
    # swipe((1000, 2000), (1000, 1700), duration=1, steps=5)
except Exception as e:
    log(e, snapshot=True)






print("-------------------------------------------------------------------------------- ")
print("-------------------------------- 首次点击线索池 ----------------------------------- ")
print("-------------------------------------------------------------------------------- ")

try:
    time.sleep(3.0)
    if poco(text="线索池", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="线索池", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        time.sleep(2.0)
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625555009715.png", record_pos=(-0.381, -0.465),
                       resolution=(1440, 2560)))
except Exception as e:
    log(e, snapshot=True)








print("---------------------------------- 开始进行搜索 -------------------------------")

try:
    time.sleep(5.0)
    print("-------------------------- 点击顶部搜索框 -----------------------")
    if exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1628152354117.png", record_pos=(-0.169, -0.655),
                       resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1628152354117.png", record_pos=(-0.169, -0.655),
                       resolution=(1440, 2560)))
    else:
        touch((500, 350))
    time.sleep(2.0)

    print("*************************输入检索词:龙达物流**********************")
    text("龙达物流", search=True)

    time.sleep(3.0)
    if poco(text="黑龙江龙达物流集团有限公司", name="companyTitle1074727", type="android.view.View").exists():
        assert_equal(poco(text="黑龙江龙达物流集团有限公司", name="companyTitle1074727", type="android.view.View").get_text(),
                     "黑龙江龙达物流集团有限公司", msg="点击线索池-黑龙江龙达物流集团有限公司")
    else:
        poco(text="黑龙江龙达物流集团有限公司", name="companyTitle1074727", type="android.view.View").wait(5.0)
        assert_equal(poco(text="黑龙江龙达物流集团有限公司", name="companyTitle1074727", type="android.view.View").get_text(),
                     "黑龙江龙达物流集团有限公司", msg="点击线索池-黑龙江龙达物流集团有限公司")

    # 返回客找找主页
    print("-----------------返回客找找主页------------------")
    time.sleep(2.0)
    if poco(name="com.android.icredit:id/j6", type="android.widget.ImageButton").exists():
        poco(name="com.android.icredit:id/j6", type="android.widget.ImageButton").click()
    else:
        touch((100, 200))
except Exception as e:
    log(e, snapshot=True)







print("-------------------------------------------------------------------------------- ")
print("----------------------------------- 二次点击线索池 -------------------------------- ")
print("-------------------------------------------------------------------------------- ")

try:
    time.sleep(3.0)
    if poco(text="线索池", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="线索池", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        time.sleep(2.0)
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625555009715.png", record_pos=(-0.381, -0.465),
                       resolution=(1440, 2560)))
except Exception as e:
    log(e, snapshot=True)




print("-----------------------------------开始进行排序 ------------------------------------")
print("-----------------------------------线索池:创建日期排序 ------------------------------------")
try:
    # 点击排序按钮
    print("点击排序按钮")
    time.sleep(2.0)
    if poco(text="排序", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="排序", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625730187765.png", record_pos=(-0.304, -0.539),
                       resolution=(1440, 2560)))

    # 点击创建日期排序
    print("点击创建日期排序")
    time.sleep(3.0)
    if poco(text="创建日期排序", name="android.view.View", type="android.view.View").exists():
        poco(text="创建日期排序", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625628948488.png", record_pos=(-0.339, -0.299),
                       resolution=(1440, 2560)))

    # 点击排序按钮
    print("点击排序按钮")
    time.sleep(3.0)
    if poco(text="排序", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="排序", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_equal(poco(text="中子汇金投资集团有限公司", name="companyTitle1001509", type="android.view.View").get_text(),
                     "中子汇金投资集团有限公司", msg="创建日期排序-中子汇金投资集团有限公司")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625730187765.png", record_pos=(-0.304, -0.539),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_equal(poco(text="中子汇金投资集团有限公司", name="companyTitle1001509", type="android.view.View").get_text(),
                     "中子汇金投资集团有限公司", msg="创建日期排序-中子汇金投资集团有限公司")
except Exception as e:
    log(e, snapshot=True)




print("-----------------------------------线索池:最后跟进日期排序 ------------------------------------")
try:
    # 点击排序按钮
    print("点击排序按钮")
    time.sleep(3.0)
    if poco(text="排序", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="排序", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625730187765.png", record_pos=(-0.304, -0.539),
                       resolution=(1440, 2560)))

    # 点击最后跟进日期排序
    print("点击最后跟进日期排序")
    time.sleep(3.0)
    if poco(text="最后跟进日期排序", name="android.view.View", type="android.view.View").exists():
        poco(text="最后跟进日期排序", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625628967982.png", record_pos=(-0.301, -0.181),
                       resolution=(1440, 2560)))

    # 点击排序按钮
    print("点击排序按钮")
    time.sleep(3.0)
    if poco(text="排序", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="排序", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625730187765.png", record_pos=(-0.304, -0.539),
                       resolution=(1440, 2560)))


    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1627566504209.png", record_pos=(-0.385, 0.658),
                               resolution=(1440, 2560)), "线索池:最后跟进日期排序-1552条线索")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626148104880.png", record_pos=(0.362, -0.541),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1627566504209.png", record_pos=(-0.385, 0.658),
                               resolution=(1440, 2560)), "线索池:最后跟进日期排序-1552条线索")
except Exception as e:
    log(e, snapshot=True)






print("--------------------------------------------------------------------------------")
print("-----------------------------------开始进行筛选 ----------------------------------")
print("--------------------------------------------------------------------------------")



print("----------------------------------- 线索池:无效筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 勾选无效按钮
    print("勾选无效按钮")
    time.sleep(3.0)
    if poco(text="无效", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="无效", name="android.view.View", type="android.view.View").get_text(),
                     "无效", msg="无效")
        poco(text="无效", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630236531.png", record_pos=(-0.406, -0.394),
                       resolution=(1440, 2560)))

    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))



    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_equal(poco(text="未搜索到相关线索,更换搜索条件试试!", name="android.view.View", type="android.view.View").get_text(),
                     "未搜索到相关线索,更换搜索条件试试!", msg="线索池:无效筛选-未搜索到相关线索,更换搜索条件试试!")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626148104880.png", record_pos=(0.362, -0.541),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_equal(poco(text="未搜索到相关线索,更换搜索条件试试!", name="android.view.View", type="android.view.View").get_text(),
                     "未搜索到相关线索,更换搜索条件试试!", msg="线索池:无效筛选-未搜索到相关线索,更换搜索条件试试!")
except Exception as e:
    log(e, snapshot=True)






print("-----------------------------------线索池:未分配筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 取消勾选无效按钮
    print("取消勾选无效按钮")
    time.sleep(3.0)
    if poco(text="无效", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="无效", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "无效", msg="无效")
        poco(text="无效", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630236531.png", record_pos=(-0.406, -0.394),
                       resolution=(1440, 2560)))


    # 勾选未分配按钮
    print("勾选未分配按钮")
    time.sleep(3.0)
    if poco(text="未分配", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="未分配", name="android.view.View", type="android.view.View").get_text(),
                     "未分配", msg="未分配")
        poco(text="未分配", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630243471.png", record_pos=(-0.224, -0.396),
                       resolution=(1440, 2560)))

    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))




    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1627868513033.png", record_pos=(-0.394, 0.656),
                               resolution=(1440, 2560)), "线索池:未分配筛选-450条线索")
    else:
        time.sleep(3.0)
        assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1627868513033.png", record_pos=(-0.394, 0.656),
                               resolution=(1440, 2560)), "线索池:未分配筛选-450条线索")

except Exception as e:
    log(e, snapshot=True)






print("----------------------------------- 线索池:手动退回筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 取消勾选未分配按钮
    print("取消勾选未分配按钮")
    time.sleep(3.0)
    if poco(text="未分配", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="未分配", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "未分配", msg="未分配")
        poco(text="未分配", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630243471.png", record_pos=(-0.224, -0.396),
                       resolution=(1440, 2560)))



    # 勾选手动退回按钮
    print("勾选手动退回按钮")
    time.sleep(3.0)
    if poco(text="手动退回", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="手动退回", name="android.view.View", type="android.view.View").get_text(),
                     "手动退回", msg="手动退回")
        poco(text="手动退回", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625646163430.png", record_pos=(-0.012, -0.395),
                       resolution=(1440, 2560)))

    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
        time.sleep(3.0)
        assert_equal(poco(text="未搜索到相关线索,更换搜索条件试试!", name="android.view.View", type="android.view.View").get_text(),
                     "未搜索到相关线索,更换搜索条件试试!", msg="线索池:手动退回筛选-未搜索到相关线索,更换搜索条件试试!")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_equal(poco(text="未搜索到相关线索,更换搜索条件试试!", name="android.view.View", type="android.view.View").get_text(),
                     "未搜索到相关线索,更换搜索条件试试!", msg="线索池:手动退回筛选-未搜索到相关线索,更换搜索条件试试!")
except Exception as e:
    log(e, snapshot=True)








print("----------------------------------- 线索池:自动掉保筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 取消勾选手动退回按钮
    print("取消勾选手动退回按钮")
    time.sleep(3.0)
    if poco(text="手动退回", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="手动退回", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "手动退回", msg="手动退回")
        poco(text="手动退回", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625646163430.png", record_pos=(-0.012, -0.395),
                       resolution=(1440, 2560)))


    # 勾选自动掉保按钮
    print("勾选自动掉保按钮")
    time.sleep(3.0)
    if poco(text="自动掉保", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="自动掉保", name="android.view.View", type="android.view.View").get_text(),
                     "自动掉保", msg="自动掉保")
        poco(text="自动掉保", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1627885758347.png", record_pos=(0.223, -0.394),
                       resolution=(1440, 2560)))


    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))



    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626155357197.png", record_pos=(-0.348, 0.656),
                               resolution=(1440, 2560)), "线索池:自动掉保筛选-自动掉保筛选")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626148104880.png", record_pos=(0.362, -0.541),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626155357197.png", record_pos=(-0.348, 0.656),
                               resolution=(1440, 2560)), "线索池:自动掉保筛选-自动掉保筛选")
except Exception as e:
    log(e, snapshot=True)







print("----------------------------------- 线索池:联系电话 有 筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 取消勾选自动掉保按钮
    print("取消勾选自动掉保按钮")
    time.sleep(3.0)
    if poco(text="自动掉保", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="自动掉保", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "自动掉保", msg="自动掉保")
        poco(text="自动掉保", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625646033518.png", record_pos=(0.218, -0.394),
                       resolution=(1440, 2560)))



    # 勾选联系电话 有 按钮
    time.sleep(3.0)
    if poco(text="有", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="有", name="android.view.View", type="android.view.View").get_text(),
                     "有", msg="有")
        poco(text="有", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647082738.png", record_pos=(-0.422, -0.154),
                       resolution=(1440, 2560)))


    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
        time.sleep(3.0)
        assert_equal(poco(text="石家庄冀华众合投资集团有限公司", name="companyTitle1074792", type="android.view.View").get_text(),
                     "石家庄冀华众合投资集团有限公司", msg="线索池:联系电话 有 筛选-石家庄冀华众合投资集团有限公司")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_equal(poco(text="石家庄冀华众合投资集团有限公司", name="companyTitle1074792", type="android.view.View").get_text(),
                     "石家庄冀华众合投资集团有限公司", msg="线索池:联系电话 有 筛选-石家庄冀华众合投资集团有限公司")
except Exception as e:
    log(e, snapshot=True)






print("----------------------------------- 线索池:联系电话 无 筛选 ------------------------------------")
try:

    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))


    # 勾选联系电话 无 按钮
    time.sleep(3.0)
    if poco(text="无", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="无", name="android.view.View", type="android.view.View").get_text(),
                     "无", msg="无")
        poco(text="无", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647096370.png", record_pos=(-0.295, -0.153),
                       resolution=(1440, 2560)))

    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))



    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1627566504209.png", record_pos=(-0.385, 0.658),
                               resolution=(1440, 2560)), "线索池:联系电话 无 筛选-1552条线索")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626148104880.png", record_pos=(0.362, -0.541),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1627566504209.png", record_pos=(-0.385, 0.658),
                               resolution=(1440, 2560)), "线索池:联系电话 无 筛选-1552条线索")
except Exception as e:
    log(e, snapshot=True)








print("-----------------------------------重置操作 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 点击重置按钮
    time.sleep(3.0)
    if poco(text="重置", name="android.widget.Button", type="android.widget.Button").exists():
        assert_equal(poco(text="重置", name="android.widget.Button", type="android.widget.Button").get_text(),
                     "重置", msg="重置")
        poco(text="重置", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625646806548.png", record_pos=(-0.325, 0.397),
                       resolution=(1440, 2560)))

except Exception as e:
    log(e, snapshot=True)






print("----------------------------------- 线索池:潜在线索筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))



    # 勾选潜在线索按钮
    time.sleep(3.0)
    if poco(text="潜在线索", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="潜在线索", name="android.view.View", type="android.view.View").get_text(),
                     "潜在线索", msg="潜在线索")
        poco(text="潜在线索", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647782091.png", record_pos=(-0.367, 0.082),
                       resolution=(1440, 2560)))



    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))


    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_exists(Template(r"D:\QCC_AIRTEST_PROJECTS\air\images\tpl1627562135193.png", record_pos=(-0.403, 0.658),
                               resolution=(1440, 2560)), "线索池:潜在线索筛选-10条线索")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626148104880.png", record_pos=(0.362, -0.541),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_exists(Template(r"D:\QCC_AIRTEST_PROJECTS\air\images\tpl1627562135193.png", record_pos=(-0.403, 0.658),
                               resolution=(1440, 2560)), "线索池:潜在线索筛选-10条线索")
except Exception as e:
    log(e, snapshot=True)







print("----------------------------------- 线索池:市场认可线索筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 取消勾选潜在线索
    print("取消勾选潜在线索")
    time.sleep(3.0)
    if poco(text="潜在线索", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="潜在线索", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "潜在线索", msg="潜在线索")
        poco(text="潜在线索", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647782091.png", record_pos=(-0.367, 0.082),
                       resolution=(1440, 2560)))



    # 勾选市场认可线索按钮
    time.sleep(3.0)
    if poco(text="市场认可线索", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="市场认可线索", name="android.view.View", type="android.view.View").get_text(),
                     "市场认可线索", msg="市场认可线索")
        poco(text="市场认可线索", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647789570.png", record_pos=(-0.103, 0.086),
                       resolution=(1440, 2560)))


    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))




    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_exists(Template(r"D:\QCC_AIRTEST_PROJECTS\air\images\tpl1627562135193.png", record_pos=(-0.403, 0.658),
                               resolution=(1440, 2560)), "线索池:市场认可线索筛选-10条线索")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626148104880.png", record_pos=(0.362, -0.541),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_exists(Template(r"D:\QCC_AIRTEST_PROJECTS\air\images\tpl1627562135193.png", record_pos=(-0.403, 0.658),
                               resolution=(1440, 2560)), "线索池:市场认可线索筛选-10条线索")

except Exception as e:
    log(e, snapshot=True)








print("-----------------------------------线索池:销售认可线索筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 取消勾选市场认可线索
    print("取消勾选市场认可线索")
    time.sleep(3.0)
    if poco(text="市场认可线索", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="市场认可线索", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "市场认可线索", msg="市场认可线索")
        poco(text="市场认可线索", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647789570.png", record_pos=(-0.103, 0.086),
                       resolution=(1440, 2560)))



    # 勾选销售认可线索按钮
    time.sleep(3.0)
    if poco(text="销售认可线索", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="销售认可线索", name="android.view.View", type="android.view.View").get_text(),
                     "销售认可线索", msg="销售认可线索")
        poco(text="销售认可线索", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647796079.png", record_pos=(0.194, 0.084),
                       resolution=(1440, 2560)))



    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))



    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_exists(Template(r"D:\QCC_AIRTEST_PROJECTS\air\images\tpl1627562135193.png", record_pos=(-0.403, 0.658),
                               resolution=(1440, 2560)), "线索池:销售认可线索筛选-10条线索")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626148104880.png", record_pos=(0.362, -0.541),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_exists(Template(r"D:\QCC_AIRTEST_PROJECTS\air\images\tpl1627562135193.png", record_pos=(-0.403, 0.658),
                               resolution=(1440, 2560)), "线索池:销售认可线索筛选-10条线索")
except Exception as e:
    log(e, snapshot=True)







print("-----------------------------------线索池:其他线索筛选 ------------------------------------")
try:
    # 点击筛选按钮
    print("点击筛选按钮")
    time.sleep(3.0)
    if poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "筛选", msg="筛选")
        poco(text="筛选", name="android.widget.TextView", type="android.widget.TextView").click()
    elif exists(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                             resolution=(1440, 2560))):
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630151003.png", record_pos=(0.003, -0.54),
                       resolution=(1440, 2560)))
    else:
        touch((750, 500))

    # 取消勾选销售认可线索
    print("取消勾选销售认可线索")
    time.sleep(3.0)
    if poco(text="销售认可线索", name="android.widget.TextView", type="android.widget.TextView").exists():
        assert_equal(poco(text="销售认可线索", name="android.widget.TextView", type="android.widget.TextView").get_text(),
                     "销售认可线索", msg="销售认可线索")
        poco(text="销售认可线索", name="android.widget.TextView", type="android.widget.TextView").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647796079.png", record_pos=(0.194, 0.084),
                       resolution=(1440, 2560)))



    # 勾选其他按钮
    time.sleep(3.0)
    if poco(text="其他", name="android.view.View", type="android.view.View").exists():
        assert_equal(poco(text="其他", name="android.view.View", type="android.view.View").get_text(),
                     "其他", msg="其他")
        poco(text="其他", name="android.view.View", type="android.view.View").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625647802933.png", record_pos=(-0.404, 0.217),
                       resolution=(1440, 2560)))

    # 点击确认按钮
    print("点击确认按钮")
    time.sleep(3.0)
    if poco(text="确认", name="android.widget.Button", type="android.widget.Button").exists():
        poco(text="确认", name="android.widget.Button", type="android.widget.Button").click()
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1625630319050.png", record_pos=(0.144, 0.401),
                       resolution=(1440, 2560)))




    # 点击批量按钮
    print("点击批量按钮")
    time.sleep(3.0)
    if poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").exists():
        poco(text="批量", name="android.widget.TextView", type="android.widget.TextView").click()
        time.sleep(3.0)
        assert_exists(Template(r"D:\QCC_AIRTEST_PROJECTS\air\images\tpl1627562135193.png", record_pos=(-0.403, 0.658),
                               resolution=(1440, 2560)), "线索池:其他线索筛选-10条线索")
    else:
        touch(Template(r"D:/QCC_AIRTEST_PROJECTS/air/images/tpl1626148104880.png", record_pos=(0.362, -0.541),
                       resolution=(1440, 2560)))
        time.sleep(3.0)
        assert_exists(Template(r"D:\QCC_AIRTEST_PROJECTS\air\images\tpl1627562135193.png", record_pos=(-0.403, 0.658),
                               resolution=(1440, 2560)), "线索池:其他线索筛选-10条线索")
except Exception as e:
    log(e, snapshot=True)






# 返回上一级
print("------------------------ 返回上一级 --------------------")
try:
    time.sleep(2.0)
    if poco(name="com.android.icredit:id/j6", type="android.widget.ImageButton").exists():
        poco(name="com.android.icredit:id/j6", type="android.widget.ImageButton").click()
    else:
        touch((100, 200))
except Exception as e:
    log(e, snapshot=True)

print("--------------------------------- 报告已生成,程序执行完毕 -------------------------------")





# print("----------------------------------- 开始关闭应用 ------------------------------------")
# try:
#     stop_app("com.android.icredit")
#     time.sleep(3.0)
# except Exception as e:
#     log(e, snapshot=True)



测试报告模板

<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
<html>
<head>
    <title>微信小程序回归测试概览</title>
    <style>
        .fail {
            color: red;
            background-color: lightsalmon;
            text-align: center;
        }
        .success {
            color: green;
            background-color: lightgreen;
            text-align: center;
        }
        .details-col-elapsed {
            color: lightslategray;
            text-align: center;
        }
        .details-col-msg {
            color: white;
            text-align: center;
            background-color: steelblue;
        }
    </style>
</head>
<body>
<div>
    <div class="panel panel-primary" style="margin-right: 20px;">
    <div class="panel-heading">
        <h2>
            <span class="text-success"><i class="glyphicon glyphicon-flag"></i></span>{{project}}<font color="white"> SUMMARY REPORT </font>
        </h2>
    </div>
    <div class="panel-body">
        <h4>
            测试设备:<code color="#778899">{{device}}</code>
        </h4>
        <h4>
            开始时间:<code><font color="#778899">{{stime}}</font></code>
        </h4>
        <h4>
            结束时间:<code><font color="#778899">{{etime}}</font></code>
        </h4>
        <h4>
            累计耗时:<code><span style="background-color:lightgray;border-radius:5px;padding-left:3px;padding-right:3px;"><font color="#4169e1">{{duration}}秒</font></span></code>
        </h4>
        <h4>测试结果:Total-&nbsp;<font color="DodgerBlue">{{results|length}}</font>,&nbsp;Success-&nbsp<font color="green">{{success}}</font>,&nbsp;Fail-&nbsp;<font color="red">{{fail}}</font></h4>
        <div class="col-xs-9">
            <table width="800" border="thin" cellspacing="0" cellpadding="0" class='table table-striped'>
                <tr  width="600">
                    <th class="details-col-msg col-xs-1">序号</th>
                    <th width="300" class='details-col-msg col-xs-3'>用例名称</th>
                    <th class='details-col-msg  col-xs-3'>执行结果</th>
                </tr>
                {% for r in results %}
                <tr>
                    <td class="details-col-elapsed  col-xs-1">{{loop.index}}</td>
                    <td class='details-col-elapsed  col-xs-3'><a href="../log/{{r.name}}/log.html" target="view_window">{{r.name}}</a></td>
                    <td class="{{'success' if r.result else 'fail'}}  col-xs-3">{{"成功" if r.result else "失败"}}</td>
                </tr>
                {% endfor %}
            </table>
        </div>
        <div class="col-xs-5 pull-left">

                <div id="pie_echarts" class="layui-card-body" style="width: 100%;height:200%;">
                </div>

        </div>
    </div>
</div>
</div>
</body>

<script src="https://cdn.bootcss.com/echarts/4.4.0-rc.1/echarts.min.js"></script>
<script>
// 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('pie_echarts'));
    // 指定图表的配置项和数据
    option = {
        title: {
            text: '执行结果统计:',
            x: 'left'
        },
        tooltip: {
            trigger: 'item',
            formatter: "{a} <br/>{b} : {c} ({d}%)"
        },
        color: ['#CD5C5C', '#9ACD32'],
        stillShowZeroSum: false,
        series: [
            {
                name: '测试结果',
                type: 'pie',
                radius: '80%',
                center: ['60%', '60%'],
                data: [
                    {value: {{fail|tojson}}, name: '失败'},
                    {value: {{success|tojson}}, name: '成功'}
                    ],
                itemStyle: {
                    emphasis: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(128, 128, 128, 0.5)'
                    },
                    normal:{
                       label:{
                          show: true,
                          formatter: '{b} : {c} ({d}%)'
                        },
                        labelLine :{show:true}
                    }
                }
            }
        ]
    };
    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);

</script>

</html>

批量执行启动器

from airtest.cli.runner import AirtestCase, run_script
import airtest.report.report as report
from airtest.report.report import simple_report

#from conf.send_email import send_email
from conf.settings import *
from argparse import *
import shutil,os,io,jinja2,datetime
from lib.common import RetryFunc
from lib import video
from airtest.core.helper import device_platform
from airtest.core.api import auto_setup, log, connect_device


class Air_Case_Handler(AirtestCase):
    def __init__(self, dev_id):
        ''' 初始化,如果是web直接通过,如果不是,传入设备id
        connect_device 连接该设备
        '''
        super(Air_Case_Handler, self).__init__()
        if deviceType.upper() == "APP":
            pass
        else:
            self.dev = connect_device(dev_id)

    def setUp(self):
        # 程序开始前
        super(Air_Case_Handler, self).setUp()

    def tearDown(self):
        # 程序开始后
        super(Air_Case_Handler, self).tearDown()


    def run_air(self,air_dir,device):
        ''' 跑用例'''
        start_time = datetime.datetime.now()
        start_time_fmt = start_time.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
        # 结果数组,下面用到
        results = []
        root_log = log_path
        # 判断该路径是否为目录
        if os.path.isdir(root_log):
            # shutil.rmtree() 表示递归删除文件夹下的所有子文件夹和子文件
            shutil.rmtree(root_log)

        else:
            # os.makedirs() 方法用于递归创建目录。
            os.makedirs(root_log)

        # 返回指定目录下的所有文件和目录名,通过file进行循环
        for file in os.listdir(air_path):
            # 如果file中结尾带了“.air”
            if file.endswith(".air"):
                airName = file
                # 把“.air”换成空格,因为airtest自动生成的文件名带.air
                airDirName = file.replace(".air", "")
                # root\air\xxx.air,每个用例的脚本路径
                script = os.path.join(air_dir, file)
                # root\log\\xxx,每个用例的测试报告
                air_log = os.path.join(root_path, "log\\" + airDirName)  # 如果air_log是目录,删除其目录下的子目录及文件夹
                if os.path.isdir(air_log):
                    # print(air_log)
                    shutil.rmtree(air_log)

                else:
                    os.makedirs(air_log)
                # html每个用例测试报告(html文件)存放的路径,root\log\\xxx\log.html
                html = os.path.join(air_log, "log.html")
                recording_mp4 = os.path.join(air_log, airDirName+".mp4")
                if deviceType.upper() == "WEB":
                    args = Namespace(device=[], log=air_log, recording=None, script=script, language="zh", compress=0,no_image=False)
                elif deviceType.upper() == "APP":
                    args = Namespace(device=device, log=air_log, recording=recording_mp4, script=script, language= "zh", compress=0,no_image=False)
                else:
                    args = Namespace(device=device, log=air_log, recording=None, script=script, language="zh", compress=0,no_image=False)
                try:
                    run_script(args, AirtestCase)  # airtest的run方法
                except:
                    pass
                finally:
                    # 将脚本路径和测试报告(截图)路径用report.py的LogToHtml生成html文件
                    rpt = report.LogToHtml(script, air_log, lang="zh")
                    # "log_template.html"报告名称,输出文件是HTML文件
                    rpt.report("log_template.html", output_file=html)
                    #simple_report(script, air_log,output=html,p)
                    result={}
                    result["name"] = airName.replace('.air', '')
                    result["result"] = rpt.test_result
                    results.append(result)

        end_time = datetime.datetime.now()
        end_time_fmt = end_time.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]


        duration = (end_time - start_time).seconds

        # jinja2是python的模板引擎(语法),loader模板加载器,FileSystemLoader从文件目录中获取模板
        env = jinja2.Environment(
            loader=jinja2.FileSystemLoader(template_path),
            extensions=(),
            autoescape=True
        )

        template = env.get_template(template_name, template_path)
        project_name = root_path.split("\\")[-1]
        success = 0
        fail = 0
        for res in results:
            if res['result']:
                success += 1
            else:
                fail += 1
        report_name = end_time.strftime("%Y-%m-%d %H-%M-%S")+"SummayrReport" + ".html"
        html = template.render({"results": results, "device": device, "stime": start_time_fmt, 'etime':end_time_fmt,'duration': duration, "project": project_name, "success": success, "fail": fail})
        output_file = os.path.join(root_path, "report", report_name)
        with io.open(output_file, 'w', encoding="utf-8") as f:
            f.write(html)

if __name__ == "__main__":
    for device in devices:
        test = Air_Case_Handler(device)
        test.run_air(air_path, device)

    # 发送测试报告到邮箱
    # email = send_email("369788028@qq.com")
    # new_report = email.new_report(report_path)
    # email.send_mail(new_report)

BAT 脚本

python runCase.py
pause()
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 10 条回复 时间 点赞

请教作者,这套用例修改维护的方便吗,airtest 方不方便做成 PO 模式的呢?

Dirty不加冰 回复

airtest 只是框架,po 是设计模式,两者不是一个概念,设计模式是针对你写的代码逻辑。

这套用例有学习的地址吗大佬,想学一下

用例是我自己工作中的业务,这个没必要学了,你看框架就行

大佬,可以出一篇搭建框架的教程吗?

Jerrygu 回复

已经好久不用了,等以后工作上需要我再单独写吧。

僅樓主可見
僅樓主可見
9楼 已删除
大海 #10 · 2025年11月04日 Author

还真被我找到了,我百度网盘发给你。
通过网盘分享的文件:QCC_AIRTEST_PROJECTS.rar
链接: https://pan.baidu.com/s/1OzuWTyA5Rg22pQYy9o-FIg?pwd=nssf 提取码: nssf,你尽快下载,1 天有效期。

大海 回复

感谢大佬~

需要 登录 後方可回應,如果你還沒有帳號按這裡 注册