基于Airtest+Python构建的自动化测试框架

目前UI自动化测试目前主要分为元素定位、图像识别两种实现方式,其中元素定位方式为主流,图像识别方式为辅助方式。实际的自动化测试中,有的业务场景元素定位会比较困难,比如游戏类app、小程序页面、windows应用程序等,加上元素定位方式普遍存在的两个缺点:

  • 元素位置定位&维护成本高

  • 代码编写效率慢&入门有一定门槛&代码维护成本高

因此当元素定位方式不适合你的测试场景时,选用图片识别方式是另一条可行的测试方向。

那么今天我们主要分享一下如何基于Airtest+Python搭建一套适用于企业级可运行的自动化测试框架,希望对有这方面需求的同学有所帮助!

框架结构图

Airtest自带pywinauto以及多种图片识别技术,因此无需重复造轮子,是非常好用的图像识别自动化测试工具。加上Airtest基于python,可以较好的进行扩展和定制,因此可搭建Airtest+Python自动化测试框架。框架同时支持UI+接口自动化测试,UI界面操作完成后可继续进行服务端相关接口层面的验证,完成整个闭环。

框架结构图:

项目目录说明

项目目录说明:

Autotest
--config                                    存放配置文件
    --global_config.py                      用于配置全局的通用的变量,比如域名、登录账号等                              
--log                                       存放每个case单场景运行测试报告
    --yyyy-mm-dd-hh-mm-ss_singleCaseName    用于存放每个case的详细测试报告文件
--resources                                 存放接口测试资源文件
    --singleCaseName.json                   单个case的接口测试资源Json文件
--testcases                                 存放测试用例文件
    --singleCaseName.air                    单个case的Airtest脚本文件夹
--utils                                     存放封装的通用工具类
    --http_utils.py                         http接口封装request工具类
    --read_json_file_utils.py               json文件读取工具类
    --common_utils.py                       通用工具类
    --report_template.py                    整体测试报告生成工具类
--run.py                                    执行测试py文件, 包含逻辑:读取+运行case+生成报告

Python工程项目图:


其他说明:

Airtest IDE编写UI自动化测试脚本基本无需编程代码知识,上手编写脚本非常快,可快速完成大量测试脚本编写。关于如何提高脚本的稳定性、健壮性,以及使用中的一些技巧经验,可参看我之前的文章。

相关技术难点处理

难点1:Airtest IDE上编写的UI自动化测试脚本,每一个测试case是单独的一个.air文件夹,里面包含了.py的脚本文件和图片文件,每个脚本都是单独运行,如何将其批量运行并接入python框架?

解决方案:调研Airtest支持命令行模式运行,通过python代码发现框架下airtest脚本,调用cmd执行对应的命令,实现在python框架下批量运行脚本的功能。

def discover_test_cases(self):
    """
    发现项目目录下所有的测试用例,以‘.air’后缀作为测试用例脚本作为判断依据
    """
    test_cases = list()
    for root, dirs, files in os.walk(self._test_case_dir):
        paths = [os.path.join(root, d) for d in dirs if d.endswith(".air")]
        test_cases.extend(paths)
    return test_cases

def get_command(self, test_case):
    """
    构造生成测试报告命令
    """
    command = "airtest report {0} --log_root {1} --outfile {2} --lang {3}".format(test_case, self.log_root, self.outfile, self.lang)
    return command


def run(self, test_case, log_root, outfile=None):
    """
    执行生成测试报告命令
    """
    self.log_root = log_root
    self._outfile = outfile if outfile else ""
    cmd = self.get_command(test_case)
    os.system(cmd)

难点2:框架要实现一个测试脚本中既能执行该场景的UI自动化,又能执行该场景的接口自动化。UI自动化运行时采用的是Airtest框架,无法再使用接口自动化的unittest/pytest框架,怎样处理接口自动化的数据驱动和case运行管理机制?

解决方案:一次运行无法同时使用两套框架,因此不使用现有的unittest/pytest框架,使用python自研实现接口自动化需要的数据驱动和case运行机制:

  • 数据驱动:通过resource文件夹下json文件管理接口测试数据入参和期望结果,通过json文件读取工具类实现接口入参和期望结果的获取。

  • case运行机制:目前提供运行所有case、运行指定的某条case、运行指定优先级的case3种case运行方式。

@staticmethod
def partner_post_interface(file_path, file_name, cookies, domain_url):
    # 获取文件相对路径
    data_file_path = ReadJsonFileUtils.get_data_path(file_path, file_name)
    # 读取测试数据文件
    param_data = ReadJsonFileUtils(data_file_path)
    # 是一个list列表,list列表中包含多个字典
    data_item = param_data.get_value('dataItem')

    # 循环获取list中的数据,根据数据发起多次测试
    for i in data_item:
        print("用例ID:{}".format(i['id']))
        print("用例名称:{}".format(i['name']))
        logging.info("测试开始啦~~~~~~~")

        req_header = i['headers']
        req_header['Cookie'] = cookies

        res = HttpUtils.http_post(req_header, domain_url + i['url'], i['parameters'])

      # 添加断言判断,判断接口是否返回期望的结果数据
      # 循环获取expectdata中的所有的key和value,key是item[0],value是item[1]
      for item in i['expectdata'].items():
          # 拼接好jsonpath的路径格式
          res_key_path = "$." + item[0]
          # 使用jsonpath获取到值
          res_key_value = jsonpath.jsonpath(res, res_key_path)[0]
          print("res key:" + res_key_path + "," + "res value:" + str(res_key_value))

          if str(res_key_value) == str(item[1]):
            pass
          else:
            error_message1 = "接口返回值不等于预期值,\n" + "用例ID:" + str(i['id']) + ",\n"
            error_message2 = "用例名称:" + str(i['name']) + ",\n"
            error_message3 = "接口返回结果:" + str(res)
            raise XError(error_message1 + error_message2 + error_message3)

难点3:Airtest框架每个case运行后都会生成单独的测试报告,批量运行多个case并不会生成汇总的一份测试报告,整体测试报告如何呈现?此外同一个脚本中包含UI自动化+接口自动化脚本时,接口自动化测试的结果如何在测试报告中展现?

解决方案:查看Airtest测试报告代码结构,通过python代码从每个case单独测试报告中提取出内容,整合数据编写一份新的定制化的整体测试报告。调研Airtest API源码,实现将接口自动化测试的函数运行结果也显示到Airtest报告中,通过抛出自定义异常,将接口自动化测试函数运行失败时的关键信息显示出来,方便排查定位问题原因。​​​​​​​

def run_all_test_case(self):
    test_cases = self.discover_test_cases()
    print("发现测试用例共计{0}个:".format(len(test_cases)))
    for test_case in test_cases:
        print(test_case)
    for test_case in test_cases:
        print("开始执行测试用例:{0}".format(test_case))
        self._runner.run(test_case)
        print("完成执行测试用例")
        print("开始生成用例报告")
        log_path = self._runner.log_path
        self._reporter.run(test_case, log_path)
        data = self.get_airtest_log_data(self._reporter.outfile)
        data["link"] = "/".join(self._reporter.outfile.replace(self.root_dir, "").strip(os.sep).split(os.sep))
        data["title"] = data["info"]["title"] + " " + ".".join(data["name"].replace(self.root_dir, "").strip(os.sep).split(os.sep))
        self._result.append(data)
        print("完成生成用例报告")
    template = ReportHtmlTemplateNew(self._result)
    template.build()
    report_file = template.report_file
    print("汇总所有测试用例的测试报告:{0}".format(report_file))

测试结果效果图

整体测试报告效果图示例:

单个case脚本详细测试报告示例:

以上就是本次的全部内容,如果对你有帮助,欢迎关注+点赞+分享,你的支持就是作者更新最大的动力!

最后:下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值