4

断言中的“每个测试一个断言”是公认的。写断言不好如下:</p>

  Assert((foo != null) && (bar != null));

更好的选择是:

  Assert(foo != null);
  Assert(bar != null);

问题是如果断言是:

  Assert((foo == null) || (foo.length == 0));

关系是 OR 而不是 AND。

有没有办法在保持逻辑的同时做出“每个测试一个断言”?

4

3 回答 3

4

该指南背后的想法是,您只在一次测试中测试一件合乎逻辑的事情(在某些情况下可能归结为几个断言)。因此,如果测试失败,您就会知道失败的确切原因,并且可以快速进入特定的代码块。借用这个页面的一个例子,如果以下测试失败,我知道在地址类型中如何提取/确定国家/地区有问题。

public void testCountry() throws Exception {
        assertEquals("COUNTRY",  anAddress.getCountry());
    }

将此与具有多个断言的测试版本进行比较,它可能由于多种原因而失败(除非您使用有用的断言消息),否则您需要调试测试(糟糕!)。

我需要看看你的完整测试。从它所看到的情况来看,您似乎正在检查集合中是否存在未找到的场景。在这种情况下,建议返回一个空集合,以便客户端不必检查 null。由于您的测试也是客户端,因此它的生活也变得更简单:Assert.AreEqual (0, foo.length)

于 2009-06-03T05:45:14.047 回答
4

问题不在于断言,而在于测试用例的排列或动作部分:当您进行单元测试时,您会在受控环境中调用一小段代码。也就是说,您应该知道被测软件的行为方式,从而知道它会返回空指针还是空字符串。每项测试都应有一个预期结果

... 除非您针对多个行为不同的函数/方法或某些第三方代码在不同情况下表现不同的函数/方法使用您的测试。如果是这种情况,“每个规则一个断言”只是一个指导方针,您可以使用问题所示的断言。如果此测试失败,则意味着返回的 foo 是一个非空字符串。

或者,您可以创建一个函数来测试空字符串,该函数还将测试字符串指针是否不为空:

Assert(is_empty_string(foo));

您的语言字符串类可能会提供此方法。

于 2009-06-03T05:54:36.903 回答
1

当然:一项测试确保空 foo 断言,一项确保长度为 0 的非空 foo 也失败(而其他测试则检查 foo 不为空长度为 != 0 的情况)。比检查 AND 有什么好处?

编辑:根据要求的伪代码...:

  should_assert(themethod(foo=null))
  fakefoo = fakewhatever(length=0)
  should_assert(themethod(foo=fakefoo))
  ...rest of tests w/foo not null, w/length != 0

例如,在带有 Still-pseudocode 的 Python 单元测试中mock,这可能是:

  self.assertRaises(AssertionError, theobj.themethod, null)
  fakefoo = mock.makeObj(length=0)
  self.assertRaises(AssertionError, theobj.themethod, fakefoo))
  ...rest of tests w/foo not null, w/length != 0
于 2009-06-03T05:30:52.993 回答