自动化软件测试 -- Pytest

本文详细介绍了pytest,一个高效、灵活的Python测试框架,涵盖了单元测试、配置文件、标记跳过、参数化、夹具和装饰器夹具的使用,以及插件和配置示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Pytest

pytest 是 python 的一种单元测试框架,同自带的unittest测试框架类似。相比起unittest框架使用起来更简洁,效率更高。

Pytest特点:

1、文档丰富,文档中有很多实例可以参考

2、支持简单的单元测试和复杂的功能测试

3、支持参数化

4、执行测试过程中可以将某些测试跳过,或者对某些预期失败的case标记成失败

5、支持重复执行失败的case

6、支持运行由Nose.Unittest 编写的测试Case

7、具有很多第三方插件,可以自定义扩展

8、方便和持续集成工具集成

二、Pytest基本操作

​
#单元测试:
#1、测试函数、类、方法能不能正常运行完成
import pytest
def test_1():
    print("test_1+++++")
    return 1*0

def test_2():
    print("test_2++++++")
    return 1/0

if __name__ == '__main__':
    pytest.main(["-s","test_py2.py"])

​

对于直接执行pytest:

模块:

直接从测试目录或者当前目录中递归寻找名称规则为test_*.py 或 *_test.py.

类:

以上模块中的Test开头的类,且没有初始化 __init__ 方法

三、Pytest 配置文件

[pytest]

addopts = -s

testpaths = ./

python_files = test_*.py *test.py

python_classes = Test*

python_functions = test_*

四、Pytest 标记跳过测试

两种标记装饰器:
@pytest.mark.skip(reason=None)

作为装饰器使用,添加到需要跳过的函数或者方法上;

@pytest.mark.skipif(condition,reason=None)

作为装饰器使用,添加到需要跳过的函数或者方法上,但只有条件成立时才会跳过

import pytest
def test_a():
    print("test_a+++++++")
    return 1+1

@pytest.mark.skip(reason="我想跳过")

def test_b():
    print("test_b++++++")
    return 1/0

if __name__ == '__main__':
    pytest.main(["-s","test_py4.py"])

@pytest.mark.xfail(condition = None,reason = None,raises = None)

import pytest
def test_a():
    print("test_a+++++++")
    return 1+1

@pytest.mark.skip(reason="我想跳过")

def test_b():
    print("test_b++++++")
    return 1/0

@pytest.mark.xfile(reason = ZeroDivisionError)

if __name__ == '__main__':
    pytest.main(["-s","test_py4.py"])

五、Pytest 参数化

对于相似的过程,但数据不一样的时候,可以使用参数化。

@pytest.mark.parametrize(self.argnames,argvalues,ids = None)

argnames 参数名称,列表或元组

argvalues 参数值,列表套元组

ids 测试id,可省略

import pytest

@pytest.mark.parametrize(["a","b"],[(1,2),(10,20),(30,40),(50,60),(70,80),(90,100),(110,120),(130,140)])
def test_a(a,b):
    print("test_a+++++++")
    assert a + b > 100


if __name__ == '__main__':
    pytest.main(["-s", "test_py5.py"])

#3 failed, 5 passed 

六、Pytest 夹具

作用:在测试之前和之后执行,用于固定测试环境,及清理回收测试资源。

模块级

def setup_module(module):
    pass
def teardown_module(module):
    pass
import pytest
def setup_module(args):
    print("setup_module",args)
def teardown_module(args):
    print("teardown_module",args)

def test_func_a():
    print('----',"test_func_a")

def test_func_b():
    print('----',"test_func_b")

class TestOne():
    TAG = "a"
    def test_1(self):
        print('----', self.TAG + 'test_1')

    def test_2(self):
        print('----', self.TAG + 'test_2')

if __name__ == '__main__':
    pytest.main(["-s","test_py6.py"])

函数级

import pytest
def setup_module(args):
    print("setup_module",args)
def teardown_module(args):
    print("teardown_module",args)

def setup_function(args):
    print("setup_function",args)
def teardown_function(args):
    print("teardown_function",args)

def test_func_a():
    print('----',"test_func_a")

