如何对OR关系条件应用“每次测试一次断言”

时间:2009-06-03 05:27:33

标签: unit-testing assert

在断言中认识到“每次测试一次断言”。写下面的断言是不好的:

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

更好的chocie是:

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

问题是如果断言是:

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

关系是OR而不是AND。

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

3 个答案:

答案 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