所有单元测试都应该成功吗?

时间:2012-08-12 18:09:33

标签: unit-testing language-agnostic phpunit

假设您创建的应用程序尝试尽可能地将字母A中的内容音译成字母B.

因为语言B非常复杂,所以这并不总是成功的。但你确实得到了大致的音译。

在这种情况下你会如何构建单元测试,考虑到你预计20-30%会失败?

5 个答案:

答案 0 :(得分:8)

您的单元测试成功必须始终是目标。您使用它的方式,无法区分软件中的严重错误和您期望的翻译错误。

我建议将两者分开:

  1. 仅使用单元测试来确保您的软件以您期望的方式工作(即使这包括翻译中的一些错误)
  2. 生成包含软件生成的翻译的测试数据集。您可以手动或使用R等统计软件包检查此测试数据集,以了解您的翻译质量。

答案 1 :(得分:7)

单元测试应该是确定性的。测试失败应指示软件故障,而不是“按预期工作”。对于您的情况,以一种您可以确定结果并对其进行测试的方式准备数据,无论转换是成功还是失败(测试失败始终是一个选项,假设期望失败 - 重要的是您“我总是控制你的测试通过/失败的时间。”

答案 2 :(得分:5)

预计失败的单元测试不是单元测试。您需要通过使用充当过滤器的评估函数来更改成功的定义,并确定它是否“足够接近”并确定通过/失败。当您的翻译器变得更好时,您可以提高过滤器中的条形。

答案 3 :(得分:3)

我在这种情况下学到的一种技术是仅测试功能(或确定性)代码的各个部分。当然,如果要将确定性与非确定性部分分开,那么困难的部分。说这个的简写方法是“减少[或重构]到函数”,这意味着将代码的部分区分为确定性的,然后测试这些部分。

对于基于场景的上下文位,请在获取遗留代码测试(以及使用名为blog的开源单元测试库)时阅读此ApprovalTests有关此技术应用的帖子。 / p>

另一种可能感兴趣的技术是“基于理论”的​​测试。有关详情,请查看此blog帖子。

答案 4 :(得分:1)

单元测试可能失败的唯一原因是如果涉及时序(主要是在测试电子设备的情况下)。但是,即使这些情况,也应该从单元测试中消除时序问题,例如,通过延长/切换超时或其他时间问题(如果可能)。如果不可能,应该有详细记录。

另一种消除时序问题并使测试具有确定性的方法是使用一些注入方法为所有外部接口编写存根,即能够设置外部接口方法将返回的值。通过这种方式设置单元测试,您可以逐字测试每个错误条件。

(故事:我曾经在一家公司工作过几次单元测试会失败。只有少数人能够分析这些是严重错误还是时间问题。这将节省大量时间来进行良好的单元测试。第一名)。