单元测试界的高富帅,Pytest框架,手把手教学,高阶用法实战

在这里插入描述

一、xunit 风格的前后置方法

1、函数用例的前后置方法

在模块中以函数形式定义用例,可以通过 setup_function 和 teardown_function 来定义函数用例的前后置方法,使用案例如下:

def setup_function(function):
    print("函数用例前置方法执行")

  
def teardown_function(function):
    print("函数用例后置方法执行")


def test_01():
    print('----用例方法01------')

运行结果:

C:\testcases>pytest -s
========================= test session starts =========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0 
cachedir: .pytest_cache
rootdir: C:\testcases
plugins:  testreport-1.1.2
collected 1 item                                                      
test_demo.py
函数用例前置方法执行
----用例方法01------ .
函数用例后置方法执行
========================= 1 passed in 0.27s =========================

2、测试类中用例的前后置方法

类级别的前后置方法

pytest 中测试类级别的前后置方法 setup_class和teardown_class,分别在测试类中的用例执行之前执行,和测试类中所有用例执行完毕之后执行,具体使用如下:

class TestDome:
    def test_01(self):
        print('----测试用例:test_01------')

    def test_02(self):
        print('----测试用例:test_02------')

    @classmethod
    def setup_class(cls):
        print("测试类前置方法---setup_class---")

    @classmethod
    def teardown_class(cls):
        print("测试类后置方法---teardown_class---")

用例级别的前后置方法

pytest 中测试类中用例级别的的前后置方法 setup_method和teardown_method,分别在测试类中的用例执行之前执行,和测试类中所有用例执行完毕之后执行,具体使用如下:

class TestDome:

    def test_01(self):
        print('----测试用例:test_01------')

    def test_02(self):
        print('----测试用例:test_02------')

    @classmethod
    def setup_class(cls):
        print("测试类前置方法---setup_class---")

    @classmethod
    def teardown_class(cls):
        print("测试类后置方法---teardown_class---")

    def setup_method(function):
        print("测试用例前置方法---setup_method---")

    def teardown_method(function):
        print("测试用例后置方法---teardown_method---")

运行结果

C:\testcases>pytest -s
==================== test session starts ====================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins:  testreport-1.1.2
collected 2 items                                                                                                                                 
test_demo.py 
测试类前置方法---setup_class---
测试用例前置方法---setup_method---
----测试用例:test_01------.
测试用例后置方法---teardown_method---
测试用例前置方法---setup_method---
----测试用例:test_02------.
测试用例后置方法---teardown_method---
测试类后置方法---teardown_class---

==================== 2 passed in 0.30s =======================

3、模块级别的前后置方法

pytest 中还有 setup_module和teardown_module 这两个用来设置模块级别前后置方法的函数,定义在模块中,会在整个模块中所有的用例执行前和用例全部执行完毕之后会执行,具体使用如下:

class TestDome:

    def test_01(self):
        print('----测试用例:test_01------')


class TestDome2:

    def test_02(self):
        print('----测试用例:test_02------')
   
  
def setup_module(module):
    print("测试模块的前置方法---setup_module---")


def teardown_module(module):
    print("测试模块的前置方法---teardown_module---")

运行结果

C:\testcases>pytest -s
====================== test session starts ====================== 
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins:testreport-1.1.2
collected 2 items                                                                   
test_demo.py 测试模块的前置方法---setup_module---
----测试用例:test_01------
.----测试用例:test_02------
.测试模块的前置方法---teardown_module---
====================== 2 passed in 0.27s ====================== 

二、fixture 机制

前面我们介绍了 pytest 中 xunit 风格的前后置方法,接下来我们来看一下 pytest 中功能更加强大的 fixture 机制(测试夹具)的使用。

1、测试夹具的级别和定义

测试夹具需要使用 pytest.fixture 这个装饰器来定义,pytest 中的测试夹具有如下几个级别:用例级别、测试类级别、模块级别,包级别,会话级别。接下来我们一起来看看夹具定义语法。

夹具定义可以通过参数 scope 指定夹具的级别,如果不指定夹具级别,scope 默认值为 function(用例级别)

用例级别:scope = function

测试类级:scope = class

模块级别:scope = module

包级别:scope = package

会话级别:scope = session

@pytest.fixture(scope='指定夹具的级别')
def work():
    # 前置执行脚本
    yield 
    # 后置执行脚本

测试夹具本质上是一个生成器函数,生产器函数在使用 next 进行迭代时,执行到 yeild 会返回数据,暂停执行,等待下一次进行迭代时才会继续执行,pytest 夹具就是利用的生成器的机制,通过 yeild 在测试夹具将前后置代码分开执行。

