当前位置: 首页 > news >正文

Jenkins+RobotFramework 失败用例重执行方案

背景:

接口测试用例运行在Jenkins节点上,在某些情况下,比如网络波动等原因,会导致用例运行失败,此时会触发邮件和钉钉预警,通知给到责任人,按照现有策略,当本次构建失败时,会立马触发第二次构建活动,若第二次构建仍然失败,则会再次触发预警信息。

在这种策略下,会导致相关责任人收到一些额外的无意义预警信息(如第一次构建超时,而第二次构建成功),所以就多写了一个脚本,在Jenkins中作为Robotframework用例的运行入口,当有用例执行失败时,在所有cases执行完成后,会选择本次运行失败的cases再重试一次,然后合并两次的测试报告文件。

脚本内容很简单,可拓展性很强:

  1. #!/usr/bin/env python

  2.   # -*- coding:utf8 -*-

  3.   import getopt

  4.   import os

  5.   import sys

  6.   from pathlib import Path

  7.   from robot.api import ExecutionResult

  8.   def parse_args() -> tuple:

  9.    """解析命令行传入的参数"""

  10.    opts, args = getopt.getopt(sys.argv[1:], '-i:-e:-F:-E:', ["includeTag=", "excludeTag=", "format=", "env="])

  11.    try:

  12.    target = args[0]

  13.    except IndexError:

  14.    target = "./"

  15.    def _parse(option, default_value=None):

  16.    if isinstance(option, tuple):

  17.    temp = [opt_value for (opt_name, opt_value) in opts if opt_name in option]

  18.    else:

  19.    temp = [opt_value for (opt_name, opt_value) in opts if opt_name == option]

  20.    return temp[0] if len(temp) > 0 else default_value

  21.    include_tag = _parse(("-i", "--includeTag")) # 包含用例标签

  22.    exclude_tag = _parse(("-e", "--excludeTag")) # 排除用例标签

  23.    env = _parse(("-E", "--env"), 'm') # 用例运行环境

  24.    fm = _parse(("-F", "--format"), 'robot') # 用例文件后缀名

  25.    return include_tag, exclude_tag, env, fm, targetdef first_run(target, env, include_tag, exclude_tag, fm): """首次运行用例

  26.    项目的基本目录结构是固定的, 在命令行中写死了变量文件的相对路径.

  27.    """

  28.    if include_tag:

  29.    cmd = f"robot -F {fm} -i {include_tag} --output output_origin.xml --log NONE --report NONE -V variables.py:{env} -V ../Common/Variables/commonVars.py:{env} {target}"

  30.    elif exclude_tag is not None:

  31.    cmd = f"robot -F {fm} -e {exclude_tag} --output output_origin.xml --log NONE --report NONE -V variables.py:{env} -V ../Common/Variables/commonVars.py:{env} {target}"

  32.    else:

  33.    cmd = f"robot -F {fm} --output output_origin.xml --log NONE --report NONE -V variables.py:{env} -V ../Common/Variables/commonVars.py:{env} {target}"

  34.    print(f'First run cmd >>>> {cmd}')

  35.    os.system(cmd)def parse_robot_result(xml_path) -> bool:

  36.    """解析用例运行结果"""

  37.    suite = ExecutionResult(xml_path).suite

  38.    fail = {}

  39.    for test in suite.tests:

  40.    if test.status == "FAIL":

  41.    fail.update({test.name: test.status})

  42.    all_tests = suite.statistics.critical print("*" * 50)

  43.    print("当前运行目录为: ", os.getcwd())

  44.    print("总测试条数:{0}, 初次运行时,通过的用例数: {1}, 失败的用例数: {2}".format(all_tests.total, all_tests.passed, all_tests.failed))

  45.    if all_tests.failed > 0:

  46.    print("其中失败的用例信息为: %s" % str(fail))

  47.    print("*" * 50)

  48.    return all_tests.failed > 0def rerun_fail_case(target, env, include_tag, exclude_tag, fm): """ # TODO

  49.    如果要重新运行整个套件,需要使用`rerunfailedsuites`, 如果只想重新运行失败的测试用例而不是套件中已通过的测试,则使用`rerunfailed`(必须保证case是独立的)

  50.    -R, --rerunfailed <file>

  51.    Selects failed tests from an earlier output file to be re-executed.

  52.    -S, --rerunfailedsuites <file>

  53.    Selects failed test suites from an earlier output file to be re-executed.

  54.    """ if include_tag:

  55.    cmd = f"robot -F {fm} -i {include_tag} -V variables.py:{env} -V ../Common/Variables/commonVars.py:{env} --rerunfailed output_origin.xml --output output_rerun.xml {target}"

  56.    elif exclude_tag is not None:

  57.    cmd = f"robot -F {fm} -e {exclude_tag} -V variables.py:{env} -V ../Common/Variables/commonVars.py:{env} --rerunfailed output_origin.xml --output output_rerun.xml {target}"

  58.    else:

  59.    cmd = f"robot -F {fm} -V variables.py:{env} -V ../Common/Variables/commonVars.py:{env} --rerunfailed output_origin.xml --output output_rerun.xml {target}"

  60.    print(f'重复运行失败的用例: {cmd}')

  61.    os.system(cmd)

  62.    """再次运行失败的用例"""def merge_output():

  63.    """合并xml文件,并生成测试报告

  64.    注意集成到jenkins中时,需要指定 Output xml name为merge.xml

  65.    """

  66.    os.system("rebot --merge --output merge.xml *.xml")def main():

  67.    include_tag, exclude_tag, env, fm, target = parse_args() # 切换到output目录

  68.    if Path(target).is_dir():

  69.    os.chdir(Path(target))

  70.    else:

  71.    os.chdir(Path(target).parent)

  72.    for xml in Path.cwd().glob("*.xml"):

  73.    os.remove(xml)

  74.    first_run(target, env, include_tag, exclude_tag, fm)

  75.    failed = parse_robot_result("output_origin.xml")

  76.    if failed:

  77.    rerun_fail_case(target, env, include_tag, exclude_tag, fm)

  78.    # 不论是否存在失败的用例, 都会合并测试报告

  79.    merge_output()if __name__ == '__main__':

  80.    main()

