首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# NUnit TestCaseSource传递参数

C# NUnit TestCaseSource传递参数
EN

Stack Overflow用户
提问于 2015-02-19 18:06:21
回答 3查看 33.7K关注 0票数 16

我有以下方法来生成一组测试用例!

代码语言:javascript
复制
public IEnumerable<ResultsOfCallMyMethod> PrepareTestCases(param1)
{
    foreach (string entry in entries)
    {
        yield return callMyMethod(param1);
    }
}

如何将字符串类型的参数作为参数传递给PrepareTestCases()方法?

有没有办法做到以下几点:

代码语言:javascript
复制
[Test, Category("Integration"), TestCaseSource("PrepareTestCases", param1)]
public void TestRun(ResultsOfCallMyMethod testData)
{
    // do something!
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-21 01:02:27

如果您查看TestCaseSourceAttribute doc,您会发现没有任何方法可以将参数传递给返回测试用例的方法。

生成测试用例的方法应该是parameterless.

因此,假设您要避免代码重复,并且需要重用相同的方法来生成一些测试用例列表,我建议您执行以下操作:

实际生成测试用例集的

  1. 写参数化方法:

(PrepareTestCases()已经做到了)

公共IEnumerable PrepareTestCases(字符串参数){ foreach (条目中的字符串条目){ yield CallMyMethod(参数);}}

  • 编写无参数包装器,调用测试用例生成器并将所需参数传递到此处:

public IEnumerable PrepareTestCases_Param1() { return PrepareTestCases("param1");} public IEnumerable PrepareTestCases_Param2() { return PrepareTestCases("param2");}

  • 编写测试方法,并将无参数包装器作为测试用例源传递:

TestCaseSource("PrepareTestCases_Param1")公共空TestRun1(ResultsOfCallMyMethod data) {} TestCaseSource("PrepareTestCases_Param2")公共空TestRun2(ResultsOfCallMyMethod data) { }

票数 10
EN

Stack Overflow用户

发布于 2016-03-06 10:26:48

我已经在即将发布的最新版本的nunit (3.2)中对此进行了更改。

https://github.com/nunit/nunit/blob/4f54fd7e86f659682e7a538dfe5abee0c33aa8b4/CHANGES.txt

  • TestCaseSourceAttribute现在可以选择接受可以传递给源方法

的参数数组

现在可以做这样的事情了

代码语言:javascript
复制
[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);
    }
  }
}
票数 26
EN

Stack Overflow用户

发布于 2015-06-11 19:45:06

在我的例子中,我想从CSV文件加载数据,但我无法将文件名传递给“数据源”。经过一番努力之后,我得到了这个两美分的解决方案。

起初,我继承了TestCaseSourceAttirbute

代码语言:javascript
复制
/// <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阅读器。

代码语言:javascript
复制
    /// <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“。

代码语言:javascript
复制
public class Configurations
{
    public string ConflictDataFilename
    {
        get
        {
            return @"C:\test.csv";
        }
    }
}

此时,只需使用要映射到数据的类的类型和包含文件路径的类来装饰测试即可。

代码语言:javascript
复制
[Test(Description="Try this one")]
[TestCaseCsv(typeof(ClassMappedToData), typeof(Configurations))]
public void Infinite(ClassMappedToData[] data)
{
}

希望这能有所帮助。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28603507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档