NUnit属性

6

我正在使用NUnit,并在我的某些测试上应用了类别属性:

[Category("FastTest")]

这些测试必须非常快地运行,不超过10秒钟。因此,我还用装饰器来优化它们的性能。

[Timeout(10000)]

现在的问题是:

每当我使用[Category("FastTest")]修饰一个方法时,如何使其自动被[Timeout(1000)]修饰?

5个回答

3
创建一个 Resharper 活动模板,当输入“catfast”时,该模板将同时输出两个属性。或者购买 PostSharp 并让它在所有标记为指定类别的方法上添加 AOP。

1
这两种解决方案都需要购买第三方工具,而你可以实现自己的属性。 - Richard Forrest
3
如果我已经具有所提及的第三方工具中的一个,我就不会实现自己的属性。在我看来,Visual Studio 是 Resharper 的插件,而不是相反的情况 :-) - Marius
2
我同意Marius的观点,Resharper物有所值(我真的很喜欢他说的方式),但如果您无法获得外部工具的预算,您也可以使用内置于Visual Studio中的代码片段来实现此功能。 - Mike Two
是的,除了Visual Studio可以不用ReSharper外,反过来不行。 - Richard Forrest

3
我认为这不是一个很好的想法。
  1. 类别属性用于分组测试,而不是设置测试期望。
  2. 其他开发人员如何知道“FastTest”组中的测试应该在10秒内运行?为什么不是2秒?或者100毫秒?
  3. 你将被固定超时时间限制。如何设置一个测试为2秒,另一个为10秒?
  4. 这样做不会节省太多时间。
当然可以使用AOP、反射等方法来实现。但最简单的方法是将所有快速测试分组到一个测试夹具中,并使用[Timeout]属性进行修饰。

如果这是一个大型企业/模块化应用程序,我不会把所有这些测试都放到同一个夹具中。我想根据它们的命名空间/项目位置将测试放在一起,而不是基于它们具有“需要快速运行”的共同属性。 - Marius
1
那么我更喜欢两个属性 - 类别和超时。因为测试需要多快并不明显。是10分钟、10秒还是10毫秒。 - Sergey Berezovskiy

0
创建一个自定义属性FastTest,它继承自TimeoutAttribute。然后该属性将实现自己的类别命名约定。像这样的东西应该可以工作。
public class FastTestAttribyte :TimeoutAttribute
{
    protected string categoryName;

    public FastTestAttribyte (int timeout):base(timeout)
   {
       categoryName = "FastTest";
   }

    public string Name { get return categoryName; }
}

编辑

如果您反编译属性,它将起作用,这就是它的作用。

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple=true, Inherited=true)]
public class CategoryAttribute : Attribute
{
    // Fields
    protected string categoryName;

    // Methods
    protected CategoryAttribute()
    {
        this.categoryName = base.GetType().Name;
        if (this.categoryName.EndsWith("Attribute"))
        {
            this.categoryName = this.categoryName.Substring(0, this.categoryName.Length - 9);
        }
    }

    public CategoryAttribute(string name)
    {
        this.categoryName = name.Trim();
    }

    // Properties
    public string Name
    {
        get
        {
            return this.categoryName;
        }
    }
}

我认为Nunit将使用反射来获取属性的名称。


3
但这个属性将只像TimeoutAttribute一样起作用,即使添加了这样的猫名字,我猜nunit UI也不会理解它必须使用Name作为类别......或者我错了?! - Davide Piras
1
NUnit如何知道您希望您的FastTestAttribyte充当CategoryAttribute?您已反编译了CategoryAttribute的代码,但尚未查看NUnit如何查看它。仅具有“名称”属性是不够的。 NUnit需要知道您打算将该属性表示为类别。它通过在方法或类上查找CategoryAttribute来实现这一点。 - Mike Two
@feans,这不是关于 NUnit 如何提取您的属性的 Name 属性。我怀疑 NUnit 甚至不会考虑查看您自己的属性,可能它有类似这样的代码:var categoryAttributes = testMethodInfo.GetCustomAttributes(typeof(CategoryAttribute)). 这样的代码永远不会找到您的属性。 - Snowbear
这是正确的,但你将用类别做什么呢?使用上面的自定义属性,TestResult xml 将输出一个名为 FastTest 的测试属性,使您能够进行自己的分类。 - Richard Forrest
@feanz - 我使用类别来选择要运行的测试,而不是解析输出。这并不意味着其他用途无效,但你的方法将无法充分利用 NUnit 中的类别功能。 - Mike Two

0

我理解你的意思/需求,但我认为这是不可能的。你是希望在添加一个属性时,IDE会自动添加另一个属性,或者让nUnit知道一个类别是什么,并为某些类别的测试应用特定的额外属性吗?

听起来像个好主意,但在这种情况下更像是nUnit配置,而不是纯粹的C#属性链接,我不知道是否存在。


0

Visual Studio 允许您创建 自定义代码片段,类似于 Marius 提到的 Resharper 模板,但不需要任何费用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接