Fixture:显式,模块化,可扩展

fixture: 夹具是指机械制造过程中用来固定加工对象,使之占有正确的位置,以接受施工或检测的装置,又称卡具(qiǎ jǜ)。从广义上说,在工艺过程中的任何工序,用来迅速、方便、安全地安装工件的装置,都可称为夹具。

测试夹具是为了给测试脚本提供一个固定的基准。

可以理解为使测试脚本可以重复、可靠地调用这些夹具进行组装测试脚本。(如果有经典的xunit样式中的setup和teardown概念,可以看作是对这两个东西的进一步的封装,细化各个预置和清理步骤,方便更灵活的组装测试脚本构成)

  • 通过从测试方法,模块,类或整个项目中声明夹具,用夹具名称来使用测试夹具。
  • 夹具以模块化的方式实现,可以把每个夹具看作一个测试步骤, 夹具本身可以调用其他夹具。
  • 可以对夹具和测试进行参数化,或者在方法,类,模块或整个测试会话范围内重复使用夹具。

夹具作为函数参数

# content of ./test_fixture.py
import pytest

@pytest.fixture
def smtp_connection():
    import smtplib

    return smtplib.SMTP_SSL("smtp.qq.com", 465, timeout=5)

def test_ehlo(smtp_connection):
    response, msg = smtp_connection.ehlo()
    assert response == 250

执行过程

  1. 因为test_前缀符合pytest收集测试程序的规范,所以pytest执行test_ehlo测试;
  2. 测试函数需要一个smtp_connection参数,用该参数匹配查找同名测试夹具;
  3. 找到后实例化该参数,被测试程序调用;

夹具:依赖注入

Fixtures allow test functions to easily receive and work against specific pre-initialized application objects without having to care about import/setup/cleanup details.

夹具共享:conftest.py

如果在编写测试时发现要使用多个测试文件中的夹具,可以将它们打包放到目录下的conftest.py文件中。

  1. 不需要导入要在测试中使用的夹具,它会被pytest自动发现。
  2. 发现顺序: 测试类 -> 模块 -> conftest.py -> 内置插件 -> 第三方插件
  3. 作用范围 scope
    • function
    • class 在每个测试类中调用一次夹具
    • module
    • package
    • session

    Pytest的缓存机制一次只会缓存一个夹具实例。这意味着当使用参数化的夹具时,pytest可以在给定范围内多次调用唯一夹具实例。

  4. 调用顺序

具有相同作用域的夹具的相对顺序遵循测试函数中声明的顺序,并遵循夹具之间的依赖关系。自动使用的灯 具将在显式使用的夹具之前实例化。

夹具:setup和teardown功能

# content of ./test_fixture.py
import smtplib
import pytest

@pytest.fixture(scope="module")
def smtp_connection(request):
    smtp_connection = smtplib.SMTP_SSL("smtp.qq.com", 465, timeout=5)

    def fin():
        print("teardown smtp_connection")
        smtp_connection.close()

    request.addfinalizer(fin)
    return smtp_connection

def test_ehlo(smtp_connection):
    response, msg = smtp_connection.ehlo()
    assert response == 250

夹具工厂模式

夹具工厂模式可以在单个测试中多次需要夹具结果的情况下提供帮助。夹具不是直接返回数据,而是返回生成数据的函数。然后可以在测试中多次调用此函数。

# content of ./test_fixture.py
import random
import pytest

@pytest.fixture
def make_customer_record():
    created_records = []

    def _make_customer_record(name):
        record = random.choice(name)
        created_records.append(record)
        return record

    yield _make_customer_record
    created_records.clear()

def test_customer_records(make_customer_record):
    make_customer_record("Lisa")
    make_customer_record("Mike")
    make_customer_record("Meredith")

夹具的嵌套和参数化

# content of ./test_fixture.py
import pytest
import smtplib

@pytest.fixture(scope="module", params=["smtp.qq.com", "mail.python.org"])
def smtp_connection(request):
    smtp_connection = smtplib.SMTP_SSL(request.param, 465, timeout=5)
    yield smtp_connection
    print("finalizing {}".format(smtp_connection))
    smtp_connection.close()

class App:
    def __init__(self, smtp_connection):
        self.smtp_connection = smtp_connection

@pytest.fixture(scope="module")
def app(smtp_connection):
    return App(smtp_connection)

def test_smtp_connection_exists(app):
    assert app.smtp_connection

自动使用夹具

@pytest.fixture(autouse=True)

夹具覆盖

  1. 文件夹级别子目录覆盖父级目录同名测试夹具;

原文地址:https://www.cnblogs.com/aquichita/p/11979511.html

时间: 2024-07-30 19:14:20

Fixture:显式,模块化,可扩展的相关文章

1.扩展方法2.接口的隐式实现和显式实现

