pytest 中 fixture 常见用法

fixture 是在测试函数运行前后由 pytest 执行的外壳函数,可以定制包括定义传入测试中的数据集,配置测试前系统的初始状态、为批量测试提供数据源等等。fixture 是 pytest 用于将测试前后进行预备、清理工作的代码分理处核心测试逻辑的机制。

@pytest.fixture()装饰器声明函数是一个 fixture,如果测试函数的参数列表中包含 fixture 名,那么 pytest 就会检测到,并在运行测试函数之前运行它,fixture 可以返回数据给测试函数。其优势在于编写测试函数时可以只考虑核心测试逻辑,而不需要考虑测试前的准备工作。正因为 fixture 如此重要所以整理一篇关于 fixture 用法的文章,使得能够更好更优雅地使用它。

通过 conftest.py 共享 fixture

fixture 可以单独放在测试文件中,但是如果需要多个测试文件共享 fixture,那么可以在其公共目录下新建一个 conftest.py 文件,将 fixture 放在其中。conftest 可以看作 pytest 的一个本地插件库,不允许使用 import conftest的用法,conftest 的作用范围是其所在目录及其子目录。

使用 fixture 执行配置及销毁逻辑

fixture 函数会在测试函数之前运行,但是如果 fixture 函数包含 yield,那么会在 yield 除停止并转而运行测试函数,等测试函数执行完毕后再回到该 fixture 继续执行 yield 后面的代码。可以将 yield 前面的代码看作是 setup,yield 后面的部分看作是 teardown 的过程。无论是测试函数中发生了什么是成功还是失败或者 error 等情况,yield 后面的代码都会被执行,yield 中的返回数据也可以在测试函数中使用。

# content of conftest.py

import smtplib
import pytest


@pytest.fixture(scope="module")
def smtp_connection():
    smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
    yield smtp_connection  # provide the fixture value
    print("teardown smtp")
    smtp_connection.close()

如上所示,只需要在测试函数的参数中添加 smtp_connection 即可,def smtp_connection() 中的 smtp_connection 返回值也可以在测试函数中使用。在测试函数执行完毕后继续执行 yield 后面的语句。

使用 --setup-show 回溯 fixture 执行过程

pytest 提供 --setup-show 可以看到测试过程中 fixture 的过程。结果中的 S 表示 session 即会话级别,M 表示 module 级别,C 表示 class 级别,F 表示 function 级别。

fixture 只能使用同级别或者比自己级别更高的 fixture。比如,函数级别的 fixture 使用同级别的 fixture 也可以使用类级别、模块级别、会话级别的 fixture,但是不可以反过来。

fixture 的作用范围

fixture 有一个 scope 可选参数,默认为 function ,可选值为 function、class、module、session,范围依次增加。function 表示每个测试函数只需要运行依次,配置代码在测试用例运行之前运行,销毁代码在测试用例之后运行。class 表示每个测试类运行依次,无论测试类中有多少方法,都可以共享这个 fixture。module 表示每个模块运行一次,无论模块里有多少测试函数、类方法或者其他 fixture 都可以共享这个 fixture。session 表示每次会话运行只需要运行一次,一次 pytest 会话中的所有测试函数、方法都可以共享这个 fixture。

使用 usefixtures 指定 fixture

可以在测试函数前使用 @pytest.mark.usefixtures("fixture1","fixture2")标记测试函数或者测试类。与在测试方法中添加 fixture 参数差不多,但是使用 usefixtures 不能使用 fixture 的返回值。

autouse 选项

对于那些不依赖于任何系统状态或者外部数据,又需要多次运行的代码,可以在 fixture 中添加 autouse=True选项,例如 @pytest.fixture(autouse=True, scope="session")

但是,如果可以的话,尽量应当选择参数传递或者 usefixtures 的方法而不是 autouse。autouse 会让测试函数逻辑看上去没有那么清晰,更像是一个特例。

为 fixture 重命名

通常来说使用 fixture 的测试函数会将 fixture 的函数名作为参数传递,但是 pytest 也允许将 fixture 重命名。只需要使用@pytest.fixture(name="new")即可,在测试函数中使用该 fixture 时只需要传入 new 即可。

fixture 的参数化

在 pytest 中有一个内建的 fixture 叫做 request,代表 fixture 的调用状态。request 有一个字段 param,可以使用类似@pytest.fixture(param=tasks_list)的方式,在 fixture 中使用 request.param的方式作为返回值供测试函数调用。其中 tasks_list 包含多少元素,该 fixture 就会被调用几次,分别作用在每个用到的测试函数上。

由于没有指定 id,所以在输出时 pytest 会以 fixture 名加上数字作为标识,fixture 也可以指定 id,例如@pytest.fixture(param=tasks_list,ids=task_ids)ids 可以是列表,也可以是函数供 pytest 生成 task 标识

总结

本篇主要是简单整理下 fixture 的用法,在日常工作中都是比较常用的。fixture 功能强大,是 pytest 的优点之一,利用好了是测试的利器。下篇再整理一下 pytest 的内置 fixture

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容