zoukankan      html  css  js  c++  java
  • pytest+allure基础知识

    介绍

    • pytest是基于unittest开发的另一款更高级更好用的单元测试框架
    • 支持参数化
    • 执行测试过程中可以将某些测试跳过(skip),或者对某些预期失败的case标记成失败
    • 支持运行由 nose, unittest 编写的测试 case
    • 方便的和持续集成工具 jenkins 集成
    • 具有很多第三方插件,并且可以自定义扩展
    • 可支持执行部分用例
    • 支持失败重跑功能

    安装

    • pytest是第三方库,需要安装后使用
    • 在命令行输入以下任意命令即可安装,使用第三方镜像源可加快下载速度
    # 豆瓣源
    pip install pytest -U -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
    # 清华源
    pip install pytest -U -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn
    

    命名规范

    • 用例文件应当以 test_*.py 进行命名,或者以 *_test.py命名
    • 类必须以 Test 开头,且类当中不能有__init__方法
    • 方法或函数必须以 test_ 开头
    • 可以在项目根目录建pytest.ini文件,在里面自定义用例匹配规则
    # 用例匹配规则
    [pytest]
    python_files = test_*.py *_test.py
    python_classes = Test*
    python_functions = test_*
    

    断言

    • 断言必须使用assert,语法:assert 表达式
    • 测试的结果, .表示成功 F表示失败,如果测试失败,会显示具体的语句
    assert 1==2 #判断等式两边是否相等
    assert 200 #判断某个语句是否为真
    assert 10 in [10,20] #判断某个值是否属于某个对象
    assert not True #判断某个语句是否不为真
    assert 1!=2 #判断某个值是否不等于另一个值
    

    初始化和清除

    • 模块级别的初始化和清除
    def setup_module():
        print('
     *** 模块初始化开始 ***')
        pass # 这里写初始化代码
        print('
     *** 模块初始化结束 ***')
    def teardown_module():
        print('
     *** 模块清除开始 ***')
        pass # 这里写清除代码
        print('
     *** 模块清除结束 ***')
    
    • 类级别的初始化和清除
    class Test_A:    
        @classmethod
        def setup_class(cls):
            print(f'
     === {cls.__name__}类初始化 ===')
        @classmethod
        def teardown_class(cls):
            print(f'
     === {cls.__name__}类清除 ===')
    
    • 方法级别的初始化和清除(类中所有方法都会调用)
        def setup_method(self):
            print('
     --- 类方法初始化  ---')
        def teardown_method(self):
            print('
     --- 类方法清除 ---')
    
    • 方法级别的初始化和清除(类中指定方法调用)
        # 在类外面自定义一个方法,名字随意,但是要带上pytest的装饰器
        @pytest.fixture(scope='function')
        def custom_setup():
            print(f'
     --- 自定义方法初始化  ---')
            pass # 在这写要初始化的代码
            yield custom_setup # 初始化函数名(不要带括号)
            custom_teardown() # 清除函数
            
        # 同时要自定义一个清除函数,名字随意
        def custom_teardown():
            print(f'
     --- 自定义方法清除 ---')
            pass # 在这写清除的代码
            
        # 如果有个方法需要调用自定义的初始化和清除函数,只需要把初始化函数传入即可
        def test_abc(custom_setup):
            pass 
    
    • 执行顺序(以类中的一个方法为例):模块初始化→类初始化→类方法初始化→自定义方法初始化→自定义方法清除→类方法清除→类清除→模块清除
    • 类方法的初始化和清除会作用于类里的每一个函数
    • 自定义方法的初始化和清除只会对传入该方法名的函数生效

    参数化

    • 使用@pytest.mark.parametrize(参数名, 参数值列表)
    # 传入多个参数时,参数值列表中,每一组数据的类型都是元组
    @pytest.mark.parametrize("val_a,val_b", [(1, 2), (3, 4), (5, 6)])
    def test_parametrize_1(val_a,val_b):
        print(f"变量val_a的值:{val_a},变量val_b的值:{val_b}")
        
    # 可以使用多个参数化装饰器,测试数据为不同数据的笛卡尔积,实际会生成m*n条用例(下面的代码生成3*4=12条用例)
    @pytest.mark.parametrize('a', [1,2,3])
    @pytest.mark.parametrize('b', [4,5,6,7])
    def test_parametrize_2(a, b):
        print(f'笛卡尔积 测试数据为:{a},{b}')
    

    mark标记用例

    • pytest支持案例标记的功能,可以给每个用例加上自定义标记,在执行测试案例时通过标记筛选要执行的案例
    • 使用标记方法
      1. pytst.ini 中添加标记名称
      2. 在需要标记的函数上使用装饰器 @pytest.mark.标记名
    • pytst.ini :pytest的配置文件
    # 在pytst.ini文件的标记名列表中添加自定义的标记
    [pytest]
    markers =
        smoke
        test
        hello
    
    # 在需要标记的函数上增加装饰器(以smoke,hello为例)
    @pytest.mark.smoke
    def test_001(self):
        print('我是一个冒烟测试用例')
    
    @pytest.mark.hello
    def test_002(self):
        print('我是一个属于hello标记的测试用例')
    

    执行用例

    • '-k 标记名' ==>可选择执行该标记所包含的用例
    • '-s' ==>在控制台输出执行过程中的print内容
    • '-q' ==>打印用例执行的简略过程
    • '-v' ==>打印用例执行的详细过程
    • '-x' ==>用例运行失败则立即停止执行
    • '--maxfail=num' ==>用例运行时允许的最大失败次数,超过num次则立即停止
    • '-l' ==>用例运行失败时,打印相关的局部变量
    • 不输入参数默认执行该当前目录及子目录中的所有测试用例
    • pytest执行案例时使用pytest.main()函数,参数传入一个列表
    # 执行所有标记为smoke的用例,显示详细过程,并打印print输出
    pytest.main(['-k','smoke','-sv'])
    
    • 如果执行过程中出现了Module already imported so cannot be rewritten的警告,那么可以用子进程的方式来执行用例,就不会弹出这种警告了
    # 导入子进程模块,避免运行时弹出警告
    import subprocess
    # 列表中第一个元素为pytest,后面的元素可以输入各种参数
    subprocess.call(['pytest', '-k smoke', '-s'])
    # 运行指定目录下用例
    subprocess.call(['pytest', './test'])
    # 运行指定模块
    subprocess.call(['pytest', './test/test_demo.py'])
    # 运行模块中的指定用例
    subprocess.call(['pytest', './test/test_demo.py::test_001'])
    # 运行类中的指定用例
    subprocess.call(['pytest', './test/test_demo.py::TestDemo::test_001'])
    # 运行test_demo.py模块下名称包含hello的用例
    subprocess.call(['pytest', '-k hello','./test/test_demo.py'])
    # 运行TestDemo类中名称包含aa的用例
    subprocess.call(['pytest', '-k aa','./test/test_demo.py::TestDemo'])
    

    allure安装

    • 下载allure:https://github.com/allure-framework/allure2/releases
    • 解压allure.zip到一个文件目录中
    • 将allure报告安装目录in所在的路径添加环境变量path中
    • 命令行输入pip install allure-pytest -i http://pypi.douban.com/simple/
    • 在命令行中输入allure,如果能看到命令就是已经配置完成

    allure装饰器

    • 根据实际需要对用例使用allure装饰器,可以提升allure报告的可读性
    • 几种常用的装饰器:
    @allure.epic('层级1')
    @allure.feature('层级2') 
    @allure.story('层级3') 
    @allure.title('用例标题') 
    @allure.description('用例描述')
    

    allure报告

    • allure生成报告分为两步:
      1. 第一步先执行用例并生成测试数据(一大堆json文件)
      2. 根据某次执行用例后生成的测试数据,通过allure generate命令来生成测试报告(包含了index.html,可在浏览器打开查看)
    • 生成allure测试数据
    # 这里我是在每次执行的时候,将当天的测试数据和测试报告按日期+时间的双层目录来存放
    date = time.strftime('%Y%m%d', time.localtime())  # 当前日期
    time = time.strftime('%H%M%S', time.localtime())  # 当前时间
    # allure命令要在命令行使用,在python中可通过os.system来调用
    os.system(f'pytest --alluredir ./result/{date}/{time}/')  # 生成测试结果
    
    • 生成allure测试报告
    # 根据测试结果生成测试报告
    # 加上--clean参数可以先清除数据,但由于我是按时间存放的,所以每次生成的目录都在不同位置,这里就不clean了,自己调试代码测试的时候可以用上clean
    os.system(f'allure generate ./result/{date}/{time}/ -o ./report/{date}/{time}/')
    
    • 手动打开测试报告:在生成的测试报告文件夹里有index.html文件,直接在浏览器打开即可查看
    • 也可以起一个服务,会自动打开allure测试报告
    • 注意:使用这个命令后会在本地起一个服务,如果打开的网页是空白的(可能存在网络限制等各种原因),那么可以将ip换成 127.0.0.1:(启动服务后命令行显示的端口号) 试下能不能正常访问
    # 自动打开测试报告,将启动后的服务ip换成 127.0.0.1
    os.system(f'allure serve ./result/{date}/{time}/')
    
  • 相关阅读:
    python爬取二手房库存,存数据库,生成折线图(下)
    python爬取二手房库存,存数数据库,生成折线图(上)
    python爬取二手房库存,存数据库,生成折线图(中)
    vue input 复制后无法修改
    js对象应用问题
    redis5.0集群搭建
    查看java 字节码的方式
    python 运行js
    对java基本对象的构想
    学习第39天
  • 原文地址:https://www.cnblogs.com/xiaocaiqa/p/15311480.html
Copyright © 2011-2022 走看看