For our API, I started using hypothesis on top pydantic, in order to enhance test test suite with autogenerated data. Our protocol is hierarchical, so comes easy to me to describe it with nested classes in pydantic:
from pydantic import BaseModel, Field, conint
from hypothesis import given, strategies as st
class Inner(BaseModel):
start: conint(ge=0, le=9) = Field(description="starting value")
end: conint(ge=0, le=9) = Field(description="it should be greater than start")
class Outer(BaseModel):
inner: Inner = Field(description="I level class")
@given(st.builds(Outer))
def test_shema(schema):
assert schema.inner.start <= schema.inner.end, "Nope!"
test_shema()
All works as expected, but I'm trying to enrich the semantic with some strategies, for example a rule between inner.start
and inner.end
. In this example one should be greater.
tentative I:
Generate values in separate ranges:
roles = {'inner.start':st.integers(max_value=5), 'inner.end':st.integers(min_value=5)}
@given(st.builds(Outer, **roles))
For this approach I'm not able to specify the field in the inner dataclass, this solution simply doesn't work. Tried nested dicts, dotted notation.
tentative II: Apply a correction to generated test function like this, but only in the test function:
if schema.inner.start >= schema.inner.end:
schema.inner.start ,schema.inner.end = schema.inner.end ,schema.inner.start
This can be a valid approach, but how to describe it to hypothesis?
Starting from official documentation I cannot find how to define strategies for nested classes or put together the composite in order to apply some logic to the generated schema.