如何使用 Pytest 和 Hypothesis 控制随机种子?

我有一个测试执行一个使用随机事物的函数。我想使用假设(或其他东西?)来运行它几次并知道,当它失败时,使用了哪个随机种子。

我怎样才能做到这一点?

我的目标是多次测试我的代码,以确保它不会因为使用随机数而失败。


守着星空守着你
浏览 124回答 3
3回答

PIPIONE

是的,假设听起来是个好方法。例如:from unittest import TestCasefrom hypothesis import givenfrom hypothesis.strategies import integersimport hypothesis_random as undertestclass Test(TestCase):&nbsp; &nbsp; @given(seed=integers())&nbsp; &nbsp; def test_uses_random(self, seed):&nbsp; &nbsp; &nbsp; &nbsp; undertest.uses_random(seed)如果您的函数引发错误,您将获得异常的回溯和来自假设的伪造示例,该示例触发它作为测试的输出,例如Falsifying example: test_uses_random(&nbsp; &nbsp; self=<test_hypothesis_random.Test testMethod=test_uses_random>, seed=-43,)ErrorTraceback (most recent call last):...

慕尼黑的夜晚无繁华

假设对于您的用例来说是一种极好的可能性——如果您使用得当的话。首先,为什么它有效:它不是随机的,而是伪随机的。当一个复杂示例的测试失败时,它会降低复杂性,直到找到失败的最小测试用例,然后给你那个。然后它还存储失败测试用例的数据库,因此重放旧失败是它尝试的第一件事。现在,缺点是构建测试用例通常需要很长时间,但好处是您可以真正确定您的代码是健壮的。我不知道你的代码是什么样的,只是为了给你一个模型:from hypothesis import strategies as stfrom hypothesis import assume# In this example, damage and miss chance are based# on the length of the name of the attacksamus = Character(health=100, attacks=['punch', 'shoot'])wario = Character(health=70, attacks=['growl', 'punch'])bowser = Character(health=250, attacks=['growl', 'kidnap_princess'])st_character = st.sampled_from([samus, wario, bowser])st_n_rounds = st.integer(min=0, max=10)@st.compositedef fight_sequence(draw):&nbsp; player_one = draw(st_character)&nbsp; player_two = draw(st_character)&nbsp; # don't test entire fights, just simulate one, record the steps,&nbsp; # and check that the end state is what you expect&nbsp; actions = [&nbsp; &nbsp; dict(type='choose', player_number=1, player=player_one),&nbsp; &nbsp; dict(type='choose', player_number=2, player=player_two)&nbsp; ]&nbsp; # this filters out all test cases where players have the same character&nbsp; assume(player_one != player_two)&nbsp; n_rounds = draw(st_n_rounds)&nbsp; both_alive = True&nbsp; def _attack(player, other):&nbsp; &nbsp; if not both_alive:&nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; attack = draw(player.attacks)&nbsp; &nbsp; response = draw(st.integers(min=0, max=len(attack)))&nbsp; &nbsp; response_type = 'miss' if response == 0 else 'crit' if response == len(attack)) else 'hit'&nbsp; &nbsp; actions.push(dict(type='attack', player=player, attack=attack, response=response_type))&nbsp; &nbsp; if response_type == 'hit':&nbsp; &nbsp; &nbsp; &nbsp;other.health -= len(attack)&nbsp; &nbsp; elif response_type == 'crit':&nbsp; &nbsp; &nbsp; &nbsp;other.health -= len(attack) * 2&nbsp; &nbsp; if other.health <= 0:&nbsp; &nbsp; &nbsp; actions.push(dict(type='ko', player=other))&nbsp; for _ in range(n_rounds):&nbsp; &nbsp; _attack(player_one, player_two)&nbsp; &nbsp; _attack(player_two, player_one)&nbsp; return actions然后在您的测试用例中,将回放脚本提供给您的代码并检查结果是否一致。我希望你能以此为灵感。

慕丝7291255

Hypothesis 的st.random_module()策略正是为这个用例而设计的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python