注意点:夹具只有在定义夹具的范围内才能使用。如果夹具是在类中定义的,则只能由该类内的测试用例使用。但是如果在模块的全局范围内定义的夹具,那么该模块中的每个测试用例,即使它是在一个类中定义的,都可以使用它。

知道了怎么定义夹具,那么接下来我们来看看如何使用夹具。

2、夹具的使用

测试夹具定义好之后,测试函数通过将它们声明为参数,来指定执行用例之前要执行的夹具。

当 pytest 开始运行测试时,它会查看该测试函数定义的形参,然后搜索与这些参数同名的测试夹具。一旦 pytest 找到它们,它就会运行这些夹具,接收它们返回的内容(如果有的话),并将这些返回内容作为参数传递给测试函数。

注意点:当我们使用夹具时,如果夹具的前置脚本执行完,有数据要传递用例,需要传递的数据写在 yield 后面即可,在使用夹具的用例或者方法中,可以通过定义的形参来获取 yeild 返回的数据(章节 2.3 中有使用案例介绍)

2.1、在用例中使用夹具
不管是函数形式定义的测试用例,还是测试类中方法的形式定义的用例,在使用的时候都是一样的,直接定义一个和要使用的夹具同名的形参即可。

import pytest

# 定义一个用例级别的夹具
@pytest.fixture
def my_fixture():
    print('------my_fixture---用例前置执行脚本--------')
    yield
    print('------my_fixture---用例后置执行脚本--------')

# 函数用例 指定测试夹具
def test_func__01(my_fixture):
    print("测试用例----test_func__01----")


class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self, my_fixture):
        print('----测试用例:test_02------')
  
     # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_03------')

运行结果

C:\testcases>pytest -s
======================== test session starts ========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins: testreport-1.1.2
collected 2 items  
test_demo.py 
------my_fixture---前置执行脚本--------
测试用例----test_func__01----.
------my_fixture---后置执行脚本--------
------my_fixture---前置执行脚本--------
----测试用例:test_02------.
------my_fixture---后置执行脚本--------
----测试用例:test_03------
======================== 2 passed in 0.27s ========================

上面 test_func__01和test_02 这两个用例在定义时指定了测试夹具,而 test_03 则没有指定执行的夹具,执行用例时库看到指定了夹具的用例,执行了对应的夹具。

2.2、测试类和模块指定夹具

上面我们通过给用例方法加形参来给单个测试用例指定测试夹具。如果一个测试类中有很多测试用例或者一个模块中有很多用例,都要指定同一个测试夹具,要我们则可以通过 usefixtures 给测试类或测试模块指定测试夹具。

给测试类中所有的用例指定夹具

# TestDome这个测试类的所有测试用例均执行my_fixture这个夹具
@pytest.mark.usefixtures('my_fixture这个夹具')
class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self):
        print('----测试用例:test_01------')

    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_02------')

使用 pytestmark 在测试模块级别 指定模块所有用例执行的夹具

# test_demo.py

# 当前模块中所有的用例,均执行my_fixture这个测试夹具
pytestmark = pytest.mark.usefixtures('my_fixture')

# 函数用例 指定测试夹具
def test_func__01(my_fixture):
    print("测试用例————test_func__01——————")

  
class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self):
        print('----测试用例:test_01------')

    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_02------')

2.3、在夹具中引用夹具

pytest 的最大优势之一是其极其灵活的夹具系统。通过测试夹具我们可以将极为复杂化的前后置依赖,拆分为更简单单一功能的测试夹具,通过在夹具中引用其他的夹具,来组织不同用例所需的复杂依赖环境。接下来我们通过一个案例来给大家演示如何使用。

import pytest
# 用户注册的夹具
@pytest.fixture
def register_user():
    print('---用户注册的夹具前置执行----')
    # ...注册代码省略,注册的用户信息如下
    user_info = {
    
    'user': 'lemonban', 'pwd': '123456'}
    yield user_info
    print('---用户注册的夹具后置执行----')


# 用户登录的夹具,通过定义形参来使用register_user这个夹具
@pytest.fixture
def user_login(register_user):
    print('---用户登录的夹具前置执行----')
    # 获取register_user结局前置脚本执行完,yeild传递出来的数据
    user_info = register_user
    # ...登录代码省略,下面为登录得到的token
    token = 'sdjasjdask'
    yield token
    print('---用户登录的夹具后置执行----')

# 函数用例 指定使用测试夹具user_login
def test_func__01(user_login):
    token = user_login
    print("测试用例夹具user_login传递过来的token:",token)
    print("测试用例---test_func__01---")

运行结果

C:\testcases>pytest -s
======================== test session starts ========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins: testreport-1.1.2
collected 1 item  
test_demo.py 
---用户注册的夹具前置执行----
夹具register_user传递过来的用户信息: {
    
    'user': 'lemonban', 'pwd': '123456'}
