我们假设有一个 Java 类对象模型,其中所有字段都用 JSR-303 约束进行注释。像这样的东西:
@SuperBuilder
@ToString
@EqualsAndHashCode
public class Address {
@Size(min = 1, max = 20)
@NotNull
public final String line1;
@Size(min = 1, max = 20)
public final String line2;
@Size(min = 1, max = 20)
public final String city;
@Size(min = 1, max = 20)
public final String country;
@Size(min = 1, max = 20)
public final String zipCode;
}
也许还有几十个这样的:
@SuperBuilder
@ToString
@EqualsAndHashCode
public class Person {
@NotNull
@Valid
public final Phone phone;
@NotNull
@Valid
public final Address address;
}
手动编写和维护这些测试数据非常繁琐。
我相信这个手动过程可以自动化,比方说:
那么程序员应该能够调用:
SomeMagicalGenerator.for(Person.class)
.generateMaximum() // returns a Stream<Person>
.distinct()
.limit(10)
并将其用作 TestNG DataProvider 例如。
起初 Instancio 看起来很有前途:) 在这里检查:https://github.com/adrian-herscu/instancio-experiment
但是...我没能找到一种方法让它根据注释生成最小值和最大值。在我的梦想中,如果这可行,那么让它生成超出范围的值也应该是可行的。
有什么想法吗?建议?我错过了什么吗?
我希望我正确理解你的意图...两种解释选项:
对我来说,这听起来很危险,接近于测试注释的实现,而不是你自己的代码。
我不期望从这种测试中学到太多东西。如果注释是手动实现的:当然 - 验证验证是否正确。但就我个人而言,这样我就会跳过编写这些测试。如果这样的测试失败会发生什么?我的期望是:如果测试失败,修复方法是更正注释。这可能会导致任何依赖原始注释的外部组件被破坏。但一般来说,您只是测试是否使用了“正确”注释 - 这是简单审查可以做到的事情(毕竟,您也审查了测试是否正确,对吗?这样就可以了同样的审查做两次:用于注释
和测试)
另一种选择:如果你想生成随机对象:这些对于每个测试都是可重复的吗?数据预计是完全随机的吗?您使用地址的示例:当然,“aiwjelfkmjlsk”听起来不像是对地球上任何点的描述,尽管“krk”实际上是。如果您
真的只想验证长度和最小/最大等静态标准,那么您是对的。但如果数据有任何语义,你就没有赢得任何东西。
如果随机值不可重复,则随机测试可能会失败,而下一次运行会由于生成其他值而成功。
测试的显式输入值也很有价值。我记得编写过一个测试,将随机数据输入“信用卡转账”网络应用程序(20 年前),实际上是通过“坐在键盘上”来生成数据。想象一下我惊讶地发现应用程序很乐意向我支付“3e3”钱(又名 3000),而不是因为不是数字而拒绝它。在测试中明确具有这样的值比随机的不可再现数据流更有价值。如果它是可再现的随机性,您甚至可能无法获得这样的值,而这为您的应用程序提供了巨大的文档价值。