C# 集成测试(填写数据库的纯文本文件)

C# 集成测试(填写数据库的纯文本文件),c#,database,text,integration,C#,Database,Text,Integration,我们的团队在测试方面非常新。我们是第一次使用scrum。 在第一个sprint中,我们在gui上有一个按钮。按下按钮将导致将文本文件的内容转换到数据库(在新线程/任务中)。gui将显示任务已启动,并将轮询任务的状态 我们知道如何使用TDD方法进行单元测试。但是当我们完成时,我们必须进行集成测试 我们需要在集成测试中执行什么样的测试? 我们是否需要通过测试不同的文件来检查数据库中的所有内容是否正确填写? (即:关系、存储为varchar(xxx)的特定格式等) 如果是这样的话:这可能相当复杂,对吗

我们的团队在测试方面非常新。我们是第一次使用scrum。 在第一个sprint中,我们在gui上有一个按钮。按下按钮将导致将文本文件的内容转换到数据库(在新线程/任务中)。gui将显示任务已启动,并将轮询任务的状态

我们知道如何使用TDD方法进行单元测试。但是当我们完成时,我们必须进行集成测试

我们需要在集成测试中执行什么样的测试? 我们是否需要通过测试不同的文件来检查数据库中的所有内容是否正确填写? (即:关系、存储为varchar(xxx)的特定格式等)

如果是这样的话:这可能相当复杂,对吗?因为您没有1个或2个输入参数,但是您有一个完整的文件(我是说文件的内容!!!),它是可测试的变量。你可以对这个按钮进行数百次,甚至数千次的测试。最糟糕的是:大多数测试(即格式化)都已经在单元测试中测试过了

internet上的大多数示例都将更多类似gui的测试显示为集成测试(或者下面的示例是否为验收测试?) 使用正确的用户名和密码登录 -输入:姓名+密码 -预期输出:重定向到主页

使用不正确的用户名和/或密码登录 -输入:名称和密码(不正确)
-预期输出:警告(登录失败、用户名或密码不正确)

您的问题涵盖了尝试采用更好的测试和环境建设程序的许多方面。因此,首先让我们谈谈集成测试

对于集成测试,您在大多数情况下需要一个空数据库,因为您正在测试给定一组特定的现有数据,您可以查询该数据并获得所需的结果

让我们使用一个简单的例子,比如UserFinder类,您希望能够在系统中找到具有给定名称的用户,并获得一个可用的模型

public class UserFinder
{
    private SomeDbContext _dbContext;

    public UserFinder(SomeDbContext dbContext)
    { _dbContext = dbContext }

