python最好的测试框架pytest

343 阅读3分钟

测试框架有哪些?

unittest + mock: python3 自带lib 库

Nose and nose2: 第三方库,based on unittest,提供部分插件 , 600+ stars,几十个贡献者

Pytest: 第三方库, 7.7K stars,几百个贡献者 官网:

docs.pytest.org/en/7.1.x/

www.tutorialspoint.com/pytest/inde…

Why pytest

1、支持用简单的assert语句实现丰富的断言,无需复杂的self.assert*函数

2、自动识别测试模块和测试函数

3、兼容unittest和nose测试集

4、支持Python3和PyPy3

5、丰富的插件生态

What is pytest

一个unittest 框架

也是一个命令行工具

Pytest 提供一些测试常用的函数、一个Mark对象、一类Fixture规范以及一些自定义plugin、fixture的hook 函数。

Pytest 生态,插件较为丰富(当前908个),包含测试所需的常见的的web 服务器、数据库插件,以及一些特殊场景所需插件;

Pytest 以及相关插件安装均可使用pip

Mark

Mark用来向测试case中传递信息,比如标记和filter测试case、跳过某个case以及向case中传递参数;

parametrize 编写参数化测试

import pytest
from string_utils import string_Upper
@pytest.mark.parametrize(
    's, expected',
    [
     ('foo', 'Foo'),
     ('',''),
     ('foo BAR', 'FOO BAR'),
     ],
)
def test_string_upper(s, expected):
    assert string_upper(s) == expected

Fixture(测试固件)

在编写单元测试时,我们常常需要重复用到一些东西。比如,当你测试一个图片操作模块时,可能需要在每个测试用例开始时,重复创建一张临时图片用于测试。

这类被许多单元测试依赖、需要重复使用的对象,常被称为fixfure。 1、在pytest框架下,可以非常方便地用@pytest.fixture装饰器创建fixture对象。

import pytest
import string
import random
@pytest.fixture
def random_token() ->str:
    """生成随机token"""
    token_l = []
    char_pool = string.ascii_lowercase + string.digits
    for _ in range(32):
        token_l.append(random.choice(char_pool))
    return ''.join(token_l)
   

使用的话,只要在测试函数的参数列表,增加random_token参数即可:

def test_foo(random_token):
    print(random_token)

2、fixture增加清理逻辑

@pytest.fixture
def db_connection():
    """创建并返回一个数据库连接"""
    conn = create_db_conn()
    yield conn
    conn.close()

yield前的代码在创建fixture前被调用 yield后的代码在销毁fixture前被调用

3、fixture 自动执行

@pytest.fixture(autouse=True)
def prepare_data():
    """在测试开始前,创建两个用户"""
    user.object.create(...)
    user.object.create(...)
    yield
    # 在测试结束时,销毁所有用户
    User.objects.all().delete()

无论测试函数的参数列表里是否添加了prepare_data,prepare_data fixture里的数据准备与销毁逻辑,都会在每个测试方法的开始与结束阶段自动执行。

4、fixture作用域scope

在pytest执行测试时,每当测试用例第一次引用某个fixture,pytest就会执行fixture函数,将结果提供给测试用例使用,同时将结果缓存起来。之后,根据scope的不同,这个被缓存的fixture结果会在不同的时机被销毁。而再次引用fixture会重新执行fixture函数而获得新的结果。

pytest里的fixture可以使用五种作用域,它们的区别如下。

  1. function:默认作用域。结果会在每个测试函数结束后销毁。
  2. class: 结果会在执行完类里的所有测试方法后销毁。
  3. module:结果会在执行完整个模块的所有测试后销毁。
  4. package:结果会在执行完整个包的所有测试后销毁。
  5. session: 结果会在测试会话(一次完整的pytest执行过程)结束后销毁。

Plugins

常用到的插件有 pytest-mock、pytest-cov,

monkey_patch: 对属性、dict或者环境变量的修改

mock: 对对象、模块、函数等返回值的修改,支持return或者raise

常用执行命令

1、pytest -s --capture=no --log-cli-level=DEBUG test_demo.py

conftest.py

The conftest.py file serves as a means of providing fixtures for an entire directory.

docs.pytest.org/en/7.2.x/re…

引用

flask-sqlalchemy、pytest 的单元测试和事务自动回滚