为测试生成器设定随机数种子

3
我使用了factory-boyget_random_state/set_random_state来使其正常工作,尽管这并不容易。最大的缺点是生成的值很大,所以我想把它写入文件。但是如果我不小心运行了没有从文件中获取种子的测试用例,那么值将会丢失。现在我想到可以显示这个值(类似于tee),但我仍然希望将其减少到4-5位数字。
我的想法如下。通常当你运行测试时,它会显示“种子:4215”。要复制相同的结果,我需要做的是SEED=4215 ./manage.py test或其他一些类似的操作。
我已经尝试过使用factory-boyrandom模块本身,但是我发现即使使用了这些方法,我也无法实现。我尝试了不同的想法,但是所有的尝试都失败了。其中最简单的方法是:
import random
import os
if os.getenv('A'):
    random.seed(os.getenv('A'))
else:
    seed = random.randint(0, 1000)
    random.seed(seed)
    print('seed: {}'.format(seed))
print(random.random())
print(random.random())

/app $ A= python a.py
seed: 62
0.9279915658776743
0.17302689004804395

/app $ A=62 python a.py
0.461603098412836
0.7402019819205794

为什么结果不同?如何使它们相等?

1个回答

1

目前您的类型不同:

if os.getenv('A'):
    random.seed(os.getenv('A'))
else:
    seed = random.randint(0, 1000)
    random.seed(seed)
    print('seed: {}'.format(seed))

在第一种情况下,你有一个 str,而在第二种情况下是一个 int。你可以通过在第一种情况下进行类型转换来解决这个问题:int

random.seed(int(os.getenv("A")))

我还没有完全理解你需要直接种子random的需求;我认为使用Factory Boy,您可以使用factory.random.reseed_randomsource)。


确实,这是一个愚蠢的错误。至于 reseed_random(),那是我试图让它只与 random 模块一起工作。对于测试,我将使用 reseed_random()。实际上,我还有另一个相关的问题。我应该不在这里问吗?..我把这段代码放在哪里?使用Django,您可以拥有多个应用程序,因此将其放在其中一个(app1/tests.py)似乎不太合适(会影响其他应用),尽管应该可以正常工作。 - x-yuri
1
根据您的具体需求,我认为推荐的解决方案是使用Django的扩展点:创建一个django.test.runner.DiscoverTestRunner的子类,在其中扩展setup_test_environment()以包含您的种子代码;然后将TEST_RUNNER设置指向该类。详细信息请参阅https://docs.djangoproject.com/en/3.1/topics/testing/advanced/#defining-a-test-runner :) - Xelnor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接