是否可以从类型注释类生成对象进行测试?



我最近看了一下假设,并像这样使用它:

import hypothesis.strategies as s
from hypothesis import given
@given(s.integers(min_value=-(10 ** 6), max_value=10 ** 6))
def test_factorize(an_integer):
if an_integer == 0:
# This is tested in `test_factorize_zero` and should throw an exception
return
factors = mpu.math.factorize(an_integer)
product = 1
for factor in factors:
product *= factor
assert product == an_integer

这很酷。我看到的主要限制是策略(例如s.integers(,尽管有很多策略,但我仍在学习哪些策略/如何正确使用它们。

是否有一种策略来生成对象,给定一个使用 pydantic 的类型注释类?

我的尝试

from typing import Optional
from hypothesis import given
from hypothesis.strategies import from_type
from pydantic import BaseModel

class Adress(BaseModel):
city: str
street: str
house_number: int
postal_code: int

class Person(BaseModel):
prename: str
middlename: Optional[str]
lastname: str
address: Adress

@given(from_type(Person))
def test_me(person: Person):
assert isinstance(person, Person)

当我将其保存为test_foo.py并执行pytest时,我得到:

――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― test_me ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
@given(from_type(Person))
>   def test_me(person: Person):
test_foo.py:20: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
>   ???
E   pydantic.error_wrappers.ValidationError: 3 validation errors for Person
E   prename
E     field required (type=value_error.missing)
E   lastname
E     field required (type=value_error.missing)
E   address
E     field required (type=value_error.missing)
pydantic/main.py:283: ValidationError
---------------------------------------------------------------- Hypothesis ----------------------------------------------------------------
You can add @seed(42732672939050403878146949573829059697) to this test or run pytest with --hypothesis-seed=42732672939050403878146949573829059697 to reproduce this failure.

如果假设产生了一个没有中间名的人和一个有中间名的人,我会特别喜欢。

这不会开箱即用,因为 Hypothesis 需要知道使用什么类型来构建 pydantic 模型,而且我们没有特别支持 pydantic(我实际上只是从这篇文章中听说过它(。

为了支持它,可以做两件事:

  1. pydantic 可以生成正确类型的__init__方法。一个 pydantic__init__方法的签名是__pydantic_self__, **data:Any的,所以我们没有办法知道它期望什么参数。相反,如果类型签名与字段参数的类型签名匹配,则假设将开箱即用。
  2. 有人可以编写一个 PR 来为假设的from_type实现添加 pydantic 支持,以便它知道如何构建 pydantic 模型。我们已经有了对 attrs 和数据类的自定义支持,这大多看起来像这样。

如果 pydantic 开发人员对它持开放态度,我的首选解决方案将是第一个。

同时,您可以使用builds函数为模型定义自定义策略。然后,您可以将其注册为该类型的策略,也可以直接使用它。

相关内容

  • 没有找到相关文章

最新更新