TDD:测试用例的适用性

我从 TDD 和 JUnit 开始。在查看教程和文档后,我有一些问题,如果我能得到一些最佳实践反馈,我会很高兴。

A)我看到的所有示例都是针对具有某种语义/逻辑的方法。

输入->逻辑->输出

例如 2 个数字 -> 添加它们 -> 结果

由于输入到输出的转换,测试用例检查逻辑。我明白这一点,它很好。

如果没有这样的输入(或者对外部结果有很大的依赖)怎么办?

例如

String getName (int id)
{
  // read the name of a staffmember out of the DB and return it
  }

我没有看到可以在编译/部署时检查上下文无关的真正逻辑。

什么断言是有意义的,或者是一个没有测试是公平的样本?

我认为只有对上下文独立输入的测试才有意义。外部数据库或网络请求的结果不是(我认为 - 你同意吗?)。

B)你们认为“方法存在”与“带有测试用例的方法”的比率是多少?当然这取决于项目或主题,但我会对一些数字感兴趣。


FFIVE
浏览 104回答 3
3回答

米琪卡哇伊

正如 deHaar 在他的评论中指出的那样,您想要涵盖许多边缘情况。在测试数据库时,可以执行以下操作:您模拟数据库(在您的存储库中的 Spring 项目中),并将其配置为返回/抛出。然后在您的测试中,您测试以下内容:givenNoCustomerInDB_thenNotFoundExceptionThrownIsWrappedToXXX(). 在这里,您将测试调用数据库的服务方法是否捕获异常并相应地包装它。对于这种方法,您可能需要查找 Mockito,它是 Java 的“事实上的”模拟框架。另一种选择是在进行测试时使用内存数据库(例如 H2)。要记住的一件事:您有责任确保模拟(或 H2)表现得像您的真实数据库。@Kraylog 建议将适配器写入 IO 设备的集成测试,以及确保模拟行为相同的合同测试。

蝴蝶刀刀

首先,虽然大多数函数都可以进行测试,但并非所有函数都需要直接测试。通过调用代码的测试可以更好地测试一些。其次,在处理依赖于状态的副作用或代码时,有一些方法可以创建测试特定场景所需的上下文。其中一种方法是使用test doubles。当然,我们需要对不是纯函数的代码进行测试。您可以尽量减少非纯函数的代码量(例如使用函数式编程),但如果您不这样做,那么您的其余代码也需要进行测试。最后,您所说的“比率”或通常所说的“测试覆盖率”取决于您对测试套件的信心水平。最后,正是这种信心使您可以重构代码而不必担心破坏事物,这最终才是重点。

慕姐4208626

在将测试对象与其通常环境隔离的测试中,您会input -> logic -> output经常看到这种模式,因为输入数据必须由环境提供,而测试是对象所经历的环境。TDD经常使用孤立的测试;它们通常既快速又令人尴尬地并行,这意味着在设计阶段运行它们具有较低的机会成本。String getName (int id){    // read the name of a staffmember out of the DB and return it} 在像这样的示例中,我们通常会被驱使设计“该”数据库是可配置的,并且在我们的测试中,我们将提供预加载到正确状态的内存数据库。// Copy input to database// connect test subject to database// invoke query, thereby retrieving the output是一样的图案,只是雕刻的不同。在许多情况下,我们可以在我们的设计中为数据库引入一些抽象,并使该抽象而不是数据库成为配置的依赖项。因此,与其使用与数据库对话的抽象,不如使用更简单的实现,通过硬编码来返回一些值。这样的事情有时被称为测试替身。// Use the input to initialize the test double// connect test subject to test double// invoke query, thereby retrieving the output同样的模式再次出现,“逻辑”的细节发生了一些变化。logicofinput -> logic -> output不一定是您的生产代码。编写与一个外观集成的测试是很常见的,该外观协调测试主体与其(双重)依赖关系之间的交互协议。(测试,就像生产代码一样,有设计——现在投资一个好的设计可能会在测试的整个生命周期内产生可观的利润)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java