在断言中认识到“每次测试一次断言”。写下面的断言是不好的:
Assert((foo != null) && (bar != null));
更好的chocie是:
Assert(foo != null);
Assert(bar != null);
问题是如果断言是:
Assert((foo == null) || (foo.length == 0));
关系是OR而不是AND。
有没有办法在保持逻辑的同时做出“每次测试一次断言”?
答案 0 :(得分:4)
指南背后的想法是,您只在一次测试中测试一个逻辑事物(在某些情况下可以归结为少数断言)。因此,如果测试失败,您就会知道失败的确切原因,并且可以快速插入特定的代码块。借用this page中的示例,如果以下测试失败,我知道在地址类型中如何提取/确定国家/地区有问题。
public void testCountry() throws Exception {
assertEquals("COUNTRY", anAddress.getCountry());
}
将此与具有多个断言的测试版本进行比较,可能由于多种原因而失败(除非您使用有用的断言消息),您需要调试测试(哎呀!)。
我需要看看你的完整测试。从它看来,它似乎是你正在检查一个没有找到的东西的集合。在这种情况下,建议返回一个空集合,以便客户端不必检查null。由于您的测试也是一个客户端,它的生命也变得更简单:Assert.AreEqual (0, foo.length)
答案 1 :(得分:4)
问题不在断言中,而是在测试用例的Arrange or Act部分:当您进行单元测试时,您在受控环境中调用[小]代码 。也就是说,您应该知道被测软件的行为方式,从而知道它是返回空指针还是空字符串。 每项测试都应有一个预期结果。
...除非您对多个行为不同的函数/方法使用测试,否则某些第三方代码在不同情况下的行为会有所不同。 如果是这种情况,“每个规则的一个断言”只是一个指导原则,您可以使用所示的断言是问题。如果此测试失败,则意味着返回的foo是非空字符串。
或者,您可以创建一个函数来测试空字符串,这也将测试字符串指针是否为null:
Assert(is_empty_string(foo));
您的语言字符串类可能会提供此方法。
答案 2 :(得分:1)
当然:一个测试确保null foo断言,一个确保0长度的非空foo也失败(其他人检查foo不为空且有长度的情况[s]! = 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
例如,在具有静态伪代码mock
的Python单元测试中,这可能是:
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