2015-09-04 180 views
0

自动化依赖注入我有,所有含有一定接口(每个组件不同)的一个实现组件的文件夹。我为该接口编写了一些单元测试,并希望自动执行在每个实现上运行接口测试的任务。在单元测试

我有我不喜欢工作的解决方案:在实际的测试类

  • 编写代码加载(大会)和实例化的实现,这些存储在列表中。

  • 编写的每个测试遍历实现的列表,运行其上的每个断言。

我想要什么,而不是是对一个实现运行所有测试,然后移动到下一个再次运行所有测试,等等。我的想法是找到一种方法来执行(编程):

  • 加载程序集并实例化实现 - 像以前一样,但不在测试类中。
  • 创建测试类的实例,注入下一执行。
  • 运行测试。
  • 继续下一个实现,重复该过程。

(我知道我可以在文件系统周围洗牌的文件 - 就像把一个装配在一个位置>运行,加载一个执行测试>替换下一个实现的程序集,然后重复的过程。不过,我想的东西减去原油,如果可能的话)。

我一直在寻找的NUnit测试的车手(一个捷径控制台等),但没有发现至今。有谁知道是否有一种方法可以通过编程控制来实现我想要使用nUnit或任何其他测试套件?或者也许还有另外一种方式可以解决这个问题,那将满足上面的“我想要的”标准吗?

+0

您可能想考虑使用'TestCaseSource'属性来提供您想要测试的类的类型/实例。你需要加载程序集等,但是NUnit会为你处理其余的管道工作。 http://www.nunit.org/index.php?p=testCaseSource&r=2.5.9 – forsvarir

+0

'TestCaseSource'是一个选项,我同意,但是不会达到_running每个测试的目标 - 一个实现,然后继续下一个实现,重复process_。由于没有得到一个很好的解决方案来实现'IAddin'和'ISuiteBuilder',我目前正在研究看起来很有前途的'SuiteAttribute'。 –

回答

0

我结束了使用NUnit的SuiteAttribute

这种方法涉及到创建“伞类”,比如:

namespace Validator { 

    public class AllTests { 

     [Suite] 
     public static IEnumerable Suite { 
      get { 
       var directory = @"[ImplementationAssembliesPath]"; 
       var suite = new ArrayList(); 

       // GetInstances is a method responsible for loading the 
       // assemblys and instantiating the implementations to be tested. 
       foreach (var instance in GetInstances(directory)) { 
        suite.Add(GetResolvedTest(instance)); 
       } 
       return suite; 
      } 
     } 

     // This part is crucial - this is where I get to inject the 
     // implementations to the test. 
     private static Object GetResolvedTest(ICalculator instance) { 
      return new CalculatorTests {Calculator = instance}; 
     } 

     [...] 

} 

注意,测试类有注入我想实现的属性。我选择属性注入是因为测试运行者通常不喜欢默认的构造函数。但是,我不得不从实际测试类中删除TestFixtureAttribute(这里省略),以免混淆控制台运行程序的运行。

然后我创建了一个简单的控制台应用程序与/fixture参数运行NUnit的控制台 - 亚军:

namespace TestRunner { 

    using System; 
    using NUnit.ConsoleRunner; 

    internal class Program { 

     private static void Main(String[] args) { 
      var testDllPath = @"[TestAssemblyPath]/Validator.dll"; 
      var processArgument = @"/process=Separate"; 
      var domainArgument = @"/domain=Multiple"; 
      var runtimeArgument = @"/framework=4.5"; 
      var shadowArgument = @"/noshadow"; 
      var fixtureArgument = String.Format(@"/fixture={0}", "[Namespace].AllTests"); 

      Runner.Main(new[] { 
       testDllPath, 
       processArgument, 
       domainArgument, 
       runtimeArgument, 
       shadowArgument, 
       fixtureArgument 
      }); 

      Console.ReadLine(); 
     } 

    } 

} 

我仍然有兴趣听到这个您的意见,并在替代解决方案。

-1

如果你想测试一组固定的,你不必做花哨的东西像移动组件或指示测试运行组件。

像正常类,您可以使用继承为单元测试类。我建议你创建一个抽象基类,为测试这个接口的实现做繁重的工作。对于接口的每个实现,您可以创建一个从基类继承的新类。

的基类可以是这样的:

public class BaseMyInterfaceImplementationTest 
{ 
    protected MyInterface ClassUnderTest; 

    //Add your tests here with the [Test] attribute: 
    [Test] 
    public void TestScenario1() 
    { 
     //do your test on ClassUnderTest 
    } 
} 

和派生类是这样的:

[TestFixture] 
public class Implementation1Tests : BaseMyInterfaceImplementationTest 
{ 
    [SetUp] 
    public void BaseTestInitialize() 
    { 
     ClassUnderTest = new Implementation1(); 
    } 
} 
+0

这对于为每个实现运行所有测试(从程序集来说,这不是一个固定的集合,而是需要在运行时加载)有何帮助? –

+0

@OskarLindberg你是对的,我提出的解决方案只有在你有一套固定的实现时才能工作。 –