繁体   English   中英

.net与nhibernate的集成测试

[英]Integration testing in .net with nhibernate

我一直在为我的最新项目进行一些诚实的TDD测试,并且很喜欢它,以前曾做过单元测试,但没有认真的TDD测试,我发现它很有帮助。

我的项目的一些背景:

  • ASP.Net前端-
  • NHibernate用于与SQL Server 2008 Express进行数据库交互
  • 用于DOmain逻辑和单元测试的C#4.0 DLL在NUnit中完成并通过重新共享器运行。
  • 运行NAnt构建脚本的Teamcity CI服务器。

我现在处于某种“ alpha”版本中,并且发现所有错误都是集成错误,主要是因为我的集成测试是对站点的手动使用,以及一些次要的自动化操作(我已停止运行)。 考虑到我对测试套件的严格培训,并且我想对其进行纠正,因此这非常差。

我的问题是,进行集成测试的最佳方法是什么,或者我可以阅读任何文章。 我知道在UI.ASP.NET Webforms中测试UI会很痛苦(将来会迁移到可测试性更高的框架,但一次只能一步)。 但是我想确保我与hibernate的交互已正确测试。

所以我需要一些有关集成测试的技巧

  • Nhibernate(缓存,会话等)-
  • 测试数据,我发现“ NDBUnit”是我应该使用什么来使数据保持良好状态? 与NHibernate兼容吗?
  • 我应该将数据库换成SQLite还是其他东西? 或者只是设置另一个仅包含测试数据的SQL Server数据库?
  • 如何使这些测试可维护? 我进行了一些集成测试,但是它们给我带来了麻烦,并发现自己避免了这些测试。 我认为这主要是由于我没有每次都设置一致的状态。

只是一些一般性的建议也是不错的,我已经阅读了Kent Beck的TDD示例和Roy Osherove的《单元测试的艺术》,它们对于单元测试/ tdd非常有用,但是我很想阅读更多有关集成测试和编写它们的策略(应该测试什么)等

关于数据库部分:
-您可以按照本文的思路直接使用它: 具有内置NHibernate支持的单元测试
-使用SQLite加速测试也非常有用。 只有在这种情况下,您才应该意识到您不再真正针对实际的生产配置。
-SQLite不支持SQL Server支持的所有功能。 本文显示了用于切换到SQLite的必要测试设置的代码示例-这非常简单明了。
-NDbUnit作为准备测试数据的一种机制也是一个不错的选择-只要您不希望在Db上进行频繁的模式更改(在这种情况下,维护所有相关的xml就需要大量工作文件...)。
关于ASP.NET部分:
-您可能会发现Selenium之类的工具对UI驱动的测试很有帮助。

HTH!
汤玛士

派对晚了一点,但这是我一段时间以来一直在做的事情。

我正在编写REST API,这些将由我们的移动应用程序使用。 移动应用程序也是用C#编写的,因此编写API包装程序(SDK)对我来说很有意义。

在进行集成测试时,我将使用SDK设置测试用例,以测试API的所有端点。 运行测试时,API在开发模式下在我的本地IIS上运行。 每次启动服务器时,都会擦除,重新创建我的dev数据库,并为所有表的数据填充种子 ,这给了我一些现实的情况。 我也不必担心测试更新/删除,因为它只需要重建服务器项目,NHibernate就会删除,创建和播种数据库。 如果需要,可以将其更改为每个请求。

在测试我的存储库时,了解NHibernate是否可以转换我的查询对我很重要,因此我的所有存储库测试都使用LocalDB,它是针对每个测试用例重新创建 这意味着每个测试用例都可以设置查询测试成功所需的种子数据。

另一件事,当用实际数据为数据库播种时,您还将免费测试外键设置。 另外,播种机正在使用您的域类,因此看起来也不错!

播种机的示例:

public void Seed(ISession s) 
{
  using(var tx = s.BeginTransaction() 
  {
    var account1 = new Account { FirstName = "Bob", LastName = "Smith" };
    var account2 = new Account { FirstName = "John", LastName = "Doe" };
    account1.AddFriend(account2); // manipulates a friends collection
    s.Save(account1);
  }
}

创建会话工厂时,应致电种子服务器。

重要提示:设置是通过IoC容器完成的。

简短的答案是:不要进行集成测试。

我们有以下设置:

  • 我们的单元测试尽可能少地进行测试。 我们仅测试业务代码的一个功能(不是直接测试方法,而是测试逻辑上的功能);

  • 为您的业务代码的每个功能编写一个单元测试;

  • 编写单元测试,以测试业务代码的不同功能之间的交互;

  • 确保这些测试涵盖所有内容。

这将为您提供涵盖所有内容的一组单元测试。

我们确实有集成测试,但是这些测试是在Word文档中编写的,通常只是原始规格。 质量保证人员会在代码交付时运行它们,并且在大多数情况下它会运行,因为我们已经测试了每一个小片段。

在InfoQ上,有一个很棒的演示文稿,解释了这种很好的工作方式: 集成测试是一个骗局

关于测试NHibernate的一件事。 我们已经应用了存储库模式 这是因为我们的NHibernate查询变得非常非常简单,例如:

public class NhRepository<T> : IRepository<T>
{
    public T Get(int id)
    {
        return GetSession().Get<T>(id);
    }
}

public interface IUserRepository : IRepository<User>
{
    IEnumerable<User> GetActiveUsers();
}

public class UserRepository : NhRepository<User>, IUserRepository
{
    public IEnumerable<User> GetActiveUsers()
    {
        return
            from user in GetSession().Users
            where user.IsActive
            return user;
    }
}

结合使用Windsor IoC容器,可以访问我们的数据。 此设置的作用是:

  1. 查询非常简单(无论如何,它们中的98%),并且我们没有对它们进行彻底的测试。 这听起来可能很奇怪,但是我们倾向于使用同行评审而不是任何其他机制来测试这些。

  2. 这些存储库很容易被嘲笑。 这意味着对于上述存储库,我们有一个模拟程序,它可以执行以下操作:

     var repositoryMock = mocks.StrictMock<IUserRepository>(); var activeUsers = new List<User>(); for (int i = 0; i < 10; i++) { var user = UserMocks.CreateUser(); user.IsActive = true; activeUsers.Add(user); } Expect.Call(repositoryMock.GetActiveUsers()).Return(activeUsers); 

    实际的代码更加简洁,但是您明白了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM