我正在尝试确定单元测试的命名约定。我喜欢Roy Osherove推荐的那个:
[MethodName_StateUnderTest_ExpectedBehavior]
http://osherove.com/blog/2005/4/3/naming-standards-for-unit-tests.html
如果应用程序通过抛出异常正确处理错误的行为,我不确定这个负面测试标准。
因此,ExpectedBehavior在这种情况下总是“CorrectExceptionThrown”。为每个负面单元测试编写ExpectedBehavior仍然有意义还是可以使它成为可选项?
有利有弊。一方面,对于负面测试,它总是相同的,因此每次写入它都是多余的,它使单元测试方法名称变长。如果我们将其作为可选项,那么在必要时也不会为单元测试添加预期行为的风险。我也认为最好在整个项目中保持一致,所以在任何地方都应用它。
答案 0 :(得分:5)
在指定作为操作结果抛出的异常时,没有什么是多余的。这实际上完全符合Roy的命名惯例,给出:
SomeMethod_ExpectionalState_ThrowsInvalidOperationException
SomeMethod_ExceptionalState_ThrowsArgumentNullException
您将获得有关您的代码的重要信息 - 抛出的异常类型。但是,当你有经典的幸福路径测试时,某些部分名称的有用性是主观的。考虑:
SomeMethod_DependencyReturnsCorrectResult_ReturnsResult
SomeMethod_WhenNothingSpecialHappens_ReturnsResult
SomeMethod_EverythingElseWorked_WorksToo
这些名字带有哪些信息?相当少。 ReturnsResult
基本上意味着它有效。 NothingSpecialHappens
也是相当含糊的信息。在这种情况下,删除部分名称可能是合理的。
但是请注意,可能值得考虑更改名称而不是完全删除部分名称(例如,ReturnsResult
可以替换为不那么模糊的ReturnsEntityFromDatabase
或{ {1}})。
最后,不要盲目跟随罗伊 - 将其视为指南,而不是惯例。约定很少适用于所有可能的情况,这一点也不例外。
答案 1 :(得分:2)
你可以写:
[Test]
public void Foo_ExceptionalCaseX1_ExceptionY1Thrown()
{
}
[Test]
public void Foo_ExceptionalCaseX2_ExceptionY2Thrown()
{
}
...
如果异常情况不同且抛出的异常类型相同,则没有冗余(即使后缀相同)。
这与编写这两个测试没什么不同:
[Test]
public void Foo_SomeCaseX1_42Returned()
{
}
[Test]
public void Foo_SomeCaseX2_42Returned()
{
}
...
你能做什么 - 在两种情况下返回42,这是现实 - 对于例外也是如此。
还有一件事:当一个人阅读一系列测试时,他们可能看起来(几乎)相同,但当其中一个人有一天失败时,幸运的开发人员将能够立即知道预期的行为是什么。每个测试都应该代表它自己。
答案 2 :(得分:1)
想象一下单个单元测试失败的情况。然后你会从CI那里得到一条消息:
Failed unit tests:
MethodName_NegativeTestParams1_CorrectExceptionThrown
没有其他背景。并且您看到问题(抛出了错误的异常)。如果您将此选项设为可选项或尝试缩短方法名称,则最终可能会使用
Failed unit tests:
MethodName_NegativeTestParams1
没有任何线索出了什么问题,直到你看看测试。
在这种情况下,除了失败的单元测试列表之外没有上下文的情况下,您应该尽可能详细地设置方法名称,并根据需要重复CorrectExceptionThrown
次。
此外,CorrectExceptionThrown
消息可能不那么通用:ArgumentExceptionThrown
等,以防您对不同的测试有不同的例外。
因此,我会在所有情况下都包含预期的行为,尽管有时看起来似乎是不必要的重复。
答案 3 :(得分:0)
我认为这是真的;但是,这只是决定单元测试命名约定的一种方法。如果您明显知道此测试中的异常抛出,我认为.NET框架单元测试将提供一种像JUnit一样简单的方法。
@Test (IOException.class)
public void testIOException() {...}