七、使用脚本生成Airtest报告

1. 前言

在AirtestIDE使用文档中,我们学习了如何使用AirtestIDE和命令行生成Airtest报告,今天我们来看下如何借助脚本直接帮助我们生成测试报告。

2. 使用simple_report() 接口

先来讲讲这个 simple_report 接口,它其实是1个简化版的生成报告的接口,可以减少同学们的理解成本和使用成本:

图片

  • filepath:指定脚本的路径
  • logpath:指定log内容的路径
  • logfile:指定log.txt文件的路径
  • output:指定HTML报告的生成路径,必须以 .html 结尾

如果同学们不指定任何参数,该接口会使用默认的参数生成1份HTML格式的报告,output='log.html' 表示在当前脚本路径下生成名为 log.html 的airtest报告:

  1. from airtest.report.report import simple_report
  2. simple_report(__file__)

图片

如果指定了 output 参数,则会按指定路径生成报告:

  1. from airtest.core.api import *
  2. from airtest.report.report import simple_report
  3. auto_setup(__file__,logdir=True)
  4. simple_report(__file__,logpath=True,output=r"D:\test\report02\log.html")

图片

图片

logdirlogpath

生成Airtest报告需要依赖脚本运行过程保存的log,所以如需生成报告,就需要保存脚本运行过程的log,auto_setup 接口的logdir参数可以设置log保存路径;使用simple_report生成报告时,就可以设置logpath,到logdir指定的log保存路径下面去找脚本对应的log内容。

1)利用output参数指定报告文件的名称

细心的同学可以发现,output可以指定Airtest报告的完整生成路径,包含报告文件的命名,xxx.html。利用这一点,我们可以自定义报告文件的名称:

  1. simple_report(__file__,logpath=True,output=r"D:\test\cloud_music.html")

2)重复运行脚本生成报告不覆盖历史报告

拓展一下,如果我们不指定output参数,则每次生成报告均使用默认的参数,这样会导致每次的新报告都会把旧报告覆盖掉;那如果我们想不覆盖旧报告,就可以使用这个参数,给它传入一个不重复命名规则,例如:

  1. # -*- encoding=utf8 -*-
  2. __author__ = "AirtestProject"
  3. from airtest.core.api import *
  4. from airtest.report.report import simple_report,LogToHtml
  5. auto_setup(__file__,logdir=True)
  6. a = 1
  7. while a < 4:
  8. print("这里假装执行了一些脚本")
  9. # 生成报告
  10. from airtest.report.report import simple_report
  11. simple_report(__file__,logpath=True,output="log"+str(a)+".html")
  12. a = a + 1

图片

3. 使用LogToHtml()

使用脚本生成Airtest报告的另外一种方式是使用LogToHtml() 类:

图片

这个类的参数相对于 simple_report() 就复杂的多了,包含:

  • script_root,指定脚本路径
  • log_root,指定log文件的路径
  • static_root,指定部署静态资源的服务器路径
  • export_dir,设置导出报告的存放路径
  • script_name,脚本名称
  • logfile,指定log文件log.txt的路径
  • lang,指定报告的语言(中文:zh;英文:en)
  • plugins,指定报告插件,使用了poco或者airtest-selenium会用到

1)使用LogToHtml() 类生成报告的示例

示例如下,我们在指定路径 D:\test\report02 中导出了 D:\test\report01.air 脚本的运行报告,报告语言为英文:

  1. from airtest.report.report import LogToHtml
  2. h1 = LogToHtml(script_root=r'D:\test\report01.air', log_root=r"D:\test\report01.air\log", export_dir=r"D:\test\report02" ,logfile=r'D:\test\report01.air\log\log.txt', lang='en', plugins=None)
  3. h1.report()

图片

图片

从示例中我们可以看出,使用LogToHtml类生成报告,我们需要先实例化一个LogToHtml类,然后再调用类方法report(),即可生成Airtest报告。

1)logdirlog_root

上文我们已经提到,生成Airtest报告需要依赖脚本运行的log内容,所以我们在生成报告之前,需要保存脚本运行的log内容,然后生成报告时再指定参数让它去找对应的log内容。

