2009-04-17 84 views
1

我刚刚遇到了我的应用程序错误,可能会被抓了一些集成测试,所以我觉得它的时候我写了一些!集成测试 - 您测试什么级别以及如何设置?

我的问题涉及到这些测试的设置,以及在什么层的代码的运行对测试。

设置

考虑我应该有很多的集成测试,我不希望创建和删除测试数据库为每一个测试,这将是缓慢的epically(即使它的SqlLite IN-记忆之一)。我的想法是:

  1. 有一个测试数据库,其旁边坐到我的dev的分贝
  2. 测试之前,运行一些复位脚本会正确设置我的架构和插入任何必要的数据(没有测试的情况下具体)
  3. 简单地使用这个测试数据库就好像它的真实分贝。

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

我的会话当前包裹在UOW图案,以创建和销毁分别对begin_request和END_REQUEST(MVC Web应用程序)执行。我是否应该修改此测试以便与测试一起解决此问题?

测试

当谈到实际编写一些测试,我应该怎么办呢?

我应该从尽可能高的级别(我MVC控制器动作),或者从最低(库)测试。

如果我以最低的测试我必须手动硬盘所有数据的代码。这会使我的测试变得更易于修改代码,也不能代表运行时代码中会发生什么。如果我在最高的测试我跑我的所有IOCC设置,使依赖注入获得与整个事情的功能(再次,在每一个[设置]重复这一点?)

咩!我迷路了,有人指着我正确的方向!

感谢

回答

2

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

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

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

1

在我当前的MVC应用程序中,我发现它足以测试存储库和数据库之间的交互。更重要的是,这是为了消除NHibernate映射中的任何皱纹。一切(当我说出所有事情时,我夸大其词)都是单元测试。我确实从控制器一直到堆栈到数据库都有一些集成测试,并且这些测试使用IoC容器(StructureMap)来构建控制器和依赖关系,但是我发现这些测试实际上没有添加任何东西,而且它们相当因此我现在已经从“集成”测试中将它们移除了 - 我可能会找到一个理由让它们进入,但到目前为止我还没有。

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

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

然后使用()语句将每个运行的集成测试包装在System.Transactions.TransactionScope中,并且TransactionScope永远不会调用Complete(),因此每个测试都可以独立运行,并且结果可以在通过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实现 - 事务回滚到更高级别。