当前位置: 首页 > article >正文

通过一个例子理解pytest的fixture的使用

需求

  • 希望编写登陆web后做一些操作的测试用例,使用pytest框架
  • 具体测试用例执行前,需要先拿到web的token,这个获取token的动作只执行一次

例一

  • 先上测试用例代码
admin@pc-1:~$ cat my_test.py 
import pytest

class TestWebLogin:
    @pytest.fixture(scope='function', autouse=True)
    def setup_teardown(self):
        # setup
        print('@@@@@@@@@@@@@@@@@@@@@get token')
        #toke = login_web()
        self.token = 'abc'

        yield  # 运行测试用例

        # teardown

    def test_case1(self):
        # 使用 self.app 进行测试
        assert self.token is not None
        # 其他测试逻辑

    def test_case2(self):
        # 使用 self.app 进行测试
        assert self.token is not None
        # 其他测试逻辑
admin@pc-1:~$ 
admin@pc-1:~$ 
admin@pc-1:~$ pytest -sv  my_test.py 
================================================================= test session starts ==================================================================
platform linux -- Python 3.8.10, pytest-7.4.0, pluggy-1.2.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/centec
plugins: dash-2.14.1, solara-1.21.0, anyio-4.0.0
collected 2 items                                                                                                                                      

my_test.py::TestWebLogin::test_case1 @@@@@@@@@@@@@@@@@@@@@get token
PASSED
my_test.py::TestWebLogin::test_case2 @@@@@@@@@@@@@@@@@@@@@get token
PASSED

================================================================== 2 passed in 0.01s ===================================================================
admin@pc-1:~$ 
  • 解释
    • class TestWebLogin里每个test_开头的function就是一个测试用例
    • setup_teardown函数是实现login和logout,yield之前是setup,yield之后是teardown
  • 运行结果是在每个test case前都执行了一遍获取token的动作(scope=‘function’)

例二

  • 希望所有的case只在执行第一个的时候获取一下token,后面的case直接使用token即可
  • 尝试将fixture的scope从fuction改为class,并执行
admin@pc-1:~$ cat my_test.py 
import pytest

class TestWebLogin:
    @pytest.fixture(scope='class', autouse=True)
    def setup_teardown(self):
        # setup
        print('@@@@@@@@@@@@@@@@@@@@@get token')
        #toke = login_web()
        self.token = 'abc'

        yield  # 运行测试用例

        # teardown

    def test_case1(self):
        # 使用 self.app 进行测试
        assert self.token is not None
        # 其他测试逻辑

    def test_case2(self):
        # 使用 self.app 进行测试
        assert self.token is not None
        # 其他测试逻辑
admin@pc-1:~$ 
admin@pc-1:~$ pytest -sv  my_test.py 
================================================================= test session starts ==================================================================
platform linux -- Python 3.8.10, pytest-7.4.0, pluggy-1.2.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/centec
plugins: dash-2.14.1, solara-1.21.0, anyio-4.0.0
collected 2 items                                                                                                                                      

my_test.py::TestWebLogin::test_case1 @@@@@@@@@@@@@@@@@@@@@get token
FAILED
my_test.py::TestWebLogin::test_case2 FAILED

======================================================================= FAILURES =======================================================================
_______________________________________________________________ TestWebLogin.test_case1 ________________________________________________________________

self = <my_test.TestWebLogin object at 0x7f909a307cd0>

    def test_case1(self):
        # 使用 self.app 进行测试
>       assert self.token is not None
E       AttributeError: 'TestWebLogin' object has no attribute 'token'

my_test.py:17: AttributeError
_______________________________________________________________ TestWebLogin.test_case2 ________________________________________________________________

self = <my_test.TestWebLogin object at 0x7f909a307610>

    def test_case2(self):
        # 使用 self.app 进行测试
>       assert self.token is not None
E       AttributeError: 'TestWebLogin' object has no attribute 'token'

