【问题标题】:Integration tests - what level do you test at and how do you setup?集成测试 - 您在什么级别进行测试以及如何设置?
【发布时间】:2009-04-17 20:59:31
【问题描述】:

我刚刚在我的应用程序中遇到了一个错误,可能已经被一些集成测试捕获了,所以我认为是时候写一些了!

我的问题与这些测试的设置有关,以及您在代码的哪一层运行测试。

设置

考虑到我应该有很多集成测试,我不想为每个测试创建和删除一个测试数据库,这会非常慢(即使它是内存中的 SqlLite)。我的想法是:

  1. 在我的开发数据库旁边有一个测试数据库
  2. 在测试之前,运行一些重置脚本,它将正确设置我的架构并插入任何必要的数据(不是特定于测试用例)
  3. 只需将此测试数据库用作真实数据库即可。

但是,我必须在每个 [Setup] 中运行我的 Fluent NHib 配置似乎非常浪费。这很难吗?我在这里有什么选择?

我的会话当前包装在 UoW 模式中,分别在 begin_request 和 end_request(MVC Web 应用程序)上执行创建和销毁。我应该修改它以更好地配合测试来解决这个问题吗?

测试

真正写一些测试的时候,我应该怎么做?

我应该从最高级别(我的 MVC 控制器操作)还是从最低级别(存储库)进行测试。

如果我测试最低,我将不得不手动对所有数据进行硬编码。这将使我的测试对代码的更改变得脆弱,并且也不能代表运行时代码中实际发生的情况。如果我在最高级别进行测试,我必须运行我所有的 IoCC 设置,以便注入依赖项并让整个事情发挥作用(再次,在每个 [SetUp] 中重复此操作?)

嗯!我迷路了,有人指出我正确的方向!

谢谢

【问题讨论】:

    标签: integration-testing


    【解决方案1】:

    关于创建会话工厂,我在我的测试项目中创建了一个名为 _AssemblyCommon 的类,并从那里将会话工厂公开为静态。用 [SetupFixture] (NUnit) 属性标记的方法配置会话工厂。

    一般来说,集成测试应该涵盖存储库中的 CRUD 操作。为此,我对每个对象(或聚合根)有一个测试方法,并在该方法中执行插入、检索、更新和删除所有操作。我还测试了我定义的任何级联删除。将这些操作保存在一个方法中不会在数据库中留下任何痕迹。我确实有一些集成测试会留下测试数据,但这不是问题。

    如果可能,您的更高级别的操作应该进行单元测试并模拟(我使用 Moq)存储库。

    【讨论】:

      【解决方案2】:

      在我当前的 MVC 应用程序中,我发现测试存储库和数据库之间的交互就足够了。最重要的是,这是为了消除 NHibernate 映射中的任何皱纹。该层之上的所有内容(好吧,当我说所有内容时我都在夸大其词)都是单独进行单元测试的。我确实有一些从控制器一直到堆栈到数据库的集成测试,这些测试使用 IoC 容器 (StructureMap) 来构建控制器和依赖项,但我发现这些测试实际上并没有添加任何东西,而且它们相当维护的开销,所以我现在已经将它们从“集成”测试中删除了——我可能会找到一个理由把它们放进去,但到目前为止我还没有。

      无论如何,我使用的测试过程是这样的:

      数据访问层测试程序集的构建过程通过 FluentNHibernate 配置 ExposeSchema() 调用创建测试数据库。构建过程然后运行一些 NHibernate 存储库级代码来填充数据库中的引用表。

      然后运行的每个集成测试都包装在 System.Transactions.TransactionScope using() 语句中,并且 TransactionScope 永远不会调用 Complete(),因此每个测试都可以单独运行,并且可以在 using 中设置和验证结果() 范围由 ISession 决定,而不改变任何其他测试数据的状态。例如

        using (new TransactionScope())
        {
          var session = NHibernateTestSessionCreator.GetNHibernateSessionForIntegrationTesting();
          // This is an NHibernate ISession - setup any dependencies for the repository tests here
      
          var testRepository = new NHibernateGenericRepository<NewsItem>(NHibernateTestSessionCreator.GetNHibernateSessionForIntegrationTesting())
          // repository test code goes here - the repository is using a different ISession
      
          // Validate the results here directly with the ISession
        }
      
        // at this point the transaction is rolled back and we haven't changed the test data
      

      这意味着我不必修改我正在使用的 UnitOfWork 实现 - 事务在更高级别回滚。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-05
        • 2012-07-29
        • 2021-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多