1.扩展方法:必须写在一个静态类里面,具体见代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 namespace ConsoleApplication1 {     class Program     {         static void Main(string[] args)         {             Student s = new Stud

C进阶指南(3):显式内联、矢量扩展、C的逸闻轶事

五.显式内联 函数代码可被直接集成到调用函数中,而非产生独立的函数目标和单个调用.可显式地使用 inline 限定符来指示编译器这么做.根据 section 6.7.4 of C standard inline 限定符仅建议编译器使得"调用要尽可能快",并且"此建议是否有效由具体实现定义" 要用内联函数优点,最简单的方法是把函数定义为 static ,然后将定义放入头文件. /* middle.h */ static inline int middle(int a,

Javascript模块化编程(一)模块的写法最佳实践六、输入全局变量 独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。 为了在模块内部调用全局变量,必须显式地将其他变量输入模块。

Javascript模块化编程,已经成为一个迫切的需求.理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块但是,Javascript不是一种模块化编程语言,它不支持类class,更遑论模块module了 随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂.网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者不得不使用软件工程的方法,管理网页的业务逻辑. Javascript模块化编程,已

C语言进阶指南(3)丨显式内联、矢量扩展、C的逸闻轶事

五.显式内联 (想让)函数代码被直接集成到调用函数中,而非产生独立的函数目标和单个调用,可显式地使用 inline 限定符来指示编译器这么做.根据section 6.7.4 of C standardinline 限定符仅建议编译器使得”调用要尽可能快”,并且“此建议是否有效由具体实现定义” 要用内联函数优点的最简单方法是把函数定义为 static ,然后将定义放入头文件. /* middle.h */ static inline int middle(int a, int b){ return

CoreAnimation4-隐式动画和显式动画

事务 Core Animation基于一个假设,说屏幕上的任何东西都可以(或者可能)做动画.动画并不需要你在Core Animation中手动打开,相反需要明确地关闭,否则他会一直存在. 当你改变CALayer的一个可做动画的属性,它并不能立刻在屏幕上体现出来.相反,它是从先前的值平滑过渡到新的值.这一切都是默认的行为,你不需要做额外的操作. 这看起来这太棒了,似乎不太真实,我们来用一个demo解释一下:首先和第一章“图层树”一样创建一个蓝色的方块,然后添加一个按钮,随机改变它的颜色.代码见清单

iOS Core Animation Advanced Techniques(四):隐式动画和显式动画

隐式动画 按照我的意思去做,而不是我说的. -- 埃德娜,辛普森 我们在第一部分讨论了Core Animation除了动画之外可以做到的任何事情.但是动画师Core Animation库一个非常显著的特性.这一章我们来看看它是怎么做到的.具体来说,我们先来讨论框架自动完成的隐式动画(除非你明确禁用了这个功能). 事务 Core Animation基于一个假设,说屏幕上的任何东西都可以(或者可能)做动画.动画并不需要你在Core Animation中手动打开,相反需要明确地关闭,否则他会一直存在.

iOS-Core-Animation之八----显式动画

如果想让事情变得顺利,只有靠自己 -- 夏尔·纪尧姆 上一章介绍了隐式动画的概念.隐式动画是在iOS平台创建动态用户界面的一种直接方式,也是UIKit动画机制的基础,不过它并不能涵盖所有的动画类型.在这一章中,我们将要研究一下*显式动画*,它能够对一些属性做指定的自定义动画,或者创建非线性动画,比如沿着任意一条曲线移动. ##属性动画 首先我们来探讨一下*属性动画*.属性动画作用于图层的某个单一属性,并指定了它的一个目标值,或者一连串将要做动画的值.属性动画分为两种:*基础*和*关键帧*. ##

C++ dll调用-动态(显式)

C++ dll调用-动态(显式) 废话不说上代码, dll 头文件 j_test.h #pragma once extern "C"_declspec(dllexport) void maopao(int *p, int count); extern "C"_declspec(dllexport) int test(int *p, char* count); extern "C"_declspec(dllexport) int sum(int i

动态链接库DLL的加载:隐式加载(载入时加载)和显式加载(运行时加载)

静态链接库在链接时,编译器会将 .obj 文件和 .LIB 文件组织成一个 .exe 文件,程序运行时,将全部数据加载到内存. 如果程序体积较大,功能较为复杂,那么加载到内存中的时间就会比较长,最直接的一个例子就是双击打开一个软件,要很久才能看到界面.这是静态链接库的一个弊端. 动态链接库有两种加载方式:隐式加载和显示加载. 隐式加载又叫载入时加载,指在主程序载入内存时搜索DLL,并将DLL载入内存.隐式加载也会有静态链接库的问题,如果程序稍大,加载时间就会过长,用户不能接受. 显式加载又叫运行