2009-07-08 18 views
9

在较大的项目中,我的单元测试通常需要运行一些“虚拟”(样本)数据。一些默认的客户,用户等。我想知道你的设置是怎样的。如何将样本(虚拟)数据添加到单元测试中?

  1. 如何组织/维护这些数据?
  2. 你如何将它应用到你的单元测试(任何自动化工具)?
  3. 您确实需要测试数据吗?或者您认为它没用?

我目前的解决方案:

主数据的样本数据其中前者将可区分当系统进入生产(安装了第一次),而后者是我测试运行所需的典型用例(并且在开发过程中)。

我店所有这一切在一个Excel文件(因为它是如此该死的易维护),其中每个工作表中包含特定实体(例如用户,客户等),并标记主或样品。

我有2个测试案例,我(小姐)用来导入所需的数据:

  1. InitForDevelopment(创建模式,导入主数据,导入示例数据)
  2. InitForProduction(创建模式,导入主数据)

回答

12

我使用的存储库的图案和具有真实由所讨论的单元测试实例化的虚拟库,它提供了一个已知的数据集,它包括一个例子是内和超出范围的各种字段。

这意味着,我可以测试我的代码通过从测试单元提供实例化的储存库进行测试或在运行时产生存储库(经由依赖注入(城堡))不变。

我不知道这一个良好的网络参考,但我从Apress出版出版的史蒂芬·桑德森的专业ASP.NET MVC 1.0书中学到了很多。 MVC方法自然提供了让您的测试在较少依赖性下运行所需的关注点分离。

的基本要素是,你储存库实现了数据访问的接口,即同一个接口,然后通过您在测试项目中构建一个假的库来实现。

在我目前的项目中,我有这样的接口:

namespace myProject.Abstract 
{ 
    public interface ISeriesRepository 
    { 
     IQueryable<Series> Series { get; } 
    } 
} 

这是作为我的两个实时数据仓库(使用LINQ to SQL),也是一个假的存储库这样的:

namespace myProject.Tests.Respository 
{ 
    class FakeRepository : ISeriesRepository 
    { 
     private static IQueryable<Series> fakeSeries = new List<Series> { 
      new Series { id = 1, name = "Series1", openingDate = new DateTime(2001,1,1) }, 
      new Series { id = 2, name = "Series2", openingDate = new DateTime(2002,1,30), 
      ... 
      new Series { id = 10, name = "Series10", openingDate = new DateTime(2001,5,5) 
     }.AsQueryable(); 

     public IQueryable<Series> Series 
     { 
      get { return fakeSeries; } 
     } 
    } 
} 

然后,消耗数据的类将实例化,并将库引用传递给构造函数:

namespace myProject 
{ 
    public class SeriesProcessor 
    { 
     private ISeriesRepository seriesRepository; 

     public void SeriesProcessor(ISeriesRepository seriesRepository) 
     { 
      this.seriesRepository = seriesRepository; 
     } 

     public IQueryable<Series> GetCurrentSeries() 
     { 
      return from s in seriesRepository.Series 
        where s.openingDate.Date <= DateTime.Now.Date 
        select s; 
     } 
    } 
} 

然后在我的测试中,我可以这样来解决:

namespace myProject.Tests 
{ 
    [TestClass] 
    public class SeriesTests 
    { 
     [TestMethod] 
     public void Meaningful_Test_Name() 
     { 
      // Arrange 
      SeriesProcessor processor = new SeriesProcessor(new FakeRepository()); 

      // Act 
      IQueryable<Series> currentSeries = processor.GetCurrentSeries(); 

      // Assert 
      Assert.AreEqual(currentSeries.Count(), 10); 
     } 

    } 
} 

然后看CastleWindsor的控制方法反转为您直播的项目,让你的产品代码,通过依赖注入自动实例化的活动资料库。这应该让你更接近你需要的地方。

+0

听起来像一个有趣的方法,但不知何故,我不完全理解它。你有没有在网上提供这种方法的参考? – Michal 2009-07-09 03:02:59

1

在我们公司,我们会讨论几个星期和几个月以来的这些问题。

要遵循单元测试的指导原则:

每个测试必须是atomar,不允许相互关系(没有数据共享),这意味着,每一个tust必须在一开始,有自己的数据并在最后清除数据。

出的产品是如此复杂(5年的发展,在数据库中的100个表),这几乎是不可能在一个可以接受的方式,以保持这一点。

我们尝试了数据库脚本,创建和前/后测试(也有它称之为自动方法)删除数据。

我会说你是在用Excel文件的好方法。从我

理念,使其一点点好:

  • 如果你有你的软件谷歌为“NDBUnit”背后的数据库。这是一个插入和删除数据库中的数据进行单元测试的框架。
  • 如果你没有数据库,那么对于像excel这样的系统来说,XML可能更灵活一些。
1

没有直接回答这个问题,但限制的测试需要使用虚拟数据是使用一个嘲弄的框架来创建嘲笑的对象,你可以使用你有任何依赖性假冒行为的量的一种方式一类。

我发现,使用嘲笑的对象而不是一个特定的具体实现可以大大减少真实数据,您需要使用的模拟考试不处理你传递到他们的数据量。他们只是执行你想要的。

我还是相信你,如果你已经使用或了解嘲讽框架可能需要在很多情况下,这样的道歉虚拟数据。

1

只是要清楚,你需要单元测试(测试与其他模块没有隐含的依赖关系模块)和应用程序测试(应用程序的测试部件)之间者区分。对于前者,你需要一个模拟框架(我只熟悉Perl的,但我确定它们存在于Java/C#中)。一个好框架的标志就是能够运行一个正在运行的应用程序,记录所有的方法调用/返回,然后使用记录的数据模拟所选择的方法(例如,您未在此特定单元测试中测试的方法)。 对于良好的单元测试,您必须模拟每个外部依赖 - 例如,不需要调用文件系统,不需要调用DB或其他数据访问层,除非您正在测试的内容等...

对于后者,嘲笑框架是有用的,加上创建测试数据集的能力(可以为每个测试重置)。要为测试加载的数据可以驻留在任何可以从其加载的脱机存储中 - 用于Sybase DB数据的BCP文件,XML,您喜欢的任何动作。我们同时使用BCP和XML。

请注意,如果您的整体公司框架允许(或者说强制执行)“此表别名”API的真实数据库表名称,那么这种“将测试数据加载到数据库”测试显着更容易。这样,您可以让应用程序在测试过程中查看克隆的“测试”数据库表,而不是真正的数据库表,除此之外,还可以让数据库表从一个数据库移动到另一个数据库。

相关问题