C# 儿童班级的单元测试
假设我们有一个超简单的类层次结构:C# 儿童班级的单元测试,c#,unit-testing,class-hierarchy,C#,Unit Testing,Class Hierarchy,假设我们有一个超简单的类层次结构: public class SomeMath { public int Add(int x, int y) { return x + y; } } public class MoreMath : SomeMath { public int Subtract(int x, int y) { return x - y; } } 当我为MoreMath类编写测试时,是否应该为Add方法
public class SomeMath
{
public int Add(int x, int y)
{
return x + y;
}
}
public class MoreMath : SomeMath
{
public int Subtract(int x, int y)
{
return x - y;
}
}
当我为MoreMath
类编写测试时,是否应该为Add
方法编写测试?或者,当我测试SomeMath
类时,我应该只关心该方法吗?更一般地说:我应该测试一个类的所有方法,还是只测试“新”方法
我可以为双方提出一些理由。例如,当测试所有方法时,您将不止一次地测试同一事物,这不是很好,而且可能会变得单调乏味。但是如果你不测试所有的方法,
SomeMath
中的一个变化可能会破坏MoreMath
的用法?这也是一件坏事。我想这可能也要视情况而定。比如它是否扩展了我控制的类。但是无论如何,我是一个完全的测试新手,所以我很想知道哪些人比我想的更聪明:-)通常我不会在子类中测试行为,除非子类改变了父类中预期的行为。如果它使用相同的行为,则无需对其进行测试。如果您计划对父类进行破坏性更改,但子类仍然需要旧的行为,那么我将首先在子类中创建测试以定义其所需的行为,然后在父类测试和后续代码更改中进行更改。这遵循了YAGNI原则——您不需要它——并延迟了子测试的实现,直到它们真正有了目的。我只测试SomeMath类的Add
方法。如果MoreMath
只继承了它,并且完全不做任何新的事情,那么为这两种代码编写测试将是纯粹的重复代码,仅此而已。在这些事情上保持一点务实总是好的。首先,我认为至少有两个因素可能会影响你做一件或另一件事的决定:
- 遗产的目的是什么
- 这项测试的目的是什么
就我个人而言,我很少进入QA阶段。通常,在TDD期间创建的测试套件是一个足够的安全网。。。但这一切都取决于您构建的软件的类型。我将使我的
MoreMath
测试类继承自SomeMath
测试类,从而继承该类的所有测试。这意味着我只需要为新功能编写额外的测试,但所有子类的功能都经过了全面测试。在我目前的位置上,我们遇到了一个类似的问题,我们希望开发接口,但要确保接口的每个实现都能正确运行(例如,不同的数据层应该表现相同,而不管该层的实现如何)。我们解决它的方法(使用NUnit)是在单元测试中有一个继承结构:
public interface ICalculator
{
public int Add(int a, int b)
}
public class Calculator : ICalculator
{
public int Add(int a, int b) { return a + b; }
}
public class TestCalculatorInterface
{
public abstract SomeMath GetObjectToTest();
[Test]
public void TestAdd()
{
var someMath = GetObjectToTest();
...
}
}
[TestFixture]
public class TestCalculator: TestCalculatorInterface
{
public virtual Calculator GetObjectToTest() { return new Calculator(); }
}
我们在基本接口测试中没有[TestFixture]属性,但在所有测试方法中都有[test]属性。TestCalculator类就是[TestFixture]但是继承了基类的所有测试,这使得子类只负责为该接口提供要测试的对象
我会为您的案例采用类似的模式,因此测试针对所有类运行,但只编写一次。我认为这个答案假设单元测试仅以TDD方式编写。在我看来,这只是答案的一半,但请参阅我的答案进行更全面的检查。考虑到您提出的问题类型没有明确的对错答案我认为在7分钟后接受答案是个坏主意。因为它涵盖了更多的角度:)