12

我目前组织单元测试的方式归结为以下几点:

  • 每个项目都有自己的带有单元测试的专用项目。对于一个项目BusinessLayer,有一个BusinessLayer.UnitTests测试项目。
  • 对于我要测试的每个类,测试项目中都有一个单独的测试类,它们位于与被测类完全相同的文件夹结构和完全相同的命名空间中。对于命名空间中的类CustomerRepository,命名空间中BusinessLayer.Repositories有一个测试类。CustomerRepositoryTestsBusinessLayerUnitTests.Repositories

每个测试类中的方法都遵循简单的命名约定MethodName_Condition_ExpectedOutcome。因此,包含对定义了方法的类的CustomerRepositoryTests测试的类如下所示:CustomerRepositoryGet

[TestFixture]
public class CustomerRepositoryTests
{
    [Test]
    public void Get_WhenX_ThenRecordIsReturned()
    {
        // ...
    }

    [Test]
    public void Get_WhenY_ThenExceptionIsThrown()
    {
        // ...
    }
}

这种方法对我很有帮助,因为它使定位某些代码的测试变得非常简单。在相反的站点上,它使代码重构变得比它应该的更加困难:

  • 当我决定将一个项目拆分为多个较小的项目时,我还需要拆分我的测试项目。
  • 当我想更改一个类的命名空间时,我必须记住也要更改一个测试类的命名空间(和文件夹结构)。
  • 当我更改方法的名称时,我必须通过所有测试并在那里更改名称。当然,我可以使用搜索和替换,但这不是很可靠。最后,我仍然需要手动检查更改。

是否有一些巧妙的方法来组织单元测试,仍然可以让我快速定位特定代码的测试,同时更适合重构?

或者,是否有一些,呃,也许是 Visual Studio 扩展,可以让我以某种方式说“嘿,这些测试是针对那个方法的,所以当方法的名称发生变化时,请善待并改变测试” ? 老实说,我正在认真考虑自己写这样的东西:)

4

5 回答 5

4

经过大量测试后,我开始意识到(至少对我而言)拥有所有这些限制从长远来看会带来很多问题,而不是好事。因此,我们不再使用“名称”和约定来确定这一点,而是开始使用代码。每个项目和每个类都可以有任意数量的测试项目和测试类。所有测试代码都是根据从功能角度测试的内容(或者它实现的要求,或者它重现的错误等)来组织的。然后为了找到一段代码的测试,我们这样做:

[TestFixture]
public class MyFunctionalityTests
{
    public IEnumerable<Type> TestedClasses()
    {
        // We can find the tests for a class, because the test cases references in some special method.
        return new []{typeof(SomeTestedType), typeof(OtherTestedType)};
    }

    [Test]
    public void TestRequirement23423432()
    {
        // ... test code.
        this.TestingMethod(someObject.methodBeingTested); //We do something similar for methods if we want to track which methods are being tested (we usually don't)
        // ... 
    }
}

我们可以使用诸如 resharper “用法”之类的工具来查找测试用例等……当这还不够时,我们通过反射和 LINQ 通过加载所有测试类来做一些魔术,并运行类似的东西allTestClasses.where(testClass => testClass.TestedClasses().FindSomeTestClasses()); 你也可以使用 TearDown收集有关每个方法/类测试哪些方法的信息并执行相同的操作。

于 2012-07-21T01:59:40.743 回答
1

移动代码时保持类和测试位置同步的一种方法:

  • 将代码移动到唯一命名的临时命名空间
  • 在测试中搜索对该命名空间的引用以确定需要移动的测试
  • 将测试移动到正确的新位置
  • 一旦测试中对临时命名空间的所有引用都在正确的位置,然后将原始代码移动到其预期目标

端到端或行为测试的优势之一是测试是按需求而非代码分组的,因此您可以避免使测试位置与相应代码保持同步的问题。

于 2012-07-20T19:05:39.757 回答
1

关于将代码与测试相关联的 VS 扩展,请查看 Visual Studio 的测试影响。它在分析器下运行测试并创建一个紧凑的数据库,将 IL 序列点映射到单元测试。换句话说,当您更改代码时,Visual Studio 知道需要运行哪些测试。

于 2012-07-22T02:16:43.483 回答
0

每个项目一个单元测试项目是要走的路。我们已经尝试过一个大型单元测试项目,但这增加了编译时间。

为了帮助您重构,请使用resharpercode rush之类的产品。

于 2012-07-20T18:53:58.120 回答
0

是否有一些巧妙的方法来组织单元测试,仍然可以让我快速找到特定代码的测试

Resharper 有一些不错的捷径,可让您搜索文件或代码

正如您对 CustomerRepository 类所说的,它们是一个测试 CustomerRepositoryTests

R# 快捷方式显示输入框,以显示您在这种情况下找到的内容,您只需输入 CRT,它将显示所有以名称开头的文件,首先是大写 C,然后是 R,然后是 T

它还允许您通过通配符进行搜索,例如 CR* 将显示文件 CustomerRepository 和 CustomerRepositoryTests 的列表

于 2012-07-20T18:57:25.397 回答