前戏

fixture是在测试函数运行前后,由pytest执行的外壳函数。fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集、配置测试前系统的初始状态、为批量测试提供数据源等等。

下面是一个简单的fixture

import pytest

@pytest.fixture()
def some_data():
return 37 def test_some_data(some_data):
assert some_data == 37

我们来运行一下

@pytest.fixture()装饰器用于声明函数是一个fixture,如果测试函数的参数列表中包含fixture名,那么pytest会检测到,并在测试函数运行之前执行该fixture。fixture可以完成任务,也可以返回数据给测试函数。

测试用例test_some_data()的参数列表中包含一个fixture名some_data,pytest会以该名称搜索fixture。pytest会优先搜索该测试所在的模块,然后搜索conftest.py

建议:被fixture装饰的函数别以test命名,比如上面的命名为some_data,而不是test_data。当然,这样命名也没有错,只是为了方便区分是fixture还是测试用例(函数)

conftest.py

fixture可以放在单独的测试文件里,如果你希望多个测试文件共享fixture,可以在某个公共目录下新建一个conftest.py文件,将fixture放在其中。

如果你希望fixture的作用域仅限于某个测试文件,那么将它写在该测试文件里。可以供所在目录及其子目录下的测试使用。

说明:

尽管conftest.py是python模块,但它不能被当测试文件导入,import conftest的用法是不允许出现的。

我们将上面的代码更改

conftest.py

import pytest

@pytest.fixture()
def some_data():
return 37

test_fixture.py

def test_some_data(some_data):
assert some_data == 37

当pytest执行test_some_data函数时,会自动去conftest.py里找some_data并执行,这样比如我们的用例,有些需要登录,有些不需要登录,我们可以给需要登录的用例加上fixture,当然,fixture也可以自定义使用范围,是函数,还是类,或者一个模块,后面会介绍。

fixture配置及销毁yield

fixture会在测试函数之前运行,但如果fixture函数包含yield,那么系统会在yield处停止,转而执行测试函数,等测试函数执行完毕后再回到fixture,继续执行yield后面的代码。因此,可以将yield之前的代码视为配置(setup)过程,将yield之后的代码视为清理(teardown)过程,无论测试过程中发生了什么,yield之后的代码都会被执行。

将上面的conftest.py里的代码修改一下

import pytest

@pytest.fixture()
def some_data():
yield 37
print('测试结束')

--setup-show

上面的测试,我们不会看到fixture的执行过程。如果希望看到测试过程中执行的是什么,以及执行的先后顺序,pytest提供的--setup-show选项可以实现这个功能

我们的测试被夹在中间,pytest将每一个fixture的执行分成SETUP和TEARDOWN两部分。

fixture名称前面的F代表的是fixture的作用范围,F代表函数级别的作用范围,如果是S,则代表的是会话级别的作用范围。

指定fixture作用范围

fixture包含一个叫scope(作用范围)的可选参数,用于控制fixture执行配置和销毁逻辑的频率。@pytest.fixture()的scope参数有四个带选值:function,class,module,session(默认值为function)。前面用到的fixture都没有指定scope,因此他们的作用范围都是默认的函数级别。

scope=“function”

函数级别的fixture每个测试函数只需要运行一次,配置代码在测试用例运行之前运行,销毁代码在测试用例运行之后运行。function是scope参数的默认值

conftest.py

import pytest

@pytest.fixture(scope="function")  # 函数级别的
def login():
print('登录成功')

test_fixture.py

def test_index(login):
print('访问index') def test_home(login):
print('访问home')

执行结果可以看到,我们在执行每个函数之前都执行了fixture

scope=“class”

类级别的fixture每个测试类只需要运行一次,无论测试类里有多少类方法都可以共享这个fixture

conftest.py

import pytest

@pytest.fixture(scope="class")  # 类级别
def login():
print('登录成功')

test_fixture.py

class Test1():
def test_index(self,login):
print('访问index1') def test_home(self,login):
print('访问home1') class Test2():
def test_index(self,login):
print('访问index2') def test_home(self,login):
print('访问home2')

