Skip to content

Pytest测试用例生命周期管理

Pytest 测试用例生命周期管理

简介

在 Pytest 中,测试用例的生命周期管理是指在测试用例的执行过程中,Pytest 提供了一些钩子函数(Fixture)和机制,以便在测试开始前和结束后执行特定的操作。这些操作可以包括设置和清理资源、数据库连接、数据准备等。

Fixture 是什么

Fixture 是一种功能,它允许在测试用例中创建和管理预定义的环境、数据或对象。Fixture 提供了一种在测试之前进行设置和在测试之后进行清理的机制,以确保测试用例在可控的环境中运行。Pytest 的 Fixture 功能使测试编写变得更加灵活、模块化和可维护,它是 Pytest 的核心特性之一。在软件开发和测试领域,用于支持自动化测试、集成测试、单元测试以及其他开发和测试任务。

Fixture 特点及优势

Fixture 是 Pytest 的一个重要特性,它用于提供测试环境的设置和清理。下面是 fixture 的几个特点和优势:

  1. 可重用性:Fixture 可以被多个测试函数共享和重复使用。我们可以在多个测试用例中使用相同的 fixture,从而避免重复编写相似的设置和清理代码。这显著提高了代码的复用性和维护性。

  2. 灵活性:Fixture 具有参数化和依赖关系的特性,可以根据需要动态配置测试环境。通过使用参数化装饰器,可以在不同的测试场景中传递不同的参数给 fixture,从而适应多样化的测试需求。

  3. 自动化:pytest 会自动管理 fixture 的生命周期,确保在每个测试函数执行前和执行后进行相应的设置和清理操作。这样,我们无需手动编写繁琐的 setup 和 teardown 逻辑,大大简化了测试用例的编写和维护过程。

  4. 依赖注入:pytest 的 fixture 可以作为参数注入到测试函数中,使得测试函数能够方便地访问和使用 fixture 提供的测试环境。这种依赖注入的机制提高了代码的可测试性和可扩展性,使测试代码更加简洁和可读。

总的来说,fixture 提供了一个强大而灵活的测试环境管理机制,它的可重用性、灵活性以及依赖注入的优势使得 pytest 在测试框架中具有独特的优势,进而提高了测试的效率和质量。

Fixture 在自动化中的应用

基本用法

在测试用例中,可以将 Fixture 作为参数传递,从而使用 Fixture 提供的数据或对象。

  • 场景: 测试⽤例执⾏时,有的⽤例需要登录才能执⾏,有些⽤例不需要登录。setup 和 teardown ⽆法满⾜。fixture 可以。默认 scope(范围)function。

  • 步骤:

  • 1.导⼊ pytest

  • 2.在登录的函数上⾯加 @pytest.fixture()

  • 3.在要使⽤登录前提的测试⽅法中传⼊(登录函数名称),就先登录

  • 4.不传⼊的就不登录直接执⾏测试⽅法。

代码示例:

import pytest

@pytest.fixture()
def login():
     print("完成登录操作")

def test_search():
    print("搜索")

def test_cart(login):
    print("购物车")

def test_order(login):
    print("下单功能")

运行结果:

作用域

@pytest.fixture()中的scope参数设置成对应的作用域取值。对应取值的作用域如下表:

取值 范围 说明
function 函数级 每一个函数或方法都会调用
class 类级别 每个测试类只运行一次
module 模块级 每一个 py 文件调用一次
package 包级 每一个 python 包只调用一次(暂不支持)
session 会话级 每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法

yield 关键字

Fixture 中的 yield 关键字用于执行 Fixture 的清理操作。yield 语句将分隔 Fixture 的初始化操作和清理操作,确保在测试用例执行前和执行后都执行适当的操作,以维护测试环境的一致性。

  • 场景: 已经将测试⽅法的前置操作解决了,运行测试⽅法后销毁清除数据要如何进⾏?

  • 解决: 通过在 fixture 函数中加⼊ yield 关键字,yield 是调⽤第⼀次返回结果,第⼆次执⾏它下⾯的语句返回。

  • 步骤: 在登录的⽅法中加 yield,之后加销毁清除的步骤。

代码示例:

import pytest

@pytest.fixture(scope="class")
def login():
     # setup 操作
     print("完成登录操作")
     token = "abcd"
     username = 'hogwarts'
     yield token,username # 相当于return
     # teardown 操作
     print("完成登出操作")

def test_search(login):
    token,username = login
    print(f"token: {token} , name : {username}")
    print("搜索")

运行结果:

数据共享

在自动化测试中,conftest.py 文件是一个特殊的文件,用于存放共享 Fixture 和配置。这个文件允许在不同的测试模块之间共享 Fixture 和配置信息,从而提高测试的组织和可维护性。

  • 场景: 你与其他测试⼯程师合作⼀起开发时,公共的模块要在不同⽂件中,要在⼤家都访问到的地⽅。

  • 解决: 使⽤ conftest.py 这个⽂件进⾏数据共享,并且可以放在不同位置起着不同的范围共享作⽤。

  • 前提:

  • conftest ⽂件名是不能换的

  • 放在项⽬下是全局的数据共享的地⽅

  • 执⾏:

  • 系统执⾏到参数 login 时先从本模块中查找是否有这个名字的变量什么的,

  • 之后在 conftest.py 中找是否有。

  • 步骤: 将登录模块带 @pytest.fixture 写在 conftest.py。

代码示例:

# conftest.py
import pytest


@pytest.fixture(scope="class")
def login():
     # setup 操作
     print("完成登录操作")
     token = "abcd"
     username = 'hogwarts'
     yield token,username # 相当于return
     # teardown 操作
     print("完成登出操作")

@pytest.fixture()
def connectDB():
     print("连接数据库")
     yield
     print("断开数据库")

# test_fixture_conftestdemo.py
def test_get_product(login,connectDB):
    print("验证 获取单品信息")

运行结果:

自动生效

在自动化测试中,Fixture 可以用于自动生效(autouse),它们会自动在每个测试用例运行前自动调用,而无需在测试用例中显式引用 Fixture 。这对于执行通用的测试前和测试后操作非常有用。

  • 场景: 不想原测试⽅法有任何改动,或全部都⾃动实现⾃动应⽤,没有特例,也都不需要返回值时可以选择⾃动应⽤

  • 解决: 使⽤ fixture 中参数 autouse=True 实现

  • 步骤: 在⽅法上⾯加 @pytest.fixture(autouse=True)

代码示例:

@pytest.fixture(scope="function",autouse=True)
def login():
     # setup 操作
     print("完成登录操作")
     token = "abcd"
     username = 'hogwarts'
     yield token,username # 相当于return
     # teardown 操作
     print("完成登出操作")

def test_case(login):
    print("demo case")

运行结果:

总结

  • Fixture 在自动化中的应用 - 基本用法。
  • Fixture 在自动化中的应用 - 作用域。
  • Fixture 在自动化中的应用 - yield 关键字。
  • Fixture 在自动化中的应用 - 数据共享。
  • Fixture 在自动化中的应用 - 自动生效。