自动化意识演变(六)-一键生成报告allure+jenkins
为什么要生成报告
- 可视化给领导看
- 统计数据(成功率、采集数据)
- 留存历史数据
怎么生成报告
自带插件pytest-html
三方插件allure(allure更像一个服务)
- pytest-html
pytest-html是一个插件,pytest用于生成测试结果的HTML报告
如果要生成报告,代码如下:
import pytest
if __name__ == "__main__":
pytest.main(['--html=report.html'])
从上面一行代码看出,其实生成自带的html报告很简单,所以就会造成想要的报告形式过于简单。
执行代码后,生成的report.html文件和执行命令的文件(run.py)属于同一个目录。
file:///C:/Users/admin/Desktop/api-test/test/report.html
- allure+jenkins
对于多元化的报告,显然pytest-html不能满足条件,比如case属于哪项功能以及哪些场景都不是很清楚的,需要能体现在报告里面。简而言之,是能结构或者层次化。
如果单纯用allure的话,是需要启动allure服务的
生成allure报告,代码如下:
import pytest
if __name__ == "__main__":
pytest.main(['--alluredir=allure-results'])
当然,默认的allure报告也可以用这个简单一行代码生成,但是能看出来,上面生成的其实是一个文件夹,这个文件夹里面包含txt和xml文件,此时并不能通过打开某个文件看出整个测试报告,你可以理解为要一次性打开整个套件(文件夹)。
此时,需要用到allure服务,将这些套件进行处理
1. allure generate report生成报告
2. allure open allure-report本地显示报告
3. allure serve allure-report对外显示报告
http://10.104.34.167:55210/index.html
所以如果要生成allure报告,还需要启动allure服务并且三步指令,无疑是增加环境部署工作量,那么有没有一个工具能做到一键执行代码并同时生成报告呢(自动化)。
显然是有的,这时候想到了jenkins集成,利用jenkins不仅能记录历史报告,也能直接将python脚本和allure服务串接,即不仅jenkins要安装可以给allure展示报告的插件Allure Jenkins Plugin,也要python执行脚本时用于allure收集信息的插件pytest-allure-adaptor。
这时候就需要更改文件路径,因为如果要jenkins生成报告,就得将python脚本生成报告的地址对应到jenkins的目录里,如下:
import pytest
if __name__ == "__main__":
pytest.main(['-s', '-q', '--alluredir', '${WORKSPACE}/target/allure-results'])
这里的workspace对应到jenkins的目录了,具体原因参考某位大佬的说明:
https://zhuanlan.zhihu.com/p/107496181
报告结构化
allure报告链路已经通了,那么就需要更细节化了
首先我们得知道allure怎么编译使报告结构化,也就是分级
* feature 模块级别
* stroy 功能级别
* severity 优先级
* step 测试步骤
* description 用例描述
基本结合测试用例所需元素扩展的
结合代码体现:
from core.requestHandle import RequestHandle
from core.loggingHandle import LoggingHandle
import allure
log = LoggingHandle('TestTruck')
@allure.MASTER_HELPER.feature('Truck')
class TestTruck(object):
@allure.MASTER_HELPER.story('用户信息')
@allure.MASTER_HELPER.severity(allure.MASTER_HELPER.severity_level.CRITICAL)
def test_getInfo(self, params):
path = "/x/tree-game/truck/get-info"
with allure.MASTER_HELPER.step('请求接口:'+path):
response = RequestHandle(path).get(params)
log.debug(response)
code = response['code']
assert code == 0
当然,如果每个case都按照上述结构化显得复杂,可以视情况而定,一般加上feature给单个class用,然后每个函数加上stroy就行了,比如:
from core.requestHandle import RequestHandle
from core.loggingHandle import LoggingHandle
import allure
log=LoggingHandle('TestTaskPop')
@allure.MASTER_HELPER.feature('TaskPop')
class TestTaskPop(object):
@allure.MASTER_HELPER.story('用户信息')
def test_pop(self,params):
path = "/x/tree-game/task/pop/info"
response = RequestHandle(path).get(params)
log.debug(response)
code = response['code']
assert code == 0
接下来要做的事还很多,列举了一下几个点
1.请求头兼容(请求体统一为字典格式)
2.path接口封装
3.redis和bd处理数据
4.fixture参数化
5.搭建一个web可视化自动化项目