自动化测试感觉很像重复测试逻辑,我做得对吗?

时间:2011-10-19 20:04:45

标签: unit-testing testing language-agnostic tdd

我正在用C ++中的CppUTest实现自动化测试 我意识到我最终几乎要复制并粘贴要在测试中测试的逻辑,所以我可以检查预期的结果 我做得对吗?应该不是吗?

编辑:我会试着更好地解释一下:
正在测试的单元输入 A ,进行一些处理并返回输出 B
因此,除了进行一些黑盒检查,比如检查输出是否在可预期的范围内,我还想看看我得到的输出 B 是否是输入 A的正确结果 IE如果逻辑按预期工作。
因此,例如,如果单位只使 A 乘以2来产生 B ,那么在测试中我没有其他方式进行检查而不是再次计算 A 次2来检查 B 以确保它没有问题 这就是我所说的重复。

// Actual function being tested:  
int times2( int a )
{
  return a * 2;
}

// Test:
int test_a;
int expected_b = test_a * 2; // here I'm duplicating times2()'s logic
int actual_b = times2( test_a );
CHECK( actual_b == expected_b );

PS:我想我会用另外一个问题用我的实际源代码重新制定这个。

4 个答案:

答案 0 :(得分:5)

如果您的目标是为现有代码构建自动化测试,那么您可能做错了。希望你知道frobozz.Gonkulate()的结果应该用于各种输入,并且可以编写测试来检查Gonkulate()是否正在返回正确的东西。如果你必须复制Gonkulate()的复杂逻辑来找出答案,你可能想要问自己,你对逻辑开始的理解程度如何。

如果您正在尝试进行测试驱动的开发,那么肯定做错了。 TDD包含许多快速循环:

  1. 编写测试
  2. 看着它失败
  3. 通过
  4. 根据需要进行重构以改善整体设计
  5. 第1步 - 编写测试第一 - 是TDD的重要组成部分。我从你的问题推断出你先编写代码然后再编写测试。

答案 1 :(得分:5)

  

因此,例如,如果单位只是将A乘以2乘以B,那么   测试我没有其他方法检查而不是重新制作   计算A次2来检查B以确定它去了   正常的。

是的,你这样做!您知道如何计算A乘以2,因此您不需要在代码中执行此操作。如果A是4那么你知道答案是8.所以你可以把它当作预期值。

CHECK( actual_b == 8 )

如果你担心魔术数字,请不要。没有人会对以下行中硬编码数字的含义感到困惑:

CHECK( times_2(4) == 8 )

如果您不知道结果应该是什么,那么您的单元测试就没用了。如果你需要计算预期的结果,那么你要么使用与函数相同的逻辑,要么使用替代算法来计算结果。在第一种情况下,如果你复制的逻辑不正确,你的测试仍然是通过!在第二种情况下,您将引入另一个发生错误的地方。如果测试失败,您将需要确定它是否失败,因为测试中的函数有错误,或者您的测试方法有错误。

答案 2 :(得分:2)

我认为这是一个破解因为它本质上是一种心态转变。这对我来说有点困难。

关于测试的事情是确保你的预期,并检查你的代码是否真的按照你的想法行事。思考如何行使它,而不是直接检查它的逻辑,而是作为一个整体。如果这太难了,也许你的功能/方法做得太多了。

尝试将您的测试视为代码可以执行的操作示例,而不是数学证明。

答案 3 :(得分:1)

编程语言无关紧要。

 var ANY_NUMBER = 4;
 Assert.That(times_2(ANY_NUMBER), Is.EqualTo(ANY_NUMBER*2)

在这种情况下,我不介意重复逻辑。与8相比,期望值是可读的。其次,这个逻辑看起来不像变换磁铁。相对静止。

对于情况,逻辑更多涉及(粗略)并且容易发生变化,绝对不建议重复测试中的逻辑。复制是邪恶的。对逻辑的任何更改都会影响测试的变化。在这种情况下,我会使用硬编码的输入预期输出对和一些可读的对名称。