如何基于java对象模型生成测试数据?

问题描述 投票:0回答:2

我们假设有一个 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;
}

手动编写和维护这些测试数据非常繁琐。

我相信这个手动过程可以自动化,比方说:

  • 最小值:可空字段为 null,数字字段为最小值,字符串/集合字段为最小长度,布尔值为 false
  • 最大值:可为空字段不为空,数字字段为最大值,字符串/集合字段为最大长度,布尔值为 true
  • 低于最小值:可空字段为 null...您将获得其余的:)
  • 高于最大值

那么程序员应该能够调用:

SomeMagicalGenerator.for(Person.class)
  .generateMaximum() // returns a Stream<Person>
  .distinct()
  .limit(10)

并将其用作 TestNG DataProvider 例如。

起初 Instancio 看起来很有前途:) 在这里检查:https://github.com/adrian-herscu/instancio-experiment

但是...我没能找到一种方法让它根据注释生成最小值和最大值。在我的梦想中,如果这可行,那么让它生成超出范围的值也应该是可行的。

有什么想法吗?建议?我错过了什么吗?

java generator test-data instancio
2个回答
1
投票

我希望我正确理解你的意图...两种解释选项:

对我来说,这听起来很危险,接近于测试注释的实现,而不是你自己的代码。

我不期望从这种测试中学到太多东西。如果注释是手动实现的:当然 - 验证验证是否正确。但就我个人而言,这样我就会跳过编写这些测试。

如果这样的测试失败会发生什么?我的期望是:如果测试失败,修复方法是更正注释。这可能会导致任何依赖原始注释的外部组件被破坏。但一般来说,您只是测试是否使用了“正确”注释 - 这是简单审查可以做到的事情(毕竟,您也审查了测试是否正确,对吗?这样就可以了同样的审查做两次:用于注释

测试)

另一种选择:

如果你想生成随机对象:这些对于每个测试都是可重复的吗?数据预计是完全随机的吗?您使用地址的示例:当然,“aiwjelfkmjlsk”听起来不像是对地球上任何点的描述,尽管“krk”实际上是。如果您

真的只想验证长度和最小/最大等静态标准,那么您是对的。但如果数据有任何语义,你就没有赢得任何东西。

如果随机值

不可重复,则随机测试可能会失败,而下一次运行会由于生成其他值而成功。

测试的显式输入值也很有价值。我记得编写过一个测试,将随机数据输入“信用卡转账”网络应用程序(20 年前),实际上是通过“坐在键盘上”来生成数据。想象一下我惊讶地发现应用程序很乐意向我支付“3e3”钱(又名 3000),而不是因为不是数字而拒绝它。在测试中明确具有这样的值比随机的不可再现数据流更有价值。如果它是可再现的随机性,您甚至可能无法获得这样的值,而这为您的应用程序提供了巨大的文档价值。


0
投票
如果启用

Keys.BEAN_VALIDATION_ENABLED

 设置,则 Instancio 将使用约束生成有效对象。

Person person = Instancio.of(Person.class) .withSettings(Settings.create().set(Keys.BEAN_VALIDATION_ENABLED, true)) .create();
参见:

https://www.instancio.org/user-guide/#bean-validation

© www.soinside.com 2019 - 2024. All rights reserved.