---用户登录的夹具前置执行----
测试用例夹具user_login传递过来的token: sdjasjdask
测试用例---test_func__01---.
---用户登录的夹具后置执行----
---用户注册的夹具后置执行----

2.4、自动使用夹具

在定义测试夹具 我们可以给夹具的装饰器加参数 autouse=True 来使夹具成为自动执行的夹具。具体案例如下:

import pytest


@pytest.fixture(autouse=True)
def my_fixture():
    print('------my_fixture---前置执行脚本--------')
    yield
    print('------my_fixture---后置执行脚本--------')


class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self):
        print('----测试用例:test_01------')

    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_02------')


class TestDome2:
    # 函数用例 指定测试夹具
    def test_03(self):
        print('----测试用例:test_03------')

执行结果:

C:\testcases>pytest -s
======================== test session starts ========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins: testreport-1.1.2
collected 3 items    
test_demo.py
------my_fixture---前置执行脚本--------
----测试用例:test_01------.
------my_fixture---后置执行脚本--------
------my_fixture---前置执行脚本--------
----测试用例:test_02------.
------my_fixture---后置执行脚本--------
------my_fixture---前置执行脚本--------
----测试用例:test_03------.
------my_fixture---后置执行脚本--------
======================== 3 passed in 0.29s ========================

从上面的执行结果我们可以看到,每条用例执行之前都自动执行了测试夹具 my_fixture

3、conftest.py

在一个项目的测试中,大多数情况下会有多个类、模块、或者包要使用相同的测试夹具。这种情况下如果我们把测试夹具定义在某一个模块中则无法实现共享,针对这种情况,我们可以把需要共享的测试夹具放入一个单独的 conftest.py 文件中 ,这样多个可以实现多个测试模块共享了

ps : pytest 运行测试时,如果项目中有 conftest.py,那么 pytest 会自动加载 conftest.py 模块中的内容,可以把 conftest 看出 pytest 会自动加载的插件模块,后续的教程中会涉及到在 conftest.py 中定义 pytest 的 hooks 函数

接下来我们来看一个 conftest.py 定义测试夹具的案例

在 conftest.py 中定义测试夹具 my_fixture

# conftest.py

import pytest

@pytest.fixture
def my_fixture():
    print('------my_fixture---前置执行脚本--------')
    yield
    print('------my_fixture---后置执行脚本--------')

在 test_demo1.py 的用例用使用 conftest.py 中定义的夹具

# test_demo1.py
class TestDome:
    # 函数用例 指定测试夹具
    def test_02(self,my_fixture):
        print('----测试用例:test_01------')

    # 函数用例 指定测试夹具
    def test_03(self,my_fixture):
        print('----测试用例:test_02------')

在 test_demo2.py 的用例用使用 conftest.py 中定义的夹具

# test_demo2.py
class TestDome2:
    # 函数用例 指定测试夹具
    def test_03(self,my_fixture):
        print('----测试用例:test_03------')

执行结果:

C:\testcases>pytest -s
======================== test session starts ========================
platform win32 -- Python 3.7.3, pytest-5.4.2, py-1.8.0, pluggy-0.13.0
rootdir: C:\testcases
plugins: testreport-1.1.2
collected 3 items
test_demo.py 
------my_fixture---前置执行脚本--------
----测试用例:test_01------.
------my_fixture---后置执行脚本--------
------my_fixture---前置执行脚本--------
----测试用例:test_02------.
------my_fixture---后置执行脚本--------
test_demo2.py 
------my_fixture---前置执行脚本--------
----测试用例:test_03------.
------my_fixture---后置执行脚本--------
======================== 3 passed in 0.29s ========================

上述案例中我们可以发现 test_demo.py和test_demo2.py 中的用例可以成功使用 conftest.py 中的测试用例。

下面是一份配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!
在这里插入图片描述
这些都可以以在公众号:伤心的辣条 ! 免费领取,还有一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中资料包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

学习不要孤军奋战,最好是能抱团取暖,相互成就一起成长,群众效应的效果是非常强大的,大家一起学习,一起打卡,会更有学习动力,也更能坚持下去。你可以加入我们的测试技术交流扣扣群:914172719(里面有各种软件测试资源和技术讨论)

喜欢软件测试的小伙伴们,如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!


好文推荐

转行面试,跳槽面试,软件测试人员都必须知道的这几种面试技巧!

面试经:一线城市搬砖!又面软件测试岗,5000就知足了…

面试官:工作三年,还来面初级测试?恐怕你的软件测试工程师的头衔要加双引号…

什么样的人适合从事软件测试工作?

那个准点下班的人,比我先升职了…

测试岗反复跳槽,跳着跳着就跳没了…

猜你喜欢

转载自blog.csdn.net/AI_Green/article/details/121705267
今日推荐