6

我对是否应该考虑某种类型的测试功能或合同有疑问。

假设我有一个类似 /getToolType 的 API,它接受 {object" "myObject"} 作为输入,并以 {type: "[az]+"} 形式返回类型

客户端和服务器之间达成一致,返回的类型将匹配一组字符串,比如 [hammer|knife|screwdriver],因此消费者决定在枚举中解析它们,当返回的类型未知时使用备用值。

消费者是否应该为每种类型(锤子、刀子、螺丝刀)包括一个测试用例,以确保生产者仍然遵守始终返回的协议,例如,当使用锤子对象调用 /getToolType 时,小写字符串“锤子” ? 或者你会认为这样的测试用例是有用的吗?为什么?

4

3 回答 3

5

IMO 的简短回答是“不”。

合同测试对结构更感兴趣,如果我们开始对 API 进行边界测试,我们就会进入功能测试 [1] 领域,最好在提供程序代码库中完成。您可以使用匹配器来确保只返回这三个值中的一个,这应该确保 Provider 构建不能返回其他值。

我会回应@J_A_X 的评论——没有正确或错误的答案,只是要小心测试输入/输出数据的所有排列。

[1] https://docs.pact.io/best_practices/contract_tests_not_functional_tests.html

于 2017-04-01T02:57:25.573 回答
1

好问题。简短的回答:没有正确或错误的方法,只是你想怎么做。

更长的答案:

Pact(和合同测试)的重点是测试特定场景并确保它们匹配。您可以在合同中简单地创建一个正则表达式,允许这些枚举使用任何字符串类型,或者可能为 null,但前提是您的消费者根本不关心该值。例如,如果工具类型有品牌,我不会关心品牌,只是它作为字符串返回,因为我只是在消费者(前端)上逐字显示品牌。

但是,如果由我决定,从我对您的场景的理解来看,考虑到它所击中的端点,似乎工具类型实际上非常重要,因此我可能会对每个枚举进行特定的测试和合同,以确保那些我的消费者的特定场景是有效的(我用某些东西调用 X,我希望 Y 具有工具类型 Z)。

这两种解决方案都是有效的,归根结底是:您认为特定的工具类型对消费者重要吗?如果是,则创建特定于它的合同,如果不是,则只需创建一个通用合同。

希望有帮助。

于 2017-03-30T00:08:13.963 回答
0

正确的状态是消费者消费锤子、刀、螺丝刀,c=(锤子,刀,螺丝刀),生产者生产锤子,刀,螺丝刀,p=(锤子,刀,螺丝刀)。有四种回归场景:

  1. c=(锤子,刀,螺丝刀,剑), p=(锤子,刀,螺丝刀)
  2. c=(锤子,刀,螺丝刀), p=(锤子,刀,螺丝刀,剑)
  3. c=(锤子,刀,螺丝刀), p=(锤子,刀)
  4. c=(锤子,刀), p=(锤子,刀,螺丝刀)

1 和 3 以非常温和的方式违约。在第一种情况下,客户声明了一种新的类型,但生产者不支持。在第三种情况下,生产者停止支持一种类型。场景的严重性当然可能是谨慎的,因为我认为软回归可能存在于关键业务流程中的某个服务中。但是,如果它很关键,那么就有很大的动机用专门的测试用例来覆盖它。第 2 和第 4 种情况更为严重,在这两种情况下,消费者可能最终都会出错,例如可能无法反序列化数据。

每种类型都有一个测试用例应该检测场景 3 和 4。在第一个场景中,它可能会触发开发人员创建一个额外的测试用例,该测试用例将在生产者站点上失败。但是,测试用例对第二种情况无能为力。因此,尽管成本相对较高,但这种策略并没有为我们提供完整的测试覆盖率。

拥有一个包含所有有效类型的正则表达式的测试用例(即锤子|刀|螺丝刀)应该是消费者开发人员在第 1 和第 4 场景中重新设计测试用例的强大触发因素。一旦正则表达式适应新的消费者能力,它就可以检测到概率 p=1/3 的场景 4(即,如果生产者选择螺丝刀作为样本值,则测试将失败)。即使没有正则表达式调整,它也会检测 p=1/3 的第三种情况。这种策略对第一种和第二种情况是无能为力的。

然而,在正则表达式之上,我们可以做更多的事情。即,我们可以用随机数据设计生产者测试用例。假设所讨论的类型定义如下:

enum Tool {hammer,knife,screwdriver}

我们可以使用以下方式渲染测试数据:

responseBody = Arranger.some(Tool.class);

这段代码使用test-arranger,但还有其他库也可以这样做。它选择一个有效的枚举值。每次都可以是不同的。它有什么变化?现在我们可以检测到第 2 种情况,并在 regex 调整后检测第 4 种情况。所以它涵盖了最严重的场景。还有一个缺点需要考虑。生产者测试是不确定的,取决于绘制的值,它可以成功或失败,这被认为是一种反模式。当一些测试有时会失败,尽管测试的代码是正确的,人们开始忽略测试的结果。请注意带有随机数据的生产者测试用例并非如此,事实上恰恰相反。尽管测试的代码不正确,它有时也会成功。它仍然远非完美,但这是一个有趣的权衡,因为它是第一个设法解决非常严重的第二种情况的策略。

我的建议是在客户端使用带有正则表达式支持的随机数据的生产者测试用例。尽管如此,没有完美的解决方案,您应该始终考虑什么对您的服务很重要。具体来说,如果消费者可以安全地忽略未知值,那么推荐的方法可能并不完美。

于 2021-02-04T06:55:52.460 回答