以上述例子为例,我们在auto_setup中指定logdir=True,即将log内容保存在当前脚本的路径下面;那生成报告时,我们再利用LogToHtmllog_root参数,来指定log的查找路径。

logdirlog_root

实际上,我们将上述示例中的log_root=r"D:\test\report01.air\log"改成log_root=True也是一样的效果,即log保存路径logdir与log查找路径log_root必须是相同的。

2)导出报告的参数export_dir

LogToHtml中使用export_dir参数,即可将Airtest报告导出,发给其它同事或者部署到文件服务器上查看。不使用该参数默认生成本地的Airtest报告,只能在本地查看,不能发送到别的地方查看。

3)指定部署静态资源的服务器地址static_root

Airtest的HTML报告包含了一些css、js之类的静态资源文件,每次导出报告时,都会导出一份静态资源文件。

为了导出报告时不用每次都导出一份一模一样的静态资源文件,我们可以将这份固定的静态资源文件部署到文件服务器上,然后给static_root参数传入部署静态资源文件的服务器地址,这样我们的报告就会到给定的服务器地址上面,去访问报告的静态资源文件,不会在报告文件夹内再复制一份静态资源文件,可以大大减少报告的体积。

4)指定报告插件plugins

当我们的自动化脚本里面包含Poco语句或者airtest-selenium语句,我们在生成报告的时候就需要传入对应的插件,来改变Airtest报告的一些样式:

  1. plugins=["poco.utils.airtest.report","airtest_selenium.report"]

5)类方法reportoutput_file参数

report 方法我们需要关注的是 output_file 参数:

image-20211117160655603

我们需要将output_fileexport_dir这两个参数区分开来,一个是指定本地报告的生成路径;一个是指定导出报告的生成路径。

  1. # example
  2. r = LogToHtml(script_root=r'D:\test\song.air',log_root=r'D:\test\song.air\log')
  3. r.report(output_file=r'D:\test\cloud_music01.html')

示例表示生成本地Airtest报告,并且指定了报告的完成生成路径,包含报告文件的名称。如果我们同时使用export_diroutput_file参数,则只有export_dir会生效,output_file将不生效。

4. 生成报告的注意事项

1)在脚本开头即使用了生成报告的脚本

新手同学很容易犯的一个错误是,将生成报告的代码放置在了脚本开头,下面跟了一系列实际操作:

  1. # -*- encoding=utf8 -*-
  2. __author__ = "AirtestProject"
  3. from airtest.core.api import *
  4. from airtest.report.report import simple_report,LogToHtml
  5. auto_setup(__file__,logdir=True)
  6. simple_report(__file__,log_path=True)
  7. touch(Template(r"tpl1637219700366.png", record_pos=(-0.103, 0.27), resolution=(1920, 1080)))
  8. sleep(1.0)
  9. snapshot(msg="请填写测试点.")
  10. # 此处省略N条脚本

这样编写的后果是,即使我们成功运行了整个脚本,但最后打开生成的报告查看时,会发现是一个空的报告;这是因为在脚本开头已经生成了测试报告,此时log未记录任何步骤的执行情况(实际运行步骤都在生成报告的脚本之后),所以将获得一个空的测试报告。

2)无论脚本是否运行成功都生成测试报告

所以一般情况下,生成报告的语句应该是放在所有用例脚本的后面,保证用例执行完毕之后,才执行生成脚本的语句。

但这里容易出现一种情况,一旦前面有用例脚本执行失败,终止了整个脚本的运行,即还没有执行到生成报告的语句时,脚本运行就已经停止了,这样也不能够正常生成报告。

所以我们可以用 try-finally 语句,不论脚本是否运行失败,最终都会生成1份运行报告,方便测试人员查看对应问题:

  1. try:
  2. poco("com.netease.newsreader.activity:id/bjd").wait_for_appearance()
  3. poco("com.netease.newsreader.activity:id/awo").click()
  4. ...
  5. finally:
  6. simple_report(__file__,logpath=True,output="../netease_music/登录.html")
  7. print("-----执行完毕-----")