我有以下方法生成一组测试用例!
public IEnumerable<ResultsOfCallMyMethod> PrepareTestCases(param1)
{
foreach (string entry in entries)
{
yield return callMyMethod(param1);
}
}
如何将字符串类型的参数作为参数传递给我的PrepareTestCases()
方法?
有没有办法执行以下操作:
[Test, Category("Integration"), TestCaseSource("PrepareTestCases", param1)]
public void TestRun(ResultsOfCallMyMethod testData)
{
// do something!
}
答案 0 :(得分:16)
我已经在即将发布的最新版本的nunit(3.2)中对此进行了更改。
https://github.com/nunit/nunit/blob/4f54fd7e86f659682e7a538dfe5abee0c33aa8b4/CHANGES.txt
- TestCaseSourceAttribute现在可选地获取一系列参数 可以传递给源方法
现在可以做这样的事情
[Test, Category("Integration"), TestCaseSource(typeof(MyDataSources),"PrepareTestCases", new object[] {param1})]
public void TestRun(ResultsOfCallMyMethod testData)
{
// do something!
}
private class MyDataSources
{
public IEnumerable<ResultsOfCallMyMethod> PrepareTestCases(param1)
{
foreach (string entry in entries)
{
yield return callMyMethod(param1);
}
}
}
答案 1 :(得分:10)
如果查看TestCaseSourceAttribute doc,您将看到没有任何方法可以将参数传递给返回测试用例的方法。
生成测试用例的方法应该是无参数。
因此,假设您要避免代码重复,并且需要重用相同的方法来生成一些测试用例列表,我建议您执行以下操作:
编写实际生成测试用例集的参数化方法:
(PrepareTestCases()
已经这样做了)
public IEnumerable<ResultsOfCallMyMethod> PrepareTestCases(string param)
{
foreach (string entry in entries)
{
yield return CallMyMethod(param);
}
}
编写无参数包装器,调用测试用例生成器并在那里传递所需的参数:
public IEnumerable<ResultsOfCallMyMethod> PrepareTestCases_Param1()
{
return PrepareTestCases("param1");
}
public IEnumerable<ResultsOfCallMyMethod> PrepareTestCases_Param2()
{
return PrepareTestCases("param2");
}
编写测试方法并将paremeterless包装器作为测试用例源传递:
[TestCaseSource("PrepareTestCases_Param1")]
public void TestRun1(ResultsOfCallMyMethod data)
{
}
[TestCaseSource("PrepareTestCases_Param2")]
public void TestRun2(ResultsOfCallMyMethod data)
{
}
答案 2 :(得分:1)
在我的情况下,我想从CSV文件加载数据,但我无法将文件名传递给“数据源”。 经过一番挣扎后,我来到了这个两分钱的解决方案。
起初我继承了TestCaseSourceAttirbute
/// <summary>
/// FactoryAttribute indicates the source to be used to provide test cases for a test method.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class TestCaseCsvAttribute : TestCaseSourceAttribute
{
public TestCaseCsvAttribute(Type mapped, Type config) : base(typeof(TestCsvReader<,>).MakeGenericType(mapped, config), "Data")
{ }
}
然后我创建了数据层,在我的例子中是一个CSV读取器。
/// <summary>
/// Test data provider
/// </summary>
/// <typeparam name="T">Type to return in enumerable</typeparam>
/// <typeparam name="C">Configuration type that provide Filenames</typeparam>
public sealed class TestCsvReader<T, C>
{
/// <summary>
/// Initializes a new instance of the <see cref="TestCsvReader{T, C}"/> class.
/// </summary>
public TestCsvReader()
{
this.Config = (C)Activator.CreateInstance<C>();
}
/// <summary>
/// Gets or sets the configuration.
/// </summary>
/// <value>
/// The configuration.
/// </value>
private C Config { get; set; }
/// <summary>
/// Gets the filename.
/// </summary>
/// <value>
/// The filename.
/// </value>
/// <exception cref="System.Exception">
/// </exception>
private string Filename
{
get
{
try
{
string result = Convert.ToString(typeof(C).GetProperty(string.Format("{0}Filename", typeof(T).Name)).GetValue(this.Config));
if (!File.Exists(result))
throw new Exception(string.Format("Unable to find file '{0}' specified in property '{1}Filename' in class '{1}'", result, typeof(C).Name));
return result;
}
catch
{
throw new Exception(string.Format("Unable to find property '{0}Filename' in class '{1}'", typeof(T).Name, typeof(C).Name));
}
}
}
/// <summary>
/// Yields values from source
/// </summary>
/// <returns></returns>
public IEnumerable Data()
{
string file = this.Filename;
T[] result = null;
using (StreamReader reader = File.OpenText(file))
{
//TODO: do it here your magic
}
yield return new TestCaseData(result);
}
}
然后我创建了一个类,其唯一的范围包含文件路径的属性。有关该属性的名称约定,即ClassTypeName +“Filename”。
public class Configurations
{
public string ConflictDataFilename
{
get
{
return @"C:\test.csv";
}
}
}
此时只需相应地修饰测试,使用要映射到数据的类的类型和包含文件路径的类。
[Test(Description="Try this one")]
[TestCaseCsv(typeof(ClassMappedToData), typeof(Configurations))]
public void Infinite(ClassMappedToData[] data)
{
}
希望这会有所帮助。