这是我的c#单元测试设计问题:
我想在一些修改文件的代码上运行一个测试。我的测试将运行修改文件的代码,然后检查结果。到目前为止非常直接...
问题是,我有大约10个文件(很快就会更多)我想要运行相同的单元测试。当测试本身真的相同时,我不想为每个文件编写一个新的单元测试。
我可以编写一个查询文件夹中文件的测试,然后在每个文件上运行测试逻辑,但使用此方法只会报告整个文件集的一个通过/失败结果。
我想创建某种动态系统,其中我放置在特定文件夹中的每个文件都通过相同的单元测试运行。因此,如果文件夹中有25个文件,则测试运行25次,单元测试结果报告运行了25个测试,并且每个测试都包含单独的通过/失败。
有什么想法可以在c#单元测试中完成吗?或者用nunit测试?
谢谢!我希望这不是一个重复的问题。我环顾四周,但找不到任何东西。
答案 0 :(得分: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));
}
}
[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);
}
}
}
}
TestCaseData
类生成“测试用例”,其期望可以通过流畅的界面设置。
答案 1 :(得分: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 );
}
您可以获得编写和维护一个测试的优势,但结果适用于每种情况。
答案 2 :(得分: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
}
<# } #>
}
}
答案 3 :(得分:0)
首先,测试取决于外部资源,如磁盘上的文件,不是严格的单元测试(意见)。
您正在寻找的是数据驱动的测试方法,然后您应该寻找支持它的工具,例如MSTest或MBunit。 (点击链接获取更多信息)。
然后你可以这样做(使用MBunit):
[TestFixture]
public class MyTestFixture
{
[Test]
public void WordCounter([TextData(ResourcePath = "Data.txt")] string text)
{
var wordCounter = new WordCounter(text);
int count = wordCounter.Count("Firecrest");
Assert.AreEqual(4, count); // Should not include the plural form "Firecrests".
}
}