You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于pytest-randomly每次测试生成相同随机结果的问题咨询

问题:pytest-randomly 每次测试生成相同随机数集合

我正尝试正确使用pytest-randomly工具(3.15.0版本),但遇到了每次测试都会生成相同随机数集合的问题。仅安装了该工具并正常运行测试,示例代码如下:

import random

def generate_random_numbers(size):
    return [random.randint(1, 100) for _ in range(size)]

def test_random_numbers_size_1():
    numbers = generate_random_numbers(10)
    print(f"test_random_numbers_size 1.1: Generated numbers = {numbers}")
    numbers = generate_random_numbers(10)
    print(f"test_random_numbers_size 1.2: Generated numbers = {numbers}")
    assert len(numbers) == 10

def test_random_numbers_size_2():
    numbers = generate_random_numbers(10)
    print(f"test_random_numbers_size 2.1: Generated numbers = {numbers}")
    numbers = generate_random_numbers(10)
    print(f"test_random_numbers_size 2.2: Generated numbers = {numbers}")
    assert len(numbers) == 10

运行结果:

...
Using --randomly-seed=2523483435

test_example.py::test_random_numbers_size_2 PASSED                       [ 50%]
test_random_numbers_size 2.1: Generated numbers = [26, 52, 25, 95, 2, 69, 11, 94, 74, 48]
test_random_numbers_size 2.2: Generated numbers = [72, 41, 6, 27, 60, 28, 54, 48, 100, 76]

test_example.py::test_random_numbers_size_1 PASSED                       [100%]
test_random_numbers_size 1.1: Generated numbers = [26, 52, 25, 95, 2, 69, 11, 94, 74, 48]
test_random_numbers_size 1.2: Generated numbers = [72, 41, 6, 27, 60, 28, 54, 48, 100, 76]

如您所见,每个测试方法生成的随机数完全重复。这不应该是不同的吗?是否可以为每个测试方法修改pytest-randomly的seed?我尝试过使用fixtures,但没有效果。

官方文档说明:

  • 在每个测试用例和测试开始时将全局random.seed()重置为固定值——默认值为测试运行开始时的time.time(),但您可以传入--randomly-seed参数来复现由随机性导致的失败。

解决方案

这是pytest-randomly的默认行为:它会在每个测试开始时把random模块的seed重置为同一个全局种子值(也就是运行时的--randomly-seed),目的是让测试可复现——只要种子相同,每次测试的随机序列就一致。

如果想要每个测试用例使用不同的随机序列,有以下几种实用方式:

1. 手动为每个测试生成独立seed(推荐,兼顾随机性和可复现性)

利用pytest-randomly提供的randomly_seed fixture,结合测试的唯一标识生成专属seed,手动重置random模块:

import random
import pytest

def generate_random_numbers(size):
    return [random.randint(1, 100) for _ in range(size)]

@pytest.fixture(autouse=True)
def unique_test_seed(randomly_seed, request):
    # 用全局seed + 测试节点ID生成唯一seed
    test_seed = hash((randomly_seed, request.node.nodeid)) % 2**32
    random.seed(test_seed)

def test_random_numbers_size_1():
    numbers = generate_random_numbers(10)
    print(f"test_random_numbers_size 1.1: Generated numbers = {numbers}")
    numbers = generate_random_numbers(10)
    print(f"test_random_numbers_size 1.2: Generated numbers = {numbers}")
    assert len(numbers) == 10

def test_random_numbers_size_2():
    numbers = generate_random_numbers(10)
    print(f"test_random_numbers_size 2.1: Generated numbers = {numbers}")
    numbers = generate_random_numbers(10)
    print(f"test_random_numbers_size 2.2: Generated numbers = {numbers}")
    assert len(numbers) == 10

这个方法的好处是:只要全局--randomly-seed不变,每个测试的专属seed也不变,测试结果依然可复现;同时不同测试的随机序列完全不同。

2. 禁用测试前的seed重置(不推荐,丢失可复现性)

在pytest.ini或pyproject.toml中添加配置,关闭测试级别的seed重置:

# pytest.ini
[pytest]
randomly_reset_seed_per_test = false

这样random模块的状态会在测试间延续,每个测试会得到不同的随机序列,但代价是测试结果无法通过固定seed复现。

3. 排除特定模块的seed干预

如果你只想让random模块在测试间不重置,其他模块(如numpy、django)保持默认行为,可以单独配置:

# pytest.ini
[pytest]
randomly_exclude = random

这样pytest-randomly不会干预random模块的seed状态,测试间会延续随机序列。


内容的提问来源于stack exchange,提问作者Duje

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 22:44:57