my_test.py:22: AttributeError
=============================================================== short test summary info ================================================================
FAILED my_test.py::TestWebLogin::test_case1 - AttributeError: 'TestWebLogin' object has no attribute 'token'
FAILED my_test.py::TestWebLogin::test_case2 - AttributeError: 'TestWebLogin' object has no attribute 'token'
================================================================== 2 failed in 0.14s ===================================================================
admin@pc-1:~$ 
  • 意料之外的是,在setup_teardown中明明已经给self.token赋值了,但是同在一个class下,其它的测试用例却看不到self.token!!!
  • pytest的test class是比较特殊的,不能通过self.xxx来传递值,只能通过fixture
  • 于是有了下面的改进

例三

  • case修改如下
admin@pc-1:~$ cat my_test.py 
import pytest

class TestWebLogin:
    @pytest.fixture(scope='class', autouse=False)
    def setup_teardown(self):
        # setup
        print('@@@@@@@@@@@@@@@@@@@@@get token')
        #toke = login_web()
        token = 'abc'

        yield token # 运行测试用例

        # teardown

    def test_case1(self, setup_teardown):
        token = setup_teardown
        assert token is not None
        print(f'toke={token}')
        # 其他测试逻辑

    def test_case2(self, setup_teardown):
        token = setup_teardown
        assert token is not None
        print(f'token={token}')
        # 其他测试逻辑
admin@pc-1:~$ 
admin@pc-1:~$ 
admin@pc-1:~$ 
admin@pc-1:~$ pytest -sv  my_test.py 
================================================================= test session starts ==================================================================
platform linux -- Python 3.8.10, pytest-7.4.0, pluggy-1.2.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/centec
plugins: dash-2.14.1, solara-1.21.0, anyio-4.0.0
collected 2 items                                                                                                                                      

my_test.py::TestWebLogin::test_case1 @@@@@@@@@@@@@@@@@@@@@get token
toke=abc
PASSED
my_test.py::TestWebLogin::test_case2 token=abc
PASSED

================================================================== 2 passed in 0.01s ===================================================================
admin@pc-1:~$ 
  • 修改点包括
    • fixture的scope为class,表示在TestWebLogin中只会执行一次
    • fixture的autouse赋值为False,相当于需要显式调用,不会自动运行
    • 所有的赋值就没有必要加self了
    • setup_teardown的yield后面加token,类似于return token
    • 后面的testcase 将setup_teardown作为一个参数传入,然后进行显式的赋值
  • 从执行结果来看,获取token只做了一次,后续所有的case都直接使用这个token了

http://www.kler.cn/a/145599.html

相关文章:

  • 电脑办公技巧之如何在 Word 文档中添加文字或图片水印
  • 【玩转全栈】----Django制作部门管理页面
  • Linux编译安装Netgen/NGSolve
  • Spring WebFlux 和 Spring MVC 的主要区别是什么?
  • 论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(一)
  • EAMM: 通过基于音频的情感感知运动模型实现的一次性情感对话人脸合成
  • npm配置最新淘宝镜像
  • 五大自动化测试的 Python 框架
  • centos 7.9 下利用miniconda里的pyinstaller打包python程序为二进制文件操作方法
  • 物联网AI 无线连接学习之蓝牙基础篇 协议的发展
  • 【ES6.0】- Promise对象
  • 打开CMD的六种方法,CMD快捷键,CMD命令大全及详解
  • 【自主探索】基于 frontier_exploration 的单个机器人自主探索建图
  • 乘法原理 LeetCode 828. 统计子串中的唯一字符
  • 顺序查找(线性查找),折半查找(二分或对分查找),分块查找(索引顺序查找)
  • QT基础开发笔记
  • 鸿蒙HarmonyOS 编辑器 下载 安装
  • vite-性能优化-构建优化-cnd加速优化
  • 学习Opencv(蝴蝶书/C++)——3. OpenCV的数据类型
  • 七、通过libfdk_aac编解码器实现aac音频和pcm的编解码
  • 4.整数输入,并输出变量类型【2023.11.26】
  • C++11
  • POJ 1795 DNA Laboratory 状态压缩DP(旅行商问题)
  • 《C++PrimePlus》第9章 内存模型和名称空间
  • 5.一维数组——输入一行字符,统计其中各个大写字母出现的次数。
  • 【Linux】23、内存超详细介绍