pytest-recording:记录网络交互的pytest插件

pytest-recording简介

pytest-recording是一个pytest插件,可以在测试中记录网络交互。插件基于VCR.pyVCR.py是一个用于Python的HTTP交互录制库。通过pytest-recording,可以记录HTTP请求和响应,并在测试中重放这些交互。

安装pytest-recording

使用pip安装:

pip install pytest-recording

注意,pytest-recordingpytest-vcr不兼容,因此在安装pytest-recording之前,确保已经卸载了pytest-vcr。

使用pytest-recording

基本用法

pytest-recording提供了一个简单的装饰器@pytest.mark.vcr,用于标记需要记录网络交互的测试函数。这个装饰器反映了VCR.py的use_cassettes API:

import pytest
import requests
 
@pytest.mark.vcr
def test_single():
    assert requests.get("http://httpbin.org/get").text == '{"get": true}'

pytest-recording将记录对http://httpbin.org/get的GET请求和响应,并将它们保存到一个YAML文件中(默认情况下,该文件位于cassettes/{module_name}/test_single.yaml)。在后续运行中,这个请求将被重放,而不会实际发送到网络。

使用默认磁带

有时候,可能希望多个测试函数共享同一个网络交互记录。这时,可以使用@pytest.mark.default_cassette装饰器来指定一个默认磁带文件。

@pytest.mark.default_cassette("example.yaml")
@pytest.mark.vcr
def test_default():
    assert requests.get("http://httpbin.org/get").text == '{"get": true}'

所有使用了@pytest.mark.default_cassette("example.yaml")@pytest.mark.vcr装饰器的测试函数都将共享同一个名为example.yaml的磁带文件。

结合多个磁带

除了使用默认磁带外,你还可以为单个测试函数指定多个磁带文件。这些磁带文件将被合并使用。

@pytest.mark.vcr("/path/to/ip.yaml", "/path/to/get.yaml")
def test_multiple():
    assert requests.get("http://httpbin.org/get").text == '{"get": true}'
    assert requests.get("http://httpbin.org/ip").text == '{"ip": true}'

在这个示例中,test_multiple函数将使用ip.yamlget.yaml这两个磁带文件。当对http://httpbin.org/get发起请求时,将使用get.yaml中的记录;当对http://httpbin.org/ip发起请求时,将使用ip.yaml中的记录。

断言调用/响应

你还可以基于磁带中的调用/响应来做出断言。这可以通过将vcr对象作为测试函数的参数来实现。

@pytest.mark.vcr
def test_call_count(vcr):
    assert requests.get("http://httpbin.org/get").text == '{"get": true}'
    assert requests.get("http://httpbin.org/ip").text == '{"ip": true}'
    assert vcr.play_count == 2

在这个示例中,vcr对象包含了磁带中的所有调用和响应信息。我们可以通过vcr.play_count来断言有多少个交互被重放了。

配置pytest-recording

pytest-recording提供了多种配置选项,以满足不同的测试需求。

录制模式

pytest-recording默认使用none录制模式,防止不经意的网络请求。要允许网络请求,需要通过--record-mode CLI选项来指定一个不同的录制模式(如once)。

pytest --record-mode=once

VCR支持4种录制模式:once、new_episodes、none、all

vcr_config fixture

可以通过vcr_config fixture来提供录制配置。这个fixture可以具有任何作用域(session、package、module或function),并返回一个字典,该字典将直接传递给VCR.use_cassettes。

@pytest.fixture(scope="module")
def vcr_config():
    return {
        "ignore_localhost": True,
        "filter_headers": ["authorization"]
    }

为整个模块指定了一些VCR配置选项。这些选项将应用于所有使用了@pytest.mark.vcr装饰器的测试函数。

合并配置

对于颗粒度更细的控制,可以将关键字参数传递给单个@pytest.mark.vcr装饰器。这些参数将与通过vcr_config fixture提供的配置合并成一个字典。合并时,具有更窄作用域(如function)的配置将覆盖具有更广作用域(如session)的配置。

@pytest.mark.vcr(filter_query_parameters=["api_key"])
def test_with_additional_config():
    # ...

test_with_additional_config函数将使用通过vcr_config fixture提供的配置,但filter_query_parameters选项将被覆盖为["api_key"]

重写记录模式

pytest-recording支持重写磁带的功能。这意味着你可以从头开始创建一个新的磁带文件,而不是在现有磁带文件上添加新的条目。然而,这个功能目前只适用于默认磁带文件,而不适用于额外的磁带文件。

可以通过命令行选项或vcr_config fixture来启用重写记录模式:

pytest --rewrite-recording

或者:

@pytest.fixture(scope="module")
def vcr_config():
    return {
        "record_mode": "rewrite"
    }

阻塞网络访问

为了增加测试的可靠性,可以阻塞网络访问。这样,即使测试代码尝试发起网络请求,这些请求也会被阻止。可以通过@pytest.mark.block_network装饰器或--block-network命令行选项来阻塞网络访问。

@pytest.mark.block_network
def test_with_blocked_network():
    # ...

或者:

pytest --block-network

请注意,如果启用了VCR.py录制功能,那么对于使用了@pytest.mark.vcr装饰器的测试函数来说,网络访问将不会被阻塞。

还可以允许访问指定的主机:

pytest --block-network --allow-hosts=example.com

或者通过vcr_config fixture来指定允许访问的主机:

@pytest.fixture(scope="module")
def vcr_config():
    return {
        "allow_hosts": ["example.com"]
    }

高级用法和钩子函数

pytest-recording还提供了一些高级用法和钩子函数,以满足更复杂的测试需求。

自定义匹配器、持久化器等

你可以通过pytest_recording_configure钩子函数来获取VCR实例,并注册自定义的匹配器、持久化器等。

def pytest_recording_configure(config, vcr):
    # 注册自定义匹配器、持久化器等
    pass

禁用VCR.py集成

在某些情况下,你可能希望完全禁用VCR.py集成。这时,你可以通过--disable-recording命令行选项来实现。

pytest --disable-recording
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值