繁体   English   中英

Osherove的负面单元测试命名约定?

[英]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可以用更少的模糊更换ReturnsEntityFromDatabaseReturnsSerializedValue )。

最后,不要盲目跟随罗伊 - 将其视为指导方针 ,而不是惯例。 公约很少适用于所有可能的情况 ,这一点也不例外。

你可以写:

[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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM