我是单元测试的新手--我只使用Testmethod做过基本的断言测试(我的最后一个模块,我创建了大约50个这样的模块)。
我目前正在阅读一本关于单元测试的书,书中的许多示例之一让我为每个单独的测试创建一个新类。下面是仅为一个测试用例创建的示例对象之一。我的问题是,有必要这样做吗?或者什么时候应该应用这种方法,什么时候不需要?
public class and_saving_an_invalid_item_type : when_working_with_the_item_type_repository
{
private Exception _result;
protected override void Establish_context()
{
base.Establish_context();
_session.Setup(s => s.Save(null)).Throws(new ArgumentNullException());
}
protected override void Because_of()
{
try
{
_itemTypeRepository.Save(null);
}
catch (Exception exception)
{
_result = exception;
}
}
[Test]
public void then_an_argument_null_exception_should_be_raised()
{
_result.ShouldBeInstanceOfType(typeof(ArgumentNullException));
}
}发布于 2012-06-05 07:27:12
您需要为每个单独的测试创建一个新类吗?我会说不,你当然不会。我不知道这本书为什么这么说,或者他们这样做只是为了帮助说明他们的例子。
为了回答你的问题,我建议对每组测试使用一个类……但它实际上要复杂一些,因为你如何定义“组”是不同的,并取决于你当时正在做的事情。
根据我的经验,一组测试实际上在逻辑上就像一个文档,它可以包含一组或多组测试,通过一些共同的方面将它们分组(有时是嵌套)在一起。测试面向对象代码的自然分组方式是先按类分组,然后再按方法分组。
下面是一个例子
1类的
- tests for method 2
- primary behaviour of method 2
- alternate behaviour of method 2
不幸的是,在C#或java (或类似的语言)中,你只能使用两层结构(而不是你真正想要的3层或4层),所以你必须修改一些东西来适应。
通常的方法是使用一个类将测试集分组在一起,而不是在方法级别对任何东西进行分组,如下所示:
class TestsForClass1 {
void Test_method1_primary()
void Test_method1_alternate()
void Test_method2_primary()
void Test_method2_alternate()
}如果您的方法1和方法2都有相同的设置/拆卸,那么这是很好的,但有时它们不是这样的,导致这种崩溃:
class TestsForClass1_method1 {
void Test_primary()
void Test_alternate()
}
class TestsForClass1_method2 {
void Test_primary()
void Test_alternate()
}如果你有更复杂的需求(假设你有10个method_1测试,前5个有设置要求X,接下来的5个有不同的设置要求),那么人们通常会像这样创建越来越多的类名:
class TestsForClass1_method1_withRequirementX { ... }
class TestsForClass1_method1_withRequirementY { ... }这很糟糕,但是嘿-方形钉子,圆孔,等等。
就我个人而言,我喜欢在方法中使用lambda函数来提供第三级分组。NSpec展示了一个可以做到这一点的方法...我们有一个内部测试框架,略有不同,它读起来有点像这样:
class TestsForClass1 {
void TestsForMethod1() {
It.Should("perform it's primary function", () => {
// ....
});
It.Should("perform it's alternate function", () => {
// ....
});
}
}这有一些缺点(如果第一个It语句失败,其他语句就不会运行),但我认为这种权衡是值得的。)
--问题最初是这样的:“真的有必要为我想要执行的每个测试创建一个对象吗?”根据这个解释,答案(大部分)是肯定的。
通常,单元测试涉及两个部分的交互
为了使单元测试可靠,这两个部分对于每个测试都需要是“新鲜的”,以确保系统的状态是合理和可靠的。
显然,在许多情况下情况并非如此--例如,你可能有一个纯数学函数,它只接受整数作为参数,不接触任何外部状态,然后你可能不想费心重新创建测试下的对象或测试环境……但一般来说,任何面向对象的系统中的大多数东西都需要刷新,所以这就是为什么这样做是“标准实践”的原因。
发布于 2012-06-05 07:27:20
我不能完全遵循您的示例,但理想情况下,任何测试用例都应该能够独立于任何其他测试用例运行--真的,独立于任何其他测试用例。
https://stackoverflow.com/questions/10889665
复制相似问题