scope=“module”

模块级别的fixture,每个模块只需要运行一次,无论模块里有多少个测试函数、类方法或者其他fixture都可以共享这个fixture

只需要修改conftest.py

import pytest

@pytest.fixture(scope="module")  # 模块级别
def login():
print('登录成功')

scope=“session”

会话级别的fixture,每次会话只需要运行一次,所有测试函数、方法都可以共享这个fixture

我们把上面的test_fixture.py在复制一份,改名为test_fixture2,这样我们在testpytest下就有两个test文件了

如果有两个文件,把session改为module,则会执行两次,因为有两个py文件

使用usefixtures指定fixture

目前为止用到fixture的测试,都是在测试函数的参数列表中指定fixture,实际上,也可以用@pytest.mark.usefixtures('fixture1', 'fixture2')标记测试函数或类。使用usefixtures,需要在参数列表中指定一个或多个fixture字符串。

使用usefixture和在测试方法中添加fixture参数,二者本体上是差不多的,区别之一在与后者才能使用fixture的返回值

import pytest

@pytest.fixture(scope="function")
def login():
print('登录成功')

conftest.py

import pytest

@pytest.mark.usefixtures('login')
def test_index():
print('访问index1') def test_home():
print('访问home1')

test_fixture2.py

如果是类值需要在类名上面加上fixture

import pytest

@pytest.mark.usefixtures('login')
class Test1():
def test_index(self):
print('访问index1') def test_home(self):
print('访问home1') @pytest.mark.usefixtures('login')
class Test2():
def test_index(self):
print('访问index2') def test_home(self):
print('访问home2')

类的fixture

@pytest.mark.usefixtures("cleandir", "anotherfixture")指定多个fixture

autouse

不想源测试数据有任何改动,或全部都实现自动应用, 没特例,也都不需要返回值时可以选择自动应用

使用fixture中参数autouse=True实现

import pytest

@pytest.fixture(autouse=True)
def login():
print('登录成功')

conftest.py

class Test1():
def test_index(self):
print('访问index1') def test_home(self):
print('访问home1') class Test2():
def test_index(self):
print('访问index2') def test_home(self):
print('访问home2')

test_fixture.py

def test_index():
print('访问index1') def test_home():
print('访问home1')

test_fixture2.py

可以看到,我们加了autouse=True之后,会给所有的方法都应用,不用再每个方法都使用fixture

如果级别是class的话,则有class的只会执行一次

为fixture重命名

fixture的名字展示在使用它的测试或其他fixture函数的参数列表上,通常会和fixture函数名保持一致,但pytest允许使用@pytest.fixture()的name参数对fixture重命名

conftest.py

import pytest

@pytest.fixture(name='login')  # 重命名为login
def alibaba_taobao_app_login():
print('登录成功')

test_fixture2.py

def test_index(login):
print('访问index1') def test_home(login):
print('访问home1')

这个fixture原来的名字是 alibaba_taobao_app_login ,重命名后变成了login

查看fixture

我们可以使用--fixtures命令行选项,并提供所在测试文件名。pytest将列举所有可供测试使用的fixture,包括重命名的。我们自己重新定义的会出现在底部

