2

我们的解决方案有两个不同的数据库提供程序,它们都位于不同的项目中。它们都继承了IDbProvider位于我们核心项目中的共同点。

namespace OurApp.Data
{
    public interface IDbProvider
    {
       // truncated
    }
}
namespace OurApp.Data.SqlServer
{
    public class DbProvider : IDbProvider {}
}
namespace OurApp.Data.Sqlite
{
    public class DbProvider : IDbProvider {}
}

数据库的功能必须相同,并且我们已经进行了针对SqlServer.DbProvider.

目前,所有 RepositoryTests 都继承自一个基类。

public abstract class RepositoryTestsBase
{
    protected IDbConnectionProvider Connection;
    protected IDbProvider DbProvider;

    [SetUp]
    public void Setup()
    {
        // Need to create a new connection to the server and make sure there is no database
        ConnectionStringSettings dbConnection = ConfigurationManager.ConnectionStrings["databaseConnection"];
        string testDatabaseName = ConfigurationManager.AppSettings["databaseName"];

        Connection = new DbConnectionProvider(dbConnection.ConnectionString, dbConnection.ProviderName);
        DbProvider = new DbProvider(Connection, testDatabaseName);
    }

我真的很讨厌不得不CTRL+ C/ CTRL+V 我所有的集成测试只是为了更改 DbProvider。

有没有一种方法可以运行所有集成测试两次,同时为每次运行注入不同的 DbProvider?我希望能够(显然)在我们的 Powershell 版本中执行此操作,但也可以在 IDE 中执行此操作。

我最初的想法是创建两个公共方法和一个私有方法,注入适当的数据库提供程序。

[Test]
public void ShouldDoStuff_SQLServer() {
    var dbProvider = sqlserver.DbProvider;
    ShouldDoStuff(dbprovider);
}

[Test]
public void ShouldDoStuff_Sqlite() {
    var dbProvider = sqlite.DbProvider;
    ShouldDoStuff(dbprovider);
}

private void ShouldDoStuff (IDbProvider dbprovider){
    // Assert
}
4

3 回答 3

5

一种解决方案可能是使用参数化测试。这个想法是您的测试每次运行都会传递不同的数据,因此允许您运行两次测试,一次针对每个数据库。

看看http://www.nunit.org/index.php?p=testCaseSource&r=2.6.2看看它是否适合您的需求。

在您的情况下,您可能会遇到以下情况:

static IDbProvider[] DbProviders = new IDbProvider[] 
{
    sqlserver.DbProvider,  
    sqlite.DbProvider
};

[Test, TestCaseSource("DbProviders")]
public void TestMethod(IDbProvider dbProvider)
{
    ShouldDoStuff(dbprovider);
} 

或者,要针对两个提供程序运行类中的所有测试,请尝试以下操作:

[TestFixture(0)]
[TestFixture(1)]
public class RepositoryTests
{
    private IDbProvider _provider;

    public IDbProvider(int index)
    {
        _provider = IDbProvider[index];
    }


    static IDbProvider[] DbProviders = new IDbProvider[] 
    {
        sqlserver.DbProvider,  
        sqlite.DbProvider
    };

    [Test]
    public void TestMethod(IDbProvider dbProvider)
    {
        ShouldDoStuff(_provider);
    }
}
于 2013-10-15T16:31:20.120 回答
2

您可以将数据驱动测试与价值源结合使用,如下所示:

public IEnumerable Providers()
{
    yield return new OurApp.Data.SqlServer.DbProvider();
    yield return new OurApp.Data.Sqlite.DbProvider();
}

[Test]
public void MyTest([ValueSource("Providers")] IDbProvider provider)
{
    // Test code...
}

将为您从值源返回的每个对象调用一次测试方法。

请参阅此处的NUnit 文档 当然,您还需要在测试项目的配置文件中提供 db 配置内容。

HTH 托马斯

于 2013-10-15T16:39:31.887 回答
0

您可以按照以下方式进行操作:

[TestFixture]
public class RepositoryTests
{
    protected IDbConnectionProvider Connection_SQLServer;
    protected IDbConnectionProvider Connection_SQLLite;
    protected string testDatabaseName_SQLServer;
    protected string testDatabaseName_SQLLite;

    [SetUp]
    public void Setup()
    {
        // init both providers and db-names
    }

    public IEnumerable Providers()
    {
        yield return new SqlServer.DbProvider(testDatabaseName_SQLServer, Connection_SQLServer);
        yield return new Sqlite.DbProvider(testDatabaseName_SQLLite, Connection_SQLLite);
    }

    // Do tests
于 2013-10-15T18:07:27.613 回答