我非常喜欢Roy Osherove关于命名单元测试的3部分命名约定:
[UnitOfWork_StateUnderTest_ExpectedBehavior]
对我来说意味着什么(即使使用参数化输入):
[TestCase("user1")]
[TestCase("user2")]
public void SayHello_OnExistingUser_ReturnsHelloMessage(string username)
{
Assert.AreEqual("Hello " + username, SayHello(username));
}
[TestCase("badusername")]
[TestCase("")]
public void SayHello_OnNonExistingUser_ReturnsNull(string username)
{
Assert.IsNull(SayHello(username));
}
但是,使用参数化单元测试并且每个测试用例具有指定的预期结果时,这有点棘手,例如:
[TestCase("user1", ExpectedResult = "Hello user1")]
[TestCase("user2", ExpectedResult = "Hello user2")]
[TestCase("badusername", ExpectedResult = null)]
[TestCase("", ExpectedResult = null)]
public void TESTNAMEHERE(string username)
{
return SayHello(username);
}
对于 StateUnderTest 和 ExpectedBehavior 的参数,测试名称应该是什么不太明显。我听说过建议不要使用"期望的结果"因为这个原因,在TestCase中,它似乎是一个可以简化测试代码的潜在功能。
我想听听有关如何执行此操作的一些建议。放弃ExpectedResult为了单元测试命名清晰度?或者为测试代码简洁交换一些清晰度?
答案 0 :(得分:1)
ExpectedResult非常方便,并且总是违反了良好命名的原则。但有时会这样,在这种情况下,你的代码试图告诉你一些事情。
对于成功案例,SayHello_OnExistingUser_ReturnsExpectedGreeting等名称将起作用。
对于不成功的案例,SayHello_OnNonExistingUser_ReturnsNull也会有效。
只有尝试将逻辑上两个不同的测试组合成一个你遇到麻烦的测试。所以不要这样做。事实上,相同的代码可用于编写两个完全不同(逻辑上)不同的测试,这只是一个意外。
答案 1 :(得分:1)
据我了解,Roy Osherove的命名理念的目的是更快看到失败测试的摘要,而没有明确打开测试方法的细节。
因此NUnit
的{{1}}有一个属性TestCaseAttribute
。该属性的值将在测试资源管理器中用作测试名称。
或者使用更通用的名称进行测试,例如:
TestName