pytest--fixture的更多相关文章

  1. pytest.fixture和普通函数调用

    普通函数嗲用def one(): a="aaaaaaaaaaa" return a def test_one(): s=one() print (s) test_one() pyt ...

  2. pytest 用 @pytest.mark.usefixtures("fixtureName")或@pytest.fixture(scope="function", autouse=True)装饰,实现类似setup和TearDown的功能

    conftest.py import pytest @pytest.fixture(scope="class") def class_auto(): print("&qu ...

  3. pytest fixture 利用 params参数实现用例集合

    @pytest.fixture有一个params参数,接受一个列表,列表中每个数据都可以作为用例的输入.也就说有多少数据,就会形成多少用例.如下面例子,就形成3条用例 test_parametrizi ...

  4. pytest fixture中scope试验,包含function、module、class、session、package

    上图是试验的目录结构 conftest.py:存放pytest fixture的文件 import uuid import pytest @pytest.fixture(scope="mod ...

  5. Pytest测试框架(三):pytest fixture 用法

    xUnit style 结构的 fixture用于初始化测试函数, pytest fixture是对传统的 xUnit 架构的setup/teardown功能的改进.pytest fixture为测试 ...

  6. Pytest fixture及conftest详解

    前言 fixture是在测试函数运行前后,由pytest执行的外壳函数.fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集.配置测试前系统的初始状态.为批量测试提供数据源等 ...

  7. python单元测试框架pytest——fixture函数(类似unitest的setup和teardown)

    pytest的setup和teardown函数(曾被一家云计算面试官问到过). pytest提供了fixture函数用以在测试执行前和执行后进行必要的准备和清理工作.与python自带的unitest ...

  8. pytest进阶之fixture

    前言 学pytest就不得不说fixture,fixture是pytest的精髓所在,就像unittest中的setup和teardown一样,如果不学fixture那么使用pytest和使用unit ...

  9. pytest 15 fixture之autouse=True

    前言 平常写自动化用例会写一些前置的fixture操作,用例需要用到就直接传该函数的参数名称就行了.当用例很多的时候,每次都传这个参数,会比较麻烦.fixture里面有个参数autouse,默认是Fa ...

  10. pytest 12 函数传参和fixture传参数request

    前沿: 有的case,需要依赖于某些特定的case才可以执行,比如,登陆获取到的cookie,每次都需要带着他,为了确保是同一个用户,必须带着和登陆获取到的同一个cookies. 大部分的用例都会先登 ...

随机推荐

  1. Linux中$()和${}区别(转)

    文章转自  https://blog.csdn.net/hxchuangxiaochuan/article/details/81204084 $( )中放的是命令,相当于` `,例如todaydate ...

  2. tensorflow之tf.to_float

    1. tf.to_float()       # 将张量转换为float32类型 2. tf.to_int32()     # 将张量转换为int32类型 等等, 就是将张量转换成某一种类型.

  3. 利用 Javascript 让 DIV 自适应屏幕的分辨率,从而决定是否显示滚动条

    直接贴代码了: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> < ...

  4. js 复制 标签中的内容 方法

    <span id='id'>hello world</span><input type='button' onClick='copy("id")' v ...

  5. Xamarin移动开发备忘

    vs2017下: 1.debug用于本地生成和调试,release用于发布.区别主要在于: 安卓项目的生成选项属性中,开发者模式release是不勾的,而且高级里的cpu不同(debug是x86,re ...

  6. Python - 输入和输出 - 第十七天

    Python 输入和输出 在前面几个章节中,我们其实已经接触了 Python 的输入输出的功能.本章节我们将具体介绍 Python 的输入输出. 输出格式美化 Python两种输出值的方式: 表达式语 ...

  7. wordpress 数据查询-全局注入-模板数据消费输出简图

    我一直比较好奇,类似于wordpress这样的CMS,它可以做的很灵活,同样的软件,为什么就能做出几乎完全不具有相似性的不同站点来呢?除了功能可以有大不同以外,即便是相同的简单blog站他们的外观也可 ...

  8. Flask笔记:cookie

    在网站中,HTTP请求是无状态的:第一次请求成功后,第二次请求时服务器依然不知道这次请求的所属用户是谁.为了解决这个问题,在第一次请求成功后,服务器会生成并返回对应的cookie信息给浏览器,而浏览器 ...

  9. DRF简易了解

    Drf框架 一丶API接口 # 为了在团队内部形成共识.防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本. ...

  10. 开发技术--浅谈Python函数

    开发|浅谈Python函数 函数在实际使用中有很多不一样的小九九,我将从最基础的函数内容,延伸出函数的高级用法.此文非科普片~~ 前言 目前所有的文章思想格式都是:知识+情感. 知识:对于所有的知识点 ...