提问人:Prabhleen Singh 提问时间:7/4/2023 最后编辑:Zac Hatfield-DoddsPrabhleen Singh 更新时间:7/4/2023 访问量:35
获取 .片状:数据生成不一致!在 Python 假设中
Getting .Flaky: Inconsistent data generation! in Python hypothesis
问:
我的测试是使用 (API) 创建策略,但 API 不允许重复的规则名称。 所以假设重试 API 时必然会给出不允许重复的名称。
如果在我的代码中添加逻辑以首先删除策略,如果生成了相同的规则名称,那么我点击
hypothesis.errors.Flaky: Inconsistent data generation! Data generation behaved differently between different runs. Is your data generation depending on external state?
import string
from hypothesis import assume
import pytest
import unittest
from hypothesis import strategies as st, reject
from hypothesis.stateful import RuleBasedStateMachine, precondition, rule
used_names = set()
@st.composite
def unique_name_strategy(draw):
name_strategy = st.text(min_size=5, max_size=31, alphabet=string.ascii_letters + string.digits)
while True:
name = draw(name_strategy)
if name not in used_names:
used_names.add(name)
return name
class TestsEdlp(RuleBasedStateMachine):
def __init__(self) -> None:
super().__init__()
rule_names = []
tries = 0
def rule_creation(self, rule_name):
print("in rule creation")
if rule_name in self.rule_names:
self.rule_names.remove(rule_name)
if rule_name:
self.rule_names.append(rule_name)
self.tries += 1
return True
else:
return False
@precondition(lambda self: self.tries < 10)
@rule(rule_name=unique_name_strategy())
def create_dlp_rule(self, rule_name):
print(f"in function create rule {rule_name} tries: {self.tries}")
is_success = self.rule_creation(rule_name=rule_name)
assert is_success
TestsEdlp: unittest.TestCase = TestsEdlp.TestCase
答:
0赞
Zac Hatfield-Dodds
7/4/2023
#1
问题在于,唯一名称的策略不允许 Hypothesis 在测试函数的两次不同运行中生成相同的名称,这必须被允许 - 否则,我们无法尝试变体或发现最小的失败示例(以及其他问题)。
这可能还需要做一些工作来重置每个输入假设尝试的 API 状态。(正如您后来对此问题的评论所暗示的那样)
更好的唯一名称策略是:
@st.composite
def unique_name_strategy(draw, name_strategy=st.text(string.ascii_letters + string.digits, min_size=5, max_size=31)):
used_names = draw(st.shared(st.builds(set), key="used names"))
name = draw(name_strategy.filter(lambda x: x not in used_names)
used_names.add(name)
return name
该策略只会为每个输入生成一个集合,因此我们获得了恰到好处的持久性。st.shared()
评论