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