亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 Pytest 和 Hypothesis 控制隨機種子?

如何使用 Pytest 和 Hypothesis 控制隨機種子?

守著星空守著你 2023-05-16 14:56:25
我有一個測試執行一個使用隨機事物的函數。我想使用假設(或其他東西?)來運行它幾次并知道,當它失敗時,使用了哪個隨機種子。我怎樣才能做到這一點?我的目標是多次測試我的代碼,以確保它不會因為使用隨機數而失敗。
查看完整描述

3 回答

?
PIPIONE

TA貢獻1829條經驗 獲得超9個贊

是的,假設聽起來是個好方法。例如:


from unittest import TestCase

from hypothesis import given

from hypothesis.strategies import integers

import hypothesis_random as undertest



class Test(TestCase):

    @given(seed=integers())

    def test_uses_random(self, seed):

        undertest.uses_random(seed)

如果您的函數引發錯誤,您將獲得異常的回溯和來自假設的偽造示例,該示例觸發它作為測試的輸出,例如


Falsifying example: test_uses_random(

    self=<test_hypothesis_random.Test testMethod=test_uses_random>, seed=-43,

)


Error

Traceback (most recent call last):

...


查看完整回答
反對 回復 2023-05-16
?
慕尼黑的夜晚無繁華

TA貢獻1864條經驗 獲得超6個贊

假設對于您的用例來說是一種極好的可能性——如果您使用得當的話。首先,為什么它有效:它不是隨機的,而是偽隨機的。當一個復雜示例的測試失敗時,它會降低復雜性,直到找到失敗的最小測試用例,然后給你那個。然后它還存儲失敗測試用例的數據庫,因此重放舊失敗是它嘗試的第一件事。


現在,缺點是構建測試用例通常需要很長時間,但好處是您可以真正確定您的代碼是健壯的。


我不知道你的代碼是什么樣的,只是為了給你一個模型:


from hypothesis import strategies as st

from hypothesis import assume


# In this example, damage and miss chance are based

# on the length of the name of the attack

samus = 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.composite

def fight_sequence(draw):

  player_one = draw(st_character)

  player_two = draw(st_character)


  # don't test entire fights, just simulate one, record the steps,

  # and check that the end state is what you expect

  actions = [

    dict(type='choose', player_number=1, player=player_one),

    dict(type='choose', player_number=2, player=player_two)

  ]


  # this filters out all test cases where players have the same character

  assume(player_one != player_two)


  n_rounds = draw(st_n_rounds)

  both_alive = True


  def _attack(player, other):

    if not both_alive:

      return


    attack = draw(player.attacks)

    response = draw(st.integers(min=0, max=len(attack)))

    response_type = 'miss' if response == 0 else 'crit' if response == len(attack)) else 'hit'

    actions.push(dict(type='attack', player=player, attack=attack, response=response_type))


    if response_type == 'hit':

       other.health -= len(attack)

    elif response_type == 'crit':

       other.health -= len(attack) * 2


    if other.health <= 0:

      actions.push(dict(type='ko', player=other))


  for _ in range(n_rounds):

    _attack(player_one, player_two)

    _attack(player_two, player_one)

  return actions

然后在您的測試用例中,將回放腳本提供給您的代碼并檢查結果是否一致。我希望你能以此為靈感。


查看完整回答
反對 回復 2023-05-16
?
慕絲7291255

TA貢獻1859條經驗 獲得超6個贊

Hypothesis 的st.random_module()策略正是為這個用例而設計的。



查看完整回答
反對 回復 2023-05-16
  • 3 回答
  • 0 關注
  • 160 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號