C#单元测试设计问题:如何减少单元测试写入的冗余?

fj4*_*yan 7 .net c# nunit unit-testing

这是我的c#单元测试设计问题:

我有一个测试,我想在一些修改文件的代码上运行.我的测试将运行修改文件的代码,然后检查结果.到目前为止非常直接......

问题是,我有大约10个文件(很快就会更多)我想要运行相同的单元测试.当测试本身真的相同时,我不想为每个文件编写一个新的单元测试.

我可以编写一个查询文件夹中文件的测试,然后在每个文件上运行测试逻辑,但使用此方法只会报告整个文件集的一个通过/失败结果.

我喜欢创建某种动态系统,其中我放置在特定文件夹中的每个文件都通过相同的单元测试运行.因此,如果文件夹中有25个文件,则测试运行25次,单元测试结果报告运行了25个测试,并且每个测试都包含单独的通过/失败.

任何想法如何或如果这可以在ac#单元测试中完成?或者用nunit测试?

谢谢!我希望这不是一个重复的问题.我环顾四周,但找不到任何东西.

Jer*_*Gee 10

听起来您需要的是参数化测试用例:请参阅http://www.nunit.org/index.php?p=testCaseSource&r=2.5.

所以:

[TestFixture]
public class Tests
{
    static string[] FileNames = new string[] 
                    { "mary.txt", "mungo.txt", "midge.txt" };

    [Test, TestCaseSource("FileNames")]
    public void TestMethod(string fileName)
    {
        Assert.That(File.Exists(fileName));
    }
}
Run Code Online (Sandbox Code Playgroud)

[TestCaseSource]属性告诉NUnit从字符串数组中获取字符串参数的值.

但是,这种方法需要文件名的静态常量.如果您更愿意使用程序化方法从数据库中读取文件或类似的尝试工厂类,如下所示:

[TestFixture]
public class Tests
{
    [Test, TestCaseSource(typeof(FilenameFactory), "FileNames")]
    public bool FileCheck(string fileName)
    {
        return File.Exists(fileName);
    }
}

public class FilenameFactory
{
    public static IEnumerable FileNames
    {
        get
        {
            foreach (var filename in 
                   Directory.EnumerateFiles(Environment.CurrentDirectory))
            {
                yield return new TestCaseData(filename).Returns(true);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

TestCaseData类生成"测试案例",其具有可以通过一个连贯接口来设定期望.


man*_*lds 5

参数化测试(http://www.nunit.org/index.php?p=parameterizedTests&r=2.5)可能对您有用,具体取决于您的操作方式.

TestcaseAttribute您可以使用的示例或者也可以使用TestCaseSourceAttribute

[TestCase(12,3,4)]
[TestCase(12,2,6)]
[TestCase(12,4,3)]
public void DivideTest(int n, int d, int q)
{
  Assert.AreEqual( q, n / d );
}
Run Code Online (Sandbox Code Playgroud)

您可以获得编写和维护一个测试的优势,但结果适用于每种情况.


Cha*_*nya 3

另一种选择是使用 T4 模板根据目录中的文件数量动态生成测试。将此“.tt”文件添加到您的单元测试项目中。

现在,每当您在 Visual Studio 中按下“运行解决方案中的所有测试”按钮之前进行构建时,它都应该为目录中具有单元测试中的文件名的所有文件生成单元测试。然后你的测试运行应该有一个很好的列表,其中包含它测试的所有文件及其状态。

<#@ template debug="false" hostspecific="true" language="C#v3.5" #>
<#@ assembly name="System.Core.dll" #>
<#@ assembly name="System.Data.dll" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ output extension=".cs" #>
<#
            string inputDirectory = @"d:\temp";
            var files = System.IO.Directory.GetFiles(inputDirectory);
#>
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestProject1
{
    [TestClass]
    public class UnitTest1
    {
        <# foreach (string filePath in files) { #>
        [TestMethod]
        public void TestingFile_<#=System.IO.Path.GetFileNameWithoutExtension(filePath).Replace(' ','_').Replace('-','_')#>()
        {
        File currentFile = System.IO.File.Open(@"<#= filePath #>", FileMode.Open);
        // TODO: Put your standard test code here which will use the file you opened above
        }
        <# } #>
    }
}
Run Code Online (Sandbox Code Playgroud)