我应该为测试编写测试吗?
Should I write tests for tests?
我知道单元测试的主要好处之一是,在进行关键更改时,破坏事物的代码更改非常明显。这适用于几乎任何类型的代码。它甚至似乎可以自己申请测试。然后我应该编写测试来测试我的测试是否成功测试吗?由于这本质上是递归的,我怎么知道什么时候停止?
为测试基础架构编写测试可能很有价值。例如,如果我写一个测试框架,我显然想验证关于它的一些断言:
- 它运行是测试套件中的所有测试。
- 所有测试都是 运行,即使有些测试失败。
- 报告所有失败。
- 运行 测试并发产生与 运行 连续测试相同的结果。
等等。但是,我认为编写越来越高阶的测试没有任何价值——测试通常很小,因此它们可以以孤立的方式验证整个组件之间更复杂的 interactions系统.
我敢打赌,识别和修复不稳定测试所需的程序员工作量通常比为测试编写测试要少得多。
Should I then write tests to test that my tests
没有。您可以做一些事情来帮助您进行有效的测试。
如果您确实先编写测试 - 因此失败了,当您编写目标代码并且测试通过时 - 您知道是被测代码导致了测试通过。
如果您以增量方式进行测试和编写,测试将以更简单、更短的步骤进行,总体而言往往是正确的。
如果有合理的覆盖率,测试和被测代码往往会在某种程度上相互验证。如果您的测试在预期时失败并在预期时通过;如果测试具有合理的广度 - 涵盖边缘情况 - 并且它们按预期工作。
深度同上。经过良好测试的 "low level/core" 代码意味着,高级代码的测试比您预期的要少且简单。
Assert
设置初始条件有助于确保有效的测试条件。例如 Sort
例程:我将测试列表最初是否未排序。如果它在之后排序,我知道它有效。
如果您在测试失败时输出消息:"Wrong answer. IsTestingUseful was 'false', expected 'false' " - 糟糕。这里看起来有些不对劲。
有一种可能的策略来测试测试:主动在代码中引入错误并检查测试集是否检测到错误 - 这种技术通常被命名为 mutation-testing.
例如,一个框架可以修改目标代码(单元测试正在测试的代码),比如将一些 + in - 或一些逻辑 and 变成逻辑 or 等...
此策略将确定测试是否具有足够的覆盖率,不是在测试功能、代码行、代码块或 MC-DC 方面,而是在语义方面。
此类 Smalltalk 框架的示例是 MuTalk,请参阅 https://code.google.com/p/mutalk/ but I'm pretty sure that equivalent frameworks exist for other languages - see the wikipedia page https://en.wikipedia.org/wiki/Mutation_testing。
但在这种情况下,您并不是真正编写测试来测试测试,而是使用框架来分析测试的完整性。
我知道单元测试的主要好处之一是,在进行关键更改时,破坏事物的代码更改非常明显。这适用于几乎任何类型的代码。它甚至似乎可以自己申请测试。然后我应该编写测试来测试我的测试是否成功测试吗?由于这本质上是递归的,我怎么知道什么时候停止?
为测试基础架构编写测试可能很有价值。例如,如果我写一个测试框架,我显然想验证关于它的一些断言:
- 它运行是测试套件中的所有测试。
- 所有测试都是 运行,即使有些测试失败。
- 报告所有失败。
- 运行 测试并发产生与 运行 连续测试相同的结果。
等等。但是,我认为编写越来越高阶的测试没有任何价值——测试通常很小,因此它们可以以孤立的方式验证整个组件之间更复杂的 interactions系统.
我敢打赌,识别和修复不稳定测试所需的程序员工作量通常比为测试编写测试要少得多。
Should I then write tests to test that my tests
没有。您可以做一些事情来帮助您进行有效的测试。
如果您确实先编写测试 - 因此失败了,当您编写目标代码并且测试通过时 - 您知道是被测代码导致了测试通过。
如果您以增量方式进行测试和编写,测试将以更简单、更短的步骤进行,总体而言往往是正确的。
如果有合理的覆盖率,测试和被测代码往往会在某种程度上相互验证。如果您的测试在预期时失败并在预期时通过;如果测试具有合理的广度 - 涵盖边缘情况 - 并且它们按预期工作。
深度同上。经过良好测试的 "low level/core" 代码意味着,高级代码的测试比您预期的要少且简单。
Assert
设置初始条件有助于确保有效的测试条件。例如 Sort
例程:我将测试列表最初是否未排序。如果它在之后排序,我知道它有效。
如果您在测试失败时输出消息:"Wrong answer. IsTestingUseful was 'false', expected 'false' " - 糟糕。这里看起来有些不对劲。
有一种可能的策略来测试测试:主动在代码中引入错误并检查测试集是否检测到错误 - 这种技术通常被命名为 mutation-testing.
例如,一个框架可以修改目标代码(单元测试正在测试的代码),比如将一些 + in - 或一些逻辑 and 变成逻辑 or 等...
此策略将确定测试是否具有足够的覆盖率,不是在测试功能、代码行、代码块或 MC-DC 方面,而是在语义方面。
此类 Smalltalk 框架的示例是 MuTalk,请参阅 https://code.google.com/p/mutalk/ but I'm pretty sure that equivalent frameworks exist for other languages - see the wikipedia page https://en.wikipedia.org/wiki/Mutation_testing。
但在这种情况下,您并不是真正编写测试来测试测试,而是使用框架来分析测试的完整性。