为“assertEqual”和“assertNotEqual”编写测试:我应该打扰吗?

时间:2012-08-09 11:44:17

标签: python unit-testing tdd

我有一个Coordinate类,它有一个add(Coordinate)方法。在为这个课程编写单元测试时,我已经测试了assertEqual结果:


a = Coordinate(1,2,3)
b = Coordinate(5,6,7)

result = a.add(b) 

assertEqual(result.x, 6)
assertEqual(result.y, 8)
assertEqual(result.z,10) 

我可以很容易地“假装”这个:


def add(self, other):
    return Coordinate(6,8,10)

这是测试失败的最简单的解决方案。下一步是编写第二个测试,以防止我以这种方式伪造它。我可以:

  • 使用不同的数字编写另一个assertEqual测试(因此伪造Coordinate(6,8,10)未通过,或
  • 使用两个不同的输入编写assertNotEqual测试,确保结果不是6,8,10

如果我写了assertEquals测试,那么我会得到两个非常非常相似的测试。这是一个问题吗?如果我在项目中看到类似的代码,我很想重构它。我是否应该为测试代码执行此操作 - 如果是这样,这是否意味着每个对测试最终都会被重构?

如果我写一个assertNotEqual,测试只是测试“假结果” - 我非常肯定不会出现算法错误。本质上,一旦我编写测试,停止伪造结果以便两个测试都通过,assertNotEquals测试可以安全删除,我将仍然有信心在代码 - 所以我写了测试,修复假,删除测试,这似乎相当愚蠢。

在这种情况下我该怎么做?

5 个答案:

答案 0 :(得分:2)

我不会太担心能够如你所描述的那样“假冒”测试 - 总是可以在你的方法中编写一个复杂的if语句来制作你的每个测试用例通过。相反,请查看add方法中涉及的逻辑,并确保您的测试用例涵盖所有代码分支 - 在我看来应该足够好。

答案 1 :(得分:2)

根据测试代码使用的特定情况,编写防止恶意编写代码以伪造测试代码的测试是不可能的。所以你不应该尝试。

当我说“不可能”时,我并不仅仅意味着“非常努力”,它可能是Liar Paradox打破正式系统的一个实例。

答案 2 :(得分:2)

另一个具有不同数字的assertEqual测试将足够好。如果可能的话,采取“边缘”或不常见的情况,如:

a = Coordinate(1,2,3)
b = Coordinate(-5,-6,-7)
...

AssertNotEqual测试对于读者IMO来说是荒谬的并且不直观。

无论如何,我不会太担心这种测试。作为读者,显而易见的是,编写它们的开发人员只是想测试几个案例,并且需要一个真正的重构极端主义者来重构它们。我的意思是,它只有2个测试,几乎没有重复,意图是显而易见的,并不像你必须在对象改变时重写300行代码......

答案 3 :(得分:1)

注意:为了简单起见,我将把Coordinate更改为Int。以下语法也是由...组成的。​​所以不会执行。但它应该得到我的观点

testAdd()
  assertThat(2.Add(2), isEqualTo(4))

然后你可以通过总是添加返回4来伪造这个。在三角测量旁边(通过改变某些参数来驱动通用代码)。

testAdd()
  assertThat(2.Add(2), isEqualTo(4))
  assertThat(3.Add(5), isEqualTo(8))

现在你需要让Add来做一些实际的工作.. 一旦它是绿色的,你可以让两个测试保持不变,或者你可以删除简单/琐碎的测试 - 只要它不会让你的信心下降。如果复制困扰您,您可以看看您的测试运行器是否支持“参数化测试”

[2,2,4]
[3,5,8]
testAdd(operand1, operand2, expectedResult)
  assertThat(operand1.Add(operand2), isEqualTo(expectedResult))

答案 4 :(得分:0)

Coordinate.Add()方法是什么样的?

似乎 方法应该处理如何添加(没有点伪造),然后您需要做的就是:

# In your test setUp code
testCoord = Coordinate(6, 8, 10)  # Explicitly setting the value you expect the test to return.
addCoord1 = Coordinate(1, 2, 3)
addCoord2 = Coordinate(5, 6, 7)

# The test
addCoord1.add(addCoord2)
assertEqual(testCoord, addCoord1, "Testing addition of coordinates using add() method.")

如果我错了,请纠正我,但你使用的是单元测试框架吗?我个人在unittest中将对象创建放在了测试用例的setUp中。