def test_func_b():
    print('----',"test_func_b")

class TestOne():
    TAG = "a"
    def test_1(self):
        print('----', self.TAG + 'test_1')

    def test_2(self):
        print('----', self.TAG + 'test_2')

if __name__ == '__main__':
    pytest.main(["-s","test_py6.py"])

 类级别

import pytest
def setup_module(args):
    print("setup_module",args)
def teardown_module(args):
    print("teardown_module",args)

def setup_function(args):
    print("setup_function",args)
def teardown_function(args):
    print("teardown_function",args)

def test_func_a():
    print('----',"test_func_a")

def test_func_b():
    print('----',"test_func_b")

class TestOne():
    TAG = "a"
    def setup_class(self):
        print(" "+self.TAG + "setup_class")
    def teardown_class(self):
        print(" "+self.TAG + "teardown_class")

    def test_1(self):
        print('----', self.TAG + 'test_1')

    def test_2(self):
        print('----', self.TAG + 'test_2')

if __name__ == '__main__':
    pytest.main(["-s","test_py6.py"])

 方法级别

import pytest
def setup_module(args):
    print("setup_module",args)
def teardown_module(args):
    print("teardown_module",args)

def setup_function(args):
    print("setup_function",args)
def teardown_function(args):
    print("teardown_function",args)

def test_func_a():
    print('----',"test_func_a")

def test_func_b():
    print('----',"test_func_b")

class TestOne():
    TAG = "a"
    def setup_class(self):
        print(" "+self.TAG + "setup_class")
    def teardown_class(self):
        print(" "+self.TAG + "teardown_class")

    def setup_method(self,args):
        print(" "+self.TAG + "setup_method",args)
    def teardown_method(self,args):
        print(" "+self.TAG + "teardown_method",args)


    def test_1(self):
        print('----', self.TAG + 'test_1')

    def test_2(self):
        print('----', self.TAG + 'test_2')

if __name__ == '__main__':
    pytest.main(["-s","test_py6.py"])

七、Pytest  装饰器夹具

除了setup 和 teardown, pytest 提供 fixture 进行更为强大的夹具使用。

import pytest
@pytest.fixture()
def before():
    print("before")
@pytest.mark.usefixtures("before")
def test_1():
    print('test_1()')

if __name__ == '__main__':
    pytest.main(["-s","test_py7.py"])

有返回值 

import pytest
@pytest.fixture()
def before():
    print("before")

@pytest.fixture()
def login():
    print("login")
    return "user"
@pytest.mark.usefixtures("before")
def test_1():
    print('test_1()')
def test_2(login):
    print('test2()',login)

if __name__ == '__main__':
    pytest.main(["-s","test_py7.py"])

有参数

import pytest
@pytest.fixture()
def before():
    print("before")

@pytest.fixture()
def login():
    print("login")
    return "user"
@pytest.mark.usefixtures("before")
def test_1():
    print('test_1()')
def test_2(login):
    print('test2()',login)

@pytest.fixture(params = [1,2,3])
def init_data(request):
    print("request参数是",request.param)
    return request.param

def test_Data(init_data):
    assert init_data >2

if __name__ == '__main__':
    pytest.main(["-s","test_py7.py"])

八、Pytest 插件 

html 报告

[pytest]

addopts = -s --html=./report.html

testpaths = ./

python_files = test_*.py *test.py

python_classes = Test*

python_functions = test_*

指定执行顺序

import pytest
def test_1():
    print("1")
def test_2():
    print("2")
def test_3():
    print("3")
@pytest.mark.run(order = 3)
def test_4():
    print("4")
@pytest.mark.run(order = 2)
def test_5():
    print("5")
@pytest.mark.run(order = 1)
def test_6():
    print("6")

if __name__ == '__main__':
    pytest.main(["-s","test_py9.py"])

注意:标了运行顺序的数越小(正整数和零),运行的优先级越高;标了运行顺序(正整数和零),运行的优先级大于没有标记的;运行顺序:零和正整数 > 没有标记 > 负整数;在各个阶段数越小的运行的优先级越高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值