    public User FindUser(string name)
    { _dbContext.Find<User>(new FindUserByNameQuery(_dbContext, name)); }
}
公共类用户查找器
{
私有somedbcontextu dbContext;
公共用户查找器(SomeDbContext)
{{u dbContext=dbContext}
公共用户FindUser(字符串名称)
{u dbContext.Find(新的FindUserByNameQuery(_dbContext,name));}
}
在上面的例子中,虽然这是一个相当垃圾的类,但我们可以测试数据库中一个名为“Tester”的用户,当您调用FindUser(“Tester”)时,您应该返回该用户模型

因此,作为该测试的一部分,您需要首先在数据库中设置预期的用户,然后创建用户查找器,给它一个真实的数据库连接,然后使用名称“Tester”查询数据库,并证明您获得了该模型

public class UserFinder
{
    private SomeDbContext _dbContext;

    public UserFinder(SomeDbContext dbContext)
    { _dbContext = dbContext }

    public User FindUser(string name)
    { _dbContext.Find<User>(new FindUserByNameQuery(_dbContext, name)); }
}
通过这种方式,您可以在任何上下文(无论是IDE、构建脚本还是命令行)中运行该测试,您将获得一致的结果,因为您的测试是自包含的,它设置场景、运行测试并验证验收标准。然后,一旦测试完成,所有数据都应该被删除,关键是您只设置了给定测试所需的内容,并且通常只在该测试中设置


现在理想的情况是,由于集成测试和验收测试的运行速度比单元测试慢得多,所以您只想测试单元测试中未包含的内容,但同时您希望确保只测试逻辑,就像您可以使用NHibernate轻松创建上面的测试场景一样,您所要证明的是NHibernate是有效的,这不是您的目标。我们无法告诉您需要测试什么,因为我们不知道您的项目或您试图实现什么,但您应该对您的应用程序逻辑流程有一些了解,如果您看到流程中的任何点连接到数据库或文件系统,或者通过其他外部边界连接到具有业务逻辑的应用程序,那么您可能需要加入一个测试场景。

我想说,您需要严格限制您正在测试的内容。在业余时间,我正在做一个MVC4项目,以EF5为后端,使用存储库和数据服务。我尝试过模仿EntityFramework行为,但它太复杂了。一般来说,人们都认为模仿DB上下文是毫无意义的。微软也会在这方面进行测试,所以不用麻烦自己测试微软已经测试过的东西

在我的项目中,我已经为此设置了测试项目和测试数据库。但我不测试存储库,因为它们非常透明并且接近EF。我通过给数据服务提供真实的上下文和连接字符串到测试数据库来测试数据服务。 对于每个测试类,我都会删除数据库并重新创建结构。我正在为每个测试重新填充数据,所以测试总是针对相同的数据运行

这被认为是一个集成测试,因为在我访问数据库之前,这里我将经历几个层。在这些测试中,我发现了与DB中的关系可能存在的所有问题,以及与DbContext的其他问题

但是,就集成测试而言,我的控制器(和其他对象)是使用模拟依赖项进行测试的(我使用的是Moq)。 一旦我对UI有了进一步的了解,我可能会通过Selenium为web页面编写一些测试

以下是我的测试项目中的一些示例:

[TestFixture]
class ProjectDataServiceTest
{
    private ProjectDataService _projectDataService;
    private DatabaseSeeder _seeder;
    private SiteContext _context;

    [TestFixtureSetUp]
    public void FixtureSetUp()
    {

        _context = new SiteContext(); // connection string is taken from app.config file

        _seeder = new DatabaseSeeder(_context);
        _seeder.InitialiseDb();  // create database structure

        ProjectRepository projectRepository = new ProjectRepository(_context);

        _projectDataService = new ProjectDataService(projectRepository);

    }

    [SetUp]
    public void TestSetUp()
    {
        _seeder.SeedDatabase(); // put some test data from a script
    }

    [TearDown]
    public void TestTearDown()
    {
        _seeder.RemoveData(); // delete everything from all the tables
    }

    /**************** Tests are here! ********************/

    [Test]
    public void CheckDatabaseConnectivity()
    {
        Assert.Pass();
    }

    [Test]
    public void GetNoProjectsForUser()
    {   // should return no project for this user, as nothing is assigned
        var user = _seeder.Users[0];
        var projects = _projectDataService.GetUserProjects(user);

        Assert.IsEmpty(user.UserProjectRoles);
        Assert.IsEmpty(projects);
    }

    [Test]
    public void GetAllProjetsForUser()
    {
        var user = _seeder.Users[2];
        var projects = (List<Project>)_projectDataService.GetUserProjects(user);
        int count = user.UserProjectRoles.Count;

        Assert.AreEqual(count, projects.Count);

        Assert.False(projects.Contains(_seeder.Projects[0]));
    }
 }
[TestFixture]
类ProjectDataServiceTest
{
私有项目数据服务(ProjectDataService);;
专用数据库播种机;
私有站点上下文\u上下文;
[TestFixtureSetUp]
public void FixtureSetUp()
{
_context=new SiteContext();//连接字符串取自app.config文件
_seeder=新数据库seeder(_上下文);
_seeder.InitialiseDb();//创建数据库结构
ProjectRepository ProjectRepository=新的ProjectRepository(\u上下文);
_projectDataService=新的projectDataService(projectRepository);