pytest使用总结及采坑指南

pytest总结

  • pytest一个很是优秀的点就是能够支持扩展不少插件。
  • 安装python工具包时,时长遇到访问链接不到仓库的状况,使用-i命令指定仓库地址,一般我都是选择这个地址:
    https://mirrors.ustc.edu.cn/p...
  • pytest插件以下及功能介绍:
  1. 安装pytest:pip3 install pytest -i https://mirrors.ustc.edu.cn/p...
  2. 因为项目测试中但愿重复执行,因此使用pytest-repeat插件
    --count=2, 指定测试的次数,默认是函数级别的测试
    --repeat-scope, 指定重复执行的域.html

    • 补充说明:pytest有一个域的概念即scope,分为function、class、module、session
    • 其中function指一个test开头的函数,class指一个Test开头的类,而module指一个test开头的文件,session指此次执行的全部用例。
    • 因此说若是--repeat-scope指定了session则代表是按照session进行重复。
    • 注意:通过测试--xdist命令下不能按照预期的repeat-scope进行执行。
    • 例子:pytest test1.py -s --count=5 --repeat-scope=session
    • 经过在函数上添加@pytest.mark.repeat(count)装饰,指定函数执行次数。
    @pytest.mark.repeat(5)
    def test_02(start, open_baidu):
        print("测试用例test_02")
  3. pytest-xdist, 并发执行多个非依赖用例
  • 解释一下,--xdist选项目的是为了节省测试用例的执行时间,使用多核执行测试用例,可是有个前提条件就是这些用例不存在依赖关系,由于依赖关系是不能被保证的,及时有后边提到的ordering、dependancy插件
  • 安装pip3 install pytest-xdist -i https://mirrors.ustc.edu.cn/p...
  • 用法:pytest test.py -n auto指示根据当前cpu信息自动分配合理的核数运行用例,一样可使用pytest test.py -n 3指定具体的运行核数,并发进程数
  1. pytest相对简单的保证项目用例先后顺序的插件
    pytest-ordering
@pytest.mark.run(order=7)
   def test_delete_port(self, host_ip, module_dict, cfg):
       if "test_create_port" not in module_dict:
           # skip
           pytest.skip("do not have test_create_port result")

       self.delete_port(host_ip, module_dict)

   @pytest.mark.run(order=8)
   def test_delete_subnet(self, host_ip, module_dict, cfg, db_session):
       if "test_create_vpc_subnet" not in module_dict:
           # skip
           pytest.skip("do not have test_create_port result")

       self.delete_subnet(host_ip, module_dict, db_session)

两段代码会先执行7在执行8,若是不指定,则按照名字排序执行。python

  1. 自定义参数
  • 有时咱们须要根据不一样的场景传入一下参数,参考以下代码便可:
# pytest_addoption是pytest已经定义好的fixture(固件)能够直接使用,指定要解析的字段,action表示存储格式  
def pytest_addoption(parser):  
    parser.addoption("--cmdopt", action="store", default="dev.ini", help="my option: type1 or type2")  
    parser.addoption("--concurrency", action="store", default='False', help="my option: concurrency")

# 定义本身的固件,即其余测试用例经过哪一个名字获取这个定义的--cmdopt参数
@pytest.fixture(scope="module")
def cmdopt(request):
    return request.config.getoption("--cmdopt")
  1. 生成报告:
  • 使用简单的pytest-html插件
    只须要安装pip3 install pytest-html
    运行命令pytest test.py --html=./report.html,指定输出的文件为report.html报告
  • 使用allure工具,界面好看,功能全,安装复杂web

    • 须要安装allure插件及工具
    1. 安装allure brew install allure
    2. 安装插件pip3 install allure-pytest -i https://mirrors.ustc.edu.cn/p...
    3. 执行命令:pytest -v test_vpc_floatingip.py -n auto --count=5 -q --alluredir ./report
    4. allure generate --clean report/ -o allure-results/ #生成html格式文件
    5. allure open ./allure-results/ 打开文件
    6. 备注:allure使用了两种方式来渲染页面,分别是allure open 和 allure serve。前者用于在本地渲染和查看结果,后者用于在本地渲染后对外展现结果,因此要想查看有数据的html内容,须要使用allure open。运行命令 allure open allure-report便可自动打开浏览器(耐心等待一下)展现渲染好的结果,其中allure-report为allure generate生成的结果所在目录。
    7. 有些人会使用pip3 install pytest-allure-adaptor -i https://mirrors.ustc.edu.cn/p... 会报错:
      INTERNALERROR> AttributeError: module 'pytest' has no attribute ‘allure’,卸载安装l allure-pytest,但我这里会报错,因此未使用
    8. 重复执行屡次,allure会记录屡次的结果,可是总的用例数是不变的,可是某一个用例的重复次数会增长
  1. 重点:个人项目测试用例之间有依赖关系,又不想整合到一块儿会丢失不少test_case细节,又想要并发将此流程执行多遍,此时简单的使用repeate ordering xdist插件终究不能知足本身的需求,最后只能利用以下方式:
    main函数:
def run(i):
    file_name = '--html=./report/report_{}.html'.format(i[0])
    pytest.main(["-v", "-s", '--log-format="%(asctime)s %(levelname)s %(message)s"',
                 '--log-date-format="%Y-%m-%d %H:%M:%S"', file_name, '', '--alluredir', './report/result', i[1]])
    # pytest.main(['-v', '--alluredir', 'report/result'])


if __name__ == "__main__":
    import sys
    if len(sys.argv) > 1:
        p1 = '--cmdopt={}'.format(sys.argv[1])
        num = int(sys.argv[2])
    else:
        p1 = '--cmdopt=dev.ini'
        num = 1

    import multiprocessing
    pool = multiprocessing.Pool(4)

    _list = [(x, p1) for x in range(num)]
    pool.map(run, _list)
    pool.close()
    pool.join()
  1. 关于日志输出:
    能够经过指定 --log-format="%(asctime)s %(levelname)s %(message)s" 和 --log-date-format="%Y-%m-%d %H:%M:%S"分别指定日志的格式和日志的日期格式
  2. 经过pytest.ini指定pytest运行时参数
    pytest的执行能够分为几种,一种是最多见的pytest test.py形式
    第二种是直接执行pytest,第三种是执行python test.py但此时的test.py内容应该是第7节中的run中的pytest.main的运行形式
    值得注意的是,无论哪一种形式pytest都会先找pytest.ini进行加载,若是有覆盖的信息会被覆盖,不然就使用pytest.ini内容

开启日志功能使用log_cli=true浏览器

[pytest]
; addopts = -s -v --html=report/report.html --alluredir ./report/result --count=1 -n auto
testpaths = ./
#python_files = test_*.py
#python_classes = Test*
log_cli=true
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_cli_format = %(asctime)s %(levelname)s %(message)s
log_cli_level = INFO
#log_level=NOTSET
log_file = ./logs/pytest-logs.txt
python_functions = test*

参考:
https://www.jianshu.com/p/ddb...
https://www.cnblogs.com/yoyok... 使用skip跳过用例
https://blog.csdn.net/qq_42610167/article/details/101204066?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-tasksession

相关文章
相关标签/搜索