Pytest框架

Pytest框架

简介

  • 常用第三方插件
    • pytest-selenium(集成selenium)
    • pytest-html(完美html测试报告)
    • pytest-rerunfailures(失败用例重复执行)
    • pytest-xdist(多CPU分发)
  • 测试用例的skip和xfail处理
  • 可以很好的和jenkins集成
  • report框架—allure也支持了pytest

0 命名规范

  1. 模块以 test_开头,建议 test_+业务名称
  2. 类的首字母大写,遵循驼峰命名规则
  3. 方法以 test_开头,遵循 test_+固定位数字+下划线+业务名称,如 test_01_cust_query,test_02_order_list

1 安装

  1. 安装

    pip install -U pytest
    
    pytest --version  验证安装
    
  2. pytest文档地址

    官方文档:[https://docs.pytest.org/en/latest/contents.html]

  3. pytest框架约束

    所有的单测文件名都需要满足test_*.py格式或*_test.py格式。


    在单测文件中,测试类以Test开头,且不能带有init方法(注意:定义class时,需要以T开头,不然pytest是不会运行该class的)


    在单测类中,可以包含一个或多个test_开头的函数。

    此时,在执行pytest命令时,会自动从当前目录及子目录中寻找符合上述约束的测试函数来执行。

  4. 运行

    # 运行主函数
     if __name__ == '__main__':
     	pytest.main("-s  test_abc.py")
            
    # 命令行模式
    pytest 文件路径/测试文件名
    例如:pytest ./test_abc.py
    
    序号演示命令命令说明
    1pytest ./运行当前目录及子目录下所有用例
    2pytest pytest_运行指定目录及子目录下所有用例
    3pytest pytest_/test_one.py指定模块运行
    4pytest -k test 或 pytest -k “test”按关键字匹配运行
    5pytest test_one.py::test_func指定函数运行
    6pytest test_one.py::Testlogin指定类运行
    7pytest test_one.py::Testlogin::test_01指定类方法运行
    8pytest --pyargs test_one.py通过包运行
    9pytest -m me运行所有用@pytest.mark修饰的用例
  5. Pytest Exit Code 含义清单

    • Exit code 0 所有用例执行完毕,全部通过
    • Exit code 1 所有用例执行完毕,存在Failed的测试用例
    • Exit code 2 用户中断了测试的执行
    • Exit code 3 测试执行过程发生了内部错误
    • Exit code 4 pytest 命令行使用错误
    • Exit code 5 未采集到可用测试用例文件
  6. 获取帮助信息

    # 显示可以用的内置函数
    pytest --fixtures
    
    # 查看帮助信息及配置文件选项
    pytest --help
    
  7. 控制测试用例执行

    pytest -x  # 第01次失败,就停止
    pytest --maxfail=2  # 出现2个失败就终止
    
    # 指定测试模块
    pytest test_mod.py
    
    # 指定测试目录
    pytest testing/
    
    # 通过关键字表达式过滤执行(跳过运行)
    pytest -k "MyClass and not method"
    
    # 通过node id 指定测试用例
    -----
    # 运行模块中指定用例
    pytest test_mod.py::test_func
    # 运行模块中指定方法
    pytest test_mod.py::TestClass::test_method
    # 通过标记表达式执行
    
    pytest -m show  # 这条命令会执行被装饰器@pytest.mark.show装饰的所有测试用例 
    -------
    # 通过包执行测试
    pytest --pyargs pkg.testing
    # 这条命令会导入包pkg.testing,并使用该包所在的目录,执行下面的用例
    
    # 仅运行上次失败的用例
    pytest --lf(--last-failed)
    
    # 运行所有用例,但是先运行上一次执行失败的用例
    pytest --ff(--failed-first)
    
    # 仅收集测试用例,不执行
    pytest --collect-only
    
  8. 多进程运行cases

    # 安装
    pip instsall -U pytest-xdist
    
    # 运行模式
    pytest test_se.py -n NUM   # 其中NUM填写并发的进程数
    
    
  9. 失败重新运行cases

    # 安装
    pip install -U pytest-rerunfailures
    
    # 运行模式
    pytest test_se.py --reruns NUM  # NUM填写重试的次数
    
  10. 重复执行

    # 安装
    pip install pytest-repeat
    
    # 重新执行3次
    pytest -v -s --count=3 test_pytest.py
    # 设置重复范围:session,module,class或者function
    pytest -v -s --count=3 --repeat-scope=session test_pytest.py
    
    # 或者在代码中标记
    import pytest
    
    def calc(a,b):
        return a + b
    
    class TestDemo():
      @pytest.mark.repeat(3)
        def test_answer1(self):        
            assert calc(1, 1) == 2
    
  11. 显示print内容

    pytest test_se.py -s
    
    # 叠加使用
    pytest test_se.py -s -n 4  # 同时运行4个进程,打印输出内容
    
    -v --verbose:打印详细日志信息
    -q --quiet:打印简略日志信息
    
  12. 多条断言

    # 安装
    pip install pytest-assume
    
    # 执行多条断言
    	# 写法1
    	pytest.assume(x == y)
    	pytest.assume(True)
    	pytest.assume(False)
    
    	# 写法2
    	with assume: assert calc(2, 1) == 4 
    	with assume: assert calc(2, 1) == 3 
    	with assume: assert calc(2, 2) == 3
    

2 Pytest的setup和teardown函数

  1. setup和teardown主要分为:模块级,类级,功能级,函数级。

    # 模块级
    在类上面,整个模块只执行一套
    
    # 函数级
    与函数对齐,在每个测试函数前后运行,不在类中
    
    # 类级别
    在类里面,测试类中调用一套
    
    # 方法级别(功能级别)
    与类级别效果一样
    
  2. 存在于测试类内部

  • 函数级别setup_method()/teardown_method()

    运行于测试方法的始末,即:运行一次测试函数会运行一次setup_method和teardown_method

  • 类级别setup_class()/eardown_class()

    运行于测试类的始末,即:在一个测试内只运行一次setup_class和teardown_class,不关心测试类内有多少个测试函数。

「setup改setup_method以及teardowm改teardowm_method」

3 Pytest配置文件

pytest的配置文件通常放在测试目录下,名称为pytest.ini,命令行运行时会使用该配置文件中的配置

#配置pytest命令行运行参数
   [pytest]
    addopts = -s ... # 空格分隔,可添加多个命令行参数 -所有参数均为插件包的参数配置测试搜索的路径
    testpaths = ./scripts  # 当前目录下的scripts文件夹 -可自定义
#配置测试搜索的文件名称
    python_files = test*.py 
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件 -可自定义
配置测试搜索的测试类名
    python_classes = Test_*  
 
   #当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类 -可自定义
配置测试搜索的测试函数名
  
    python_functions = test_*
 
#当前目录下的scripts文件夹下,以test开头,以.py结尾的所有文件中,以Test开头的类内,以test_开头的方法 -可自定义

4 Pytest常用插件

插件列表网址:[https://plugincompat.herokuapp.com]
包含很多插件包,大家可依据工作的需求选择使用。

  1. 前置条件

    • 文件路径

      Test_App
      	- - test_abc.py
      	- - pytest.ini
      
    • pytest.ini配置文件内容

        [pytest]
      # 命令行参数
       addopts = -s
      # 搜索文件名
       python_files = test_*.py
       # 搜索的类名
       python_classes = Test_*
       #搜索的函数名
          python_functions = test_*
      
  2. pip install pytest-ordering(重点)

    @pytest.mark.run(order=2)
        def test_02(self):
            print("--02--")
    
    @pytest.mark.run(order=1)
        def test_01(self):
            print("--01--")
    
  3. pip install pytest-xdist(重点)

  4. pip install allure-pytest(重点)

  5. pip install pytest-dependency(了解)

  6. pip install pytest-assume(了解)

  7. pip install pytest-random-order(了解)

  8. Pytest测试报告(了解)

  9. pip install pytest-reportlog(了解)

    pytest-HTML是一个插件,pytest用于生成测试结果的HTML报告

    # 安装
    pip install pytest-html
    
    # 运行
    pytest --html=用户路径/report.html
    
    # 运行方式
    1.修改Test_App/pytest.ini文件,添加报告参数,即:addopts = -s --html=./report.html 
        # -s:输出程序运行信息
        # --html=./report.html 在当前目录下生成report.html文件
        ️ 若要生成xml文件,可将--html=./report.html 改成 --html=./report.xml
    2.命令行进入Test_App目录
    3.执行命令: pytest
    执行结果:
        1.在当前目录会生成assets文件夹和report.html文件
    

5 pytest的高阶用法1

前置条件

  1. 文件路径
Test_App
	- - test_abc.py
	- - pytest.ini
  1. pyetst.ini配置文件内容:
 
[pytest]
  命令行参数
 addopts = -s
 搜索文件名
 python_files = test*.py
  搜索的类名
 python_classes = Test*
搜索的函数名
 python_functions = test_*

1. pytest之fixture

fixture修饰器来标记固定的工厂函数,在其他函数,模块,类或整个工程调用它时会被激活并优先执行,通常会被用于完成预置处理和重复操作。

方法:fixture(scope=“function”, params=None, autouse=False, ids=None, name=None)
常用参数:

scope: 被标记方法的作用域
	"function"(default):作用于每个测试方法,每个test都运行一次
	"class":作用于整个模块,每个class的所有test只运行一次
    "module":作用于整个模块,每个module的所有test只运行一次
    "session":作用于整个session(慎用),每个session(多个文件)只运行一次
params:(list类型)提供参数数据,供调用标记方法的函数使用
autouse:是否自动运行,默认False不运行,设置为True自动运行
   

2 fixture–通过参数引用(类里面)

class Test_ABC:
    @pytest.fixture()
    def before(self):
        print("------->before")
    def test_a(self,before): # ️ test_a方法传入了被fixture标识的函数,以变量的形式
        print("------->test_a")
        assert 1
if __name__ == '__main__':
    pytest.main("-s  test_abc.py")
执行结果:
    test_abc.py 
        ------->before # 发现before会优先于测试函数运行
        ------->test_a
         .

3 fixture–通过函数引用(类外面)

import pytest
@pytest.fixture() # fixture标记的函数可以应用于测试类外部
def before():
    print("------->before")
@pytest.mark.usefixtures("before")
class Test_ABC:
    def setup(self):
        print("------->setup")
    def test_a(self):
        print("------->test_a")
        assert 1
if __name__ == '__main__':
          pytest.main("-s  test_abc.py")
  执行结果:
      test_abc.py 
      ------->before # 发现before会优先于测试类运行
      ------->setup
      ------->test_a
      .

4 fixture–设置为默认运行

 import pytest
 @pytest.fixture(autouse=True) # 设置为默认运行
 def before():
     print("------->before")
 class Test_ABC:
     def setup(self):
         print("------->setup")
     def test_a(self):
         print("------->test_a")
         assert 1
 if __name__ == '__main__':
     pytest.main("-s  test_abc.py")
执行结果:
    test_abc.py 
    ------->before # 发现before自动优先于测试类运行
    ------->setup
    ------->test_a
        .

5 fixture–设置作用域为function

    import pytest
    @pytest.fixture(scope='function',autouse=True) # 作用域设置为function,自动运行
    def before():
        print("------->before")
    class Test_ABC:
        def setup(self):
            print("------->setup")
        def test_a(self):
            print("------->test_a")
            assert 1
        def test_b(self):
            print("------->test_b")
            assert 1
    if __name__ == '__main__':
        pytest.main("-s  test_abc.py")
执行结果:
    test_abc.py
        ------->before # 运行第一次
        ------->setup
        ------->test_a
        .------->before # 运行第二次
        ------->setup
        ------->test_b
        .

6 fixture–设置作用域为function

    import pytest
    @pytest.fixture(scope='function',autouse=True) # 作用域设置为function,自动运行
    def before():
        print("------->before")
    class Test_ABC:
        def setup(self):
            print("------->setup")
        def test_a(self):
            print("------->test_a")
            assert 1
        def test_b(self):
            print("------->test_b")
            assert 1
    if __name__ == '__main__':
        pytest.main("-s  test_abc.py")
执行结果:
    test_abc.py
        ------->before # 运行第一次
        ------->setup
        ------->test_a
        .------->before # 运行第二次
        ------->setup
        ------->test_b
        .

7 fixture—设置作用域为class

    import pytest
    @pytest.fixture(scope='class',autouse=True) # 作用域设置为class,自动运行
    def before():
        print("------->before")
    class Test_ABC:
        def setup(self):
            print("------->setup")
        def test_a(self):
            print("------->test_a")
            assert 1
        def test_b(self):
            print("------->test_b")
            assert 1
    if __name__ == '__main__':
        pytest.main("-s  test_abc.py")
执行结果:
    test_abc.py
    ------->before # 发现只运行一次
    ------->setup
        ------->test_a
        .
        ------->setup
        ------->test_b
        .

8 fixture—返回值

  • 示例1
import pytest
@pytest.fixture()
def need_data():
    return 2 # 返回数字2 
class Test_ABC:
    def test_a(self,need_data):
        print("------->test_a")
        assert need_data != 3 # 拿到返回值做一次断言

if __name__ == '__main__':
    pytest.main("-s  test_abc.py")
执行结果:
    test_abc.py 
    ------->test_a
    .
  • 示例2
import pytest
@pytest.fixture(params=[1, 2, 3])
def need_data(request): # 传入参数request 系统封装参数
    return request.param # 取列表中单个值,默认的取值方式
class Test_ABC:
 
    def test_a(self,need_data):
        print("------->test_a")
        assert need_data != 3 # 断言need_data不等于3
 
if __name__ == '__main__':
    pytest.main("-s  test_abc.py")
 
 执行结果:
      # 可以发现结果运行了三次
      test_abc.py 
      1
      ------->test_a
      .
      2
      ------->test_a
      .
      3
      ------->test_a
      F

9 共享fixture函数:conftest.py

在测试过程中,多个测试文件可能都要调用 fixture 函数,可以将其移动到 conftest.py 文件中。conftest.py 文件中的 fixture 函数不需要在测试函数中导入,可以被 pytest 自动识别,查找顺序从测试类开始,然后是测试模块,然后是 conftest.py 文件,最后是内置插件和第三方插件。

conftest.py

import pytest
@pytest.fixture()
def login():
    print("登录")
    return 8

测试用例

import pytest

class Test_Demo():
    def test_case1(self):
        print("\n开始执行测试用例1")
        assert 1 + 1 == 2

    def test_case2(self, login):
        print("\n开始执行测试用例2")
        print(login)
        assert 2 + login == 10

    def test_case3(self):
        print("\n开始执行测试用例3")
        assert 99 + 1 == 100


if __name__ == '__main__':
    pytest.main()

10 yield方法

使用yield关键字可以实现setup/teardown的功能,在yield关键字之前的代码在case之前执行,yield之后的代码在case运行结束后执行

import pytest

@pytest.fixture()
def login():
    print("登录")
    yield
    print("退出登录")

class Test_Demo():
    def test_case1(self):
        print("\n开始执行测试用例1")
        assert 1 + 1 == 2

    def test_case2(self, login):
        print("\n开始执行测试用例2")
        assert 2 + 8 == 10

    def test_case3(self):
        print("\n开始执行测试用例3")
        assert 99 + 1 == 100


if __name__ == '__main__':
    pytest.main()

结果

PASSED                      [ 33%]
开始执行测试用例1
登录
PASSED                      [ 66%]
开始执行测试用例2
退出登录
PASSED                      [100%]
开始执行测试用例3

addfinalizer方法暂时省略

6 Pytest高阶用法2

前置条件

  1. 文件路径
Test_App
	- - test_abc.py
	- - pytest.ini
  1. pyetst.ini配置文件内容:
 
[pytest]
  命令行参数
 addopts = -s
 搜索文件名
 python_files = test*.py
  搜索的类名
 python_classes = Test*
搜索的函数名
 python_functions = test_*

1. 跳过测试函数

根据特定的条件,不执行标识的测试函数
方法:
	skipif(condition, reason=None)
参数:
	condition:跳过的原因
    reason:标注原因,必传参数
使用方法:
	@pytest.mark.skipif(condition, reason="xxx")
  • 示例

    import pytest
    class Test_ABC:
        def setup_class(self):
            print("------->setup_class")
        def teardown_class(self):
            print("------->teardown_class")
        def test_a(self):
            print("------->test_a")
            assert 1
        @pytest.mark.skipif(condition=2>1,reason = "跳过该函数") # 跳过测试函数test_b
        def test_b(self):
            print("------->test_b")
                assert 0
    执行结果:
       test_abc.py 
       ------->setup_class
       ------->test_a #只执行了函数test_a
       .
       ------->teardown_class
           s # 跳过函数```
    

2 标记为预期失败的函数

方法:
	xfail(condition=None, reason=None, raises=None, run=True, strict=False)
常用参数:
	condition:预期失败的条件,必传参数
	reason:失败的原因,必传参数
使用方法:
	@pytest.mark.xfail(condition, reason="xxx")
import pytest
class Test_ABC:
    def setup_class(self):
        print("------->setup_class")
    def teardown_class(self):
        print("------->teardown_class")
    def test_a(self):
        print("------->test_a")
        assert 1
    @pytest.mark.xfail(2 > 1, reason="标注为预期失败") # 标记为预期失败函数test_b
       def test_b(self):
           print("------->test_b")
          assert 0
   执行结果:
       test_abc.py 
       ------->setup_class
       ------->test_a
       .
       ------->test_b
       ------->teardown_class
       x  # 失败标记

3 函数数据参数化

方法:
	parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
常用参数:
    argnames: 参数名
    argvalues: 参数对应值,类型必须为list
        		当参数为一个时格式[value]
            	当参数个数大于一个时,格式为[(param_value1,param_value2.....),(param_value1,param_value2.....)]
使用方法:
	@pytest.mark.parametrize(argnames, argvalues)	参数值为N个,测试方法就会运行N次
  • 单个参数示例

    import pytest
    class Test_ABC:
        def setup_class(self):
            print("------->setup_class")
        def teardown_class(self):
            print("------->teardown_class")
    
    @pytest.mark.parametrize("a",[3,6]) # a参数被赋予两个值,函数会运行两遍
    def test_a(self,a): # 参数必须和parametrize里面的参数一致
        print("test data:a=%d"%a)
        assert a%3 == 0
        执行结果:
        test_abc.py 
        ------->setup_class
        test data:a=3 # 运行第一次取值a=3
        .
        test data:a=6 # 运行第二次取值a=6
        . 
        ------->teardown_class        
    
  • 多个参数示例

    import pytest
    class Test_ABC:
        def setup_class(self):
            print("------->setup_class")
        def teardown_class(self):
            print("------->teardown_class")
    @pytest.mark.parametrize("a,b",[(1,2),(0,3)]) # 参数a,b均被赋予两个值,函数会运行两遍
    def test_a(self,a,b): # 参数必须和parametrize里面的参数一致
        print("test data:a=%d,b=%d"%(a,b))
        assert a+b == 3
        执行结果:
        test_abc.py 
        ------->setup_class
        test data:a=1,b=2 # 运行第一次取值 a=1,b=2
        .
        test data:a=0,b=3 # 运行第二次取值 a=0,b=3
        .
        ------->teardown_class
    
  • 函数返回值类型示例:

    import pytest
    def return_test_data():
        return [(1,2),(0,3)]
    class Test_ABC:
        def setup_class(self):
            print("------->setup_class")
        def teardown_class(self):
                print("------->teardown_class")
                
    @pytest.mark.parametrize("a,b",return_test_data()) # 使用函数返回值的形式传入参数值
    def test_a(self,a,b):
        print("test data:a=%d,b=%d"%(a,b))
        assert a+b == 3
        
        执行结果:
        test_abc.py 
        ------->setup_class
        test data:a=1,b=2 # 运行第一次取值 a=1,b=2
        .
        test data:a=0,b=3 # 运行第二次取值 a=0,b=3
        .
            ------->teardown_class            
    

4 修改Python traceback输出(没懂)

pytest --showlocals     # show local variables in tracebacks
pytest -l               # show local variables (shortcut)
pytest --tb=auto        # (default) 'long' tracebacks for the first and last
                        # entry, but 'short' style for the other entries
pytest --tb=long        # exhaustive, informative traceback formatting
pytest --tb=short       # shorter traceback format
pytest --tb=line        # only one line per failure
pytest --tb=native      # Python standard library formatting
pytest --tb=no          # no traceback at all

–full-trace 参数会打印更多的错误输出信息,比参数 --tb=long 还多,即使是 Ctrl+C 触发的错误,也会打印出来

5 执行失败的时候跳转到PDB(没懂)

执行用例的时候,跟参数 --pdb,这样失败的时候,每次遇到失败,会自动跳转到 PDB

pytest --pdb              # 每次遇到失败都跳转到 PDB
pytest -x --pdb           # 第一次遇到失败就跳转到 PDB,结束测试执行
pytest --pdb --maxfail=3  # 只有前三次失败跳转到 PDB 

6 设置断点(没懂)

在用例脚本中加入如下python代码,pytest会自动关闭执行输出的抓取,这里,其他test脚本不会受到影响,带断点的test上一个test正常输出

 import pdb; pdb.set_trace()

7 获取用例的执行性能数据

# 获取最慢的10个用例的执行耗时
pytest --durations=10

8 生成JunitXML格式结果文件

pytest --junitxml=path

9 禁用插件

# 例如,关闭 doctest 插件
pytest -p no:doctest

10 从Python代码中调用pytest

pytest.main()                      # 基本用法
pytest.main(['-x', 'mytestdir'])   # 传入配置参数
 
 
// 指定自定义的或额外的插件
# content of myinvoke.py
import pytest
class MyPlugin(object):
    def pytest_sessionfinish(self):
        print("*** test run reporting finishing")
 
pytest.main(["-qq"], plugins=[MyPlugin()])

11 测试脚本迁移后快速部署包含pytest的virtualenv

cd <repository>
pip install -e .

12 pytest + allure生成测试报告

  1. 安装java

  2. 安装allure

  3. 安装allure-pytest插件

    pip install allure-pytest
    
  • 生成Allure报告

    pytest [测试文件] -s -q --alluredir=./result
    
  • 查看测试报告

    1. 直接打开默认浏览器展示报告

      allure serve .\result\
      
    2. 从结果生成测试报告

      • 生成报告
      allure generate ./result/ -o ./report/ --clean
      # 覆盖路径加-clean
      
      • 打开报告
      allure open -h 127.0.0.1 -p 8883 ./report/
      
  • allure特性—feature, story, step

    @allure.feature("功能名称"):相当于testsuite
    @allure.story("子功能名称"):相当于testcase
    @allure.step("步骤"):测试过程中的每个步骤,放在具体逻辑方法中
    	--allure.step("步骤") 只能以装饰器的形式放在类或者方法上面
        --with allure.step:可以放在测试用例方法里面
    

    示例

    import pytest
    import allure
    
    @allure.feature("登录")
    class TestLogin():
        @allure.story("登录成功")
        def test_login_success(self):
            print("登录成功")
            pass
    
        @allure.story("密码错误")
        def test_login_failure(self):
            with allure.step("输入用户名"):
                print("输入用户名")
            with allure.step("输入密码"):
                print("输入密码")
            print("点击登录")
            with allure.step("登录失败"):
                assert '1' == 1
                print("登录失败")
            pass
    
        @allure.story("用户名密码错误")
        def test_login_failure_a(self):
            print("用户名或者密码错误,登录失败")
            pass
    
    
    @allure.feature("注册")
    class TestRegister():
        @allure.story("注册成功")
        def test_register_success(self):
            print("测试用例:注册成功")
            pass
    
        @allure.story("注册失败")
        def test_register_failure(self):
            with allure.step("输入用户名"):
                print("输入用户名")
            with allure.step("输入密码"):
                print("输入密码")
            with allure.step("再次输入密码"):
                print("再次输入密码")
            print("点击注册")
            with allure.step("注册失败"):
                assert 1 + 1 == 2
                print("注册失败")
            pass
    
  • allure特性—link, issue, testcase

    可以在测试报告中添加链接、bug地址、测试用例地址。

    关联bug时需要再用例执行时添加参数

    --allure-link-pattern=issue:"http://www.xxx.com/issure/{}"
    

    示例:

    import allure
    
    @allure.link("http://www.baidu.com", name="baidu link")
    def test_with_link():
        pass
    
    @allure.issue("140","this is a issue")
    def test_with_issue_link():
        pass
    
    TEST_CASE_LINK = 'https://github.com'
    @allure.testcase(TEST_CASE_LINK, 'Test case title')
    def test_with_testcase_link():
        pass
    
    
    • 执行
    pytest test_allure_link_issue.py --allure-link-pattern=issue:"http://www.bugfree.com/issue/{}" --alluredir=./result/3
    allure serve ./result/3
    
  • allure特性—severity

    1. 可以使用pytest.mark来标记用例(待学习)

      @pytest.mark.webtest # 添加标签 
      @pytest.mark.sec 
      pytest -m "webtest and not sec"
      
    2. 通过allure.feature, allure.story来实现

      pytest test_feature_story_step.py --allure-features "登录" //只运行登录模块
      pytest test_feature_story_step.py --allure-stories "登录成功" //只运行登录成功子模块
      
    3. 通过allure.severity按重要性级别来标记

      • Blocker级别:阻塞
      • Critical级别:严重
      • Normal级别:正常
      • Minor级别:不太重要
      • Trivial级别:不重要

      示例test_allure_severity.py

      import allure
      import pytest
      
      def test_with_no_severity_label():
          pass
      
      @allure.severity(allure.severity_level.TRIVIAL)
      def test_with_trivial_severity():
          pass
      
      @allure.severity(allure.severity_level.NORMAL)
      def test_with_normal_severity():
          pass
      
      @allure.severity(allure.severity_level.NORMAL)
      class TestclassWithNormalSeverity(object):
          def test_inside_the_normalseverity_test_class(self):
              pass
      
          @allure.severity(allure.severity_level.CRITICAL)
          def test_inside_the_normal_severity_test_class_with_overriding_critical_severity(self):
              pass
      

      运行

      pytest .\testcases\test_allure_severity.py --alluredir=./result5/
       --allure-severities normal,critical
       # -------------------------------------
       allure serve .\result5 
      
  • allure.attach()

    可以在报告中附加文本、图片以及html网页,用来补充测试步骤或测试结果,比如错误截图或者关键步骤的截图

    @allure.attach("具体文本信息")
    	--附加信息:数据,文本,图片,视频,网页
    

    test_allure_attach.py

    import allure
    import pytest
    
    def test_attach_text():
        allure.attach("纯文本", attachment_type=allure.attachment_type.TEXT)
    
    def test_attach_html():
        allure.attach("<body>这是一段htmlbody块</body>", "html页面", attachment_type=allure.attachment_type.HTML)
    
    def test_attach_photo():
        allure.attach.file("test.jpg", name="图片", attachment_tye=allure.attachment_type.JPG)
    

    运行

    pytest test_allure_attach.py --alluredir=./result/5
    allure serve ./result/5
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值