除-E参数外,其他都是robot提供的的命令行参数,在项目中使用了变量文件,来使得用例支持切换运行环境,-E参数需要传入用例运行的环境,-i 或-e参数用来传入标签,过滤本次要运行的测试用例,可以传入多个标签,如:H5ANDP1、H5ORMini、NotPaid等。

在Jenkins项目配置中,构建操作配置的 Execute Windows Batch Cmd 如下:

  1.  cd %WORKSPACE%/ParkTest/interface

  2.   python runrobot.py --env=%Env% -F robot -i %Tag% ./

  3.   exit 0

Env和Tag都是在参数化构建时传入的,并且设有默认值。

在构建后操作中,使用Robot Framework插件收集构建结果,由于上面在脚本中修改了默认的输出文件名,这里要对应进行配置,如下:

当项目第一次构建失败时,第二次构建只会运行之前失败的测试用例,并合并两次生成的测试报告,在测试报告中展示如下:

这样就可以减少一些无效的报错邮件了。

关于以上方案,有一点还要进行特别说明,那就是项目中测试用例之前必须是相互独立的。保持Case独立性我认为是很有必要的,每一个 Test Case 应该只测试一种场景,根据case复杂程度,不同场景同样可大可小,但不能相互影响。当我们有随机的跑其中某个Case或乱序的跑这些Cases时,测试的结果都应该是准确的。Suite level和Directory level同样要注意独立性的问题。保持Case的独立性,这一点应当作为自动化用例编写规范,严格要求组内其他成员。

 感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

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

 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。


http://www.mrgr.cn/news/61190.html

相关文章:

  • git报错处理
  • 【微信小程序】let和const-综合实训
  • ESP32,uart安装驱动uart_driver_install函数剖析,以及intr_alloc_flags 参数的意义
  • python 3个线程轮流打印A、B、C
  • P10打卡——pytorch实现车牌识别
  • springboot vue uniapp 仿小红书 1:1 还原 (含源码演示)
  • 串口调试工具
  • 人工智能图谱
  • java基础练习:三天打鱼,两天晒网
  • AI(10)-瓶子logo
  • JS中的正则表达式
  • 高压线路覆冰厚度测量,输电线路微波覆冰监测装置守护电网安全
  • 后端检测_文件头检测漏洞
  • 线上问题排查@Transactional事务失效
  • 探索 Python 异步库的神秘力量:sniffio 库全解析
  • 鸿蒙开发 五十一 Command Line Tools 之ohpm
  • Java Lock LockSupport 总结
  • 玩转软件定义存储HBlock | 全方位体验天翼云存储资源盘活系统
  • MobileNetv2网络详解
  • 基于uniapp微信小程序的宠物救助宠物领养系统
  • 笔记本合上盖子不休眠设置
  • 4457M数字示波器
  • 【学术会议论文投稿】大数据治理:解锁数据价值,引领未来创新
  • python这10个接口自动化的装饰器
  • 阻塞队列/生产者消费者问题
  • 边缘图片渲染API-开箱即用的动态图片生成方案,轻松实现分享海报图片生成