目录
框架需求及实现方案
框架需求
实现方案
支持接口自动化、Web UI自动化及App自动化#
可以批量运行用例并生成测试报告
测试完成发送邮件
提供灵活的运行方式,如按功能模块运行、按脚本运行、按用例等级运行等等
提供运行日志方便定位问题
支持切换环境
支持数据库断言
减少维护成本
增加运行的稳定性
提高运行效率
框架规划
功能规划及方案选择
总结:
框架需求及实现方案
框架是为了解决某一特定问题而设计的。在搭建测试框架前,我们要清楚我们的需求以及设计目标。然后才能根据需求来选择实现方案。
框架需求
假设我们要设计一款,支持接口自动化、Web UI自动化及App自动化的全栈自动化测试框架,我们的需求如下:
- 支持接口自动化、Web UI自动化及App自动化
- 可以批量运行用例并生成测试报告;
- 测试完成发送邮件;
- 提供灵活的运行方式,如按功能模块运行、按脚本运行、按用例等级运行等等;
- 提供运行日志方便定位问题;
- 支持切换环境;
- 支持数据库断言;
- 减少维护成本;
- 增加运行的稳定性;
- 提高运行效率。
这些是测试框架常见的需求,另外还包括,灵活的实用方式,如配置分类,数据分类,尽量设计的易用和清晰,支持持续集成等等。我们可以根据这些需求,结合Pytest框架来选择实现方案。
实现方案
由于Pytest非常灵活且生态丰富,我们使用Pytest作为基础框架来实现这些需求,针对以上每个需求,我们的简单实现方案如下:
支持接口自动化、Web UI自动化及App自动化#
我们通过封装requests、selenium、appium-python-client库来为框架提供操作HTTP接口、Web浏览器以及App的方法。
在用例目录中使用api_test、web_test、app_test对接口自动化用例、Web UIz i动画用例及App UI自动化用例进行分别管理。
安装方法:
$ pip3 install requests selenium appium-python-client
可以批量运行用例并生成测试报告
按Pytest用例格式编写测试用例函数或类,我们便可以在命令行使用pytest命令批量选择用例执行。
生成测试报告我们可以使用Pytest三方插件pytest-html或allure-pytest,pytest-html测试报告简单方便,allure-pytest生成的测试报告绚丽多彩,这里选择使用allure-pytest作为测试报告生成工具。同时还需要下载allure-commandline工具来将测试数据转为测试报告网站。
安装方法:
$ pip3 install allure-pytest
命令行工具下载链接:
测试完成发送邮件
由于Allure生成的测试报告是一个文件夹,我们需要将报告压缩后发送,压缩可以使用Python自带的zipfile模块,发送邮件可以使用Python自带的email模块来组装邮件消息所需的MIME格式,然后使用smtplib连接自己邮箱的SMTP服务来发送。相应的模块需要我们自己封装。
如何在Pytest执行用例完成后自动发送邮件?这里我们需要使用Pytest的钩子方法,在测试完成生成命令行终端测试总结的时候,捎带执行我们的发送测试报告的方法。
即:
def pytest_terminal_summary(config):# 稍带发送邮件
另外,我们还需要增加一个自定义的命令行参数—send-email来控制运行完是否发送邮件,同时添加一些自定义ini配置,来配置邮件的主题、正文、收件人以及发件邮箱SMTP服务地址、用户名密码等。
另外,也可以使用Jenkins的邮件通知功能来实现测试完成发送邮件。
提供灵活的运行方式,如按功能模块运行、按脚本运行、按用例等级运行等等
Pytest本身提供了灵活的运行方式,如按目录运行、按测试脚本运行、按用例命名规则运行及按用例标记运行等等。我们可以在用例目录中,按功能模块建立子目录,这样便可以通过指定目录来运行特定的模块。
对于用例等级,我们可以使用pytest-level插件,也可以使用allure-pytest中的@allure.severity装饰器来设置不同的严重(优先)等级。由于已经使用了Allure报告框架,这里使用@allure.severity来设置用例等级
同时,我们可以在框架中规范用例的名称以及设立自定义标记来对用例进行更灵活的归类。
提供运行日志方便定位问题
日志是框架必不可少的一部分,相比与使用print函数输出信息,日志可以记录运行的时间,调用的函数、代码行等各种信息,并能根据日志等级来控制输出的详略程度。
Pytest自带有日志功能,我们只需要在pytest.ini中配置即可。在框架代码中使用Python自带的logging模块输出需要的信息即可。
支持切换环境
在手工测试过程中往往要经历不同“环境”(测试阶段)等测试,如test(测试)环境、stage(预发)、prod(生产)环境等等。自动化测试同样需要支持切换不同的环境进行测试。
大部分情况下,不同环境只是部署服务的地址(base_url)不一样,我们可以使用插件pytest-base-url来通过命令后或配置来修改base_url,由此来实现环境的切换。
如果不同环境还需要不同的数据时,我们可以配合插件pytest-variables来通过指定不同的数据文件来切换对应的数据,例如:
$ pytest --base-url=https://www.xxx.com --variables=prod.json
或在pytest.ini中配置
[pytest]
adopts = --variables=prod.json
base_url=https://www.xxx.com
安装方法如下:
$ pip3 install pytest-base-url pytest-variables
支持数据库断言
在接口自动化测试过程中,经常要对比校验数据库中的数据。在用例执行前或执行后有时候还需要通过执行SQL来完成数据准备或环境清理。因此我们在框架中要提供数据库操作的能力。以MySQL数据库为例,我们可以使用三方库pymysql来连接并操作MySQL数据库。通过封装来简化数据库操作,然后根据不同的库,封装成Pytest Fixture函数来方便用例直接使用。
安装方法:
$ pip3 install pymysql
Redis、PostgreSQL、Oracle、MongoDB等其他数据库也可以使用对应的包进行封装。
减少维护成本
自动化框架和用例往往并不是一劳永逸的。开发完成后往往还需要根据业务的迭代不断的进行维护。尽量减少将来的维护成本也是我们需要考虑的问题之一。
分层及模块化是减少维护成本低有效方法之一。减少维护成本的关键操作是解耦,就是把不同的模块分开,这样既可以灵活组合,又可以有效收缩问题的范围。分层是将不同的操作分成不同的层,如:
底层操作:例如,发送请求、数据库操作、操作Web、操作App、发送邮件、读取数据等
业务操作:例如,调用底层操作完成,业务接口请求、操作某个页面或App某个流程等
用例操作:调用业务操作或底层操作完成测试准备、测试步骤及测试清理等
分成模型是软件架构中最常见的模型,主要特点是不同层职责清晰、单向依赖,即上层依赖下层、下层为上层服务。
增加运行的稳定性
不稳定用例(flaky tests)处理,是自动化,特别UI自动化必须要面对的问题之一。常见的导致用例不稳定的原因一般有:
- 当前环境状态不适合某些用例执行
- 网络不稳定,导致在网络较差的情况下打开页面超时
- 偶现的弹框等导致操作中断
- 环境或服务偶现的不可用或异常状态
前三种情况出现执行失败,一般属于误报,而最后一种又可能是误报也有坑你是存在偶现性的Bug,这个要配合监控根据实际情况进行定位。
对应环境状态不适合某些用例执行的情况,我们可以使用@pytest.mark.skipIf()增加对环境的检查以在不适宜执行时跳过该用例。
当网络不稳定时,在Web UI和App UI自动化中使用driver.implicitly_wait(),智能等待可以有效应对元素定位时的延迟问题。
对于偶现的弹框,除了在用例中尽可能的考虑到,捕获并处理这些异常以为,也可以在操作前或启动独立的线程对是否存在弹框进行校验并处理。
对于环境或服务偶现的不可用或异常状态,或上面其他问题导致的用例不稳定,用例重跑是最有效的方法之一,我们可以使用pytest-rerunfailures插件来对单个或所有用例设置用例失败后进行重试几次,另外还可以设置等待的间隔时间。
安装方法:
$ pip3 install pytest-rerunfailures
对用例单独使用的方法如下:
@pytest.mark.flaky(reruns=5, reruns_delay=2)
def test_example():pass
对所有用例使用的方法如下:
$ pytest --reruns 5 --reruns-delay 2
即每条用例失败最多重跑5次,每次重跑间隔2秒。
提高运行效率
当用例数量多起来的情况下,提高运行效率变成为一个问题。多进程并行或多线程并发是常用的方式之一。相对于多线程共享变量,以及Python的GIL锁问题。使用多进程在某些情况下可能会更安全和更有效率一点。
我们可以使用pytest-xdist插件来启动多个进程来执行用例。一般来说,运行的最小独立单位是一条用例,用例平均分配到不同的进程中执行。用例的执行顺序往往是不可控的,这就要求,用例之间不要存在顺序依赖,每条用例都可以单独执行,互不影响。
另外,为了防止某些用例执行陷入长久等待,我们可以使用pytest-timeout为用例设置超时时间,防止用例卡死,并顺利的执行完所有的用例。
安装方法:
$ pip3 install pytest-xdist pytest-timeout
使用方法:
$ pytest -n 4 --timeout 60
即启动4个进程运行用例,每条用例最大执行时间限制为60秒。
框架规划
框架规划时需要考虑解决的问题和实现的目标。接口测试框架一般需要实现的功能如下:
基础功能
- 接口授权等公共方法的封装
- 批量运行并生成测试报告
- 发送邮件通知
- 使用日志记录方便追溯问题
灵活性
- 支持灵活的断言方式、包括响应文本断言、JSON断言、JSONPath提取、JSONSchema断言、数据库断言等
- 支持切换不同的测试环境
- 支持灵活的运行方式,按模块、标记、等级运行
效率
- 提高用例执行效率
易用性
- 数据分离以降低代码的修改成本
- 增加框架的易用性、报告的易读性
功能规划及方案选择
针对上面列出的目标,我们选择的方案如下
- 数据库断言 pymysql -> 封装
- 环境清理 数据库操作 -> Fixtures
- 并发执行 pytest-xdist 多进程并行
- 复合断言 pytest-check
- 环境切换 pytest-base-url
- 数据分离 pyyaml
- 配置分离 pytest.ini
- 报告生成 pytest-html
- 用例等级 pytest-level
- 限制用例超时时间 pytest-timeout
- 发送报告邮件 通过自定Fixture及Hooks实现
总结:
感谢每一个认真阅读我文章的人!!!
我个人整理了我这几年软件测试生涯整理的一些技术资料,包含:电子书,简历模块,各种工作模板,面试宝典,自学项目等。欢迎大家点击下方名片免费领取,千万不要错过哦。