如何检查项目是否为测试项目?(NUnit,MSTest,xUnit)

3
我想检查选定的项目(我有源代码)是否是以下任何一个测试框架的TestProject:NUnit、MSTest、xUnit。
对于MSTest,这很简单。我可以检查.csproj和标记。如果我在那里有{3AC096D0-A1C2-E12C-1390-A8335801FDAB},那么它就意味着是测试项目。
问题在于NUnit和xUnit。我可以检查.csproj中的引用来判断这些情况。如果我有nunit.framework或xunit,那么就显而易见了。但我想知道是否有不同的方法来识别测试项目。
您知道识别测试项目的其他方式吗?

@Krzystof:您对更新的解决方案满意吗? - Dariusz Woźniak
是的,它运行得很好。感谢您的帮助。 - Krzysztof Madej
3个回答

5

其中一种方法是检查程序集是否包含测试方法。 测试方法的属性如下:

  • NUnit:[Test]
  • MSTest:[TestMethod]
  • xUnit.net:[Fact]

遍历程序集并检查程序集是否包含具有测试方法的类。 例如代码:

bool IsAssemblyWithTests(Assembly assembly)
{
    var testMethodTypes = new[]
    {
        typeof(Xunit.FactAttribute),
        typeof(NUnit.Framework.TestAttribute),
        typeof(Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute)
    };

    foreach (var type in assembly.GetTypes())
    {
        if (HasAttribute(type, testMethodTypes)) return true;
    }
    return false;
}

bool HasAttribute(Type type, IEnumerable<Type> testMethodTypes)
{
    foreach (Type testMethodType in testMethodTypes)
    {
        if (type.GetMethods().Any(x => x.GetCustomAttributes(testMethodType, true).Any())) return true;
    }

    return false;
}

您还可以添加更多的假设:
  • 检查类是否包含 TestFixture 方法,
  • 检查类/测试方法是否为公共的。

编辑:

如果您需要使用 C# 解析器,则可以使用以下 NRefactory 代码示例检查 .cs 文件中是否包含具有测试的类:

string[] testAttributes = new[]
    {
        "TestMethod", "TestMethodAttribute", // MSTest
        "Fact", "FactAttribute", // Xunit
        "Test", "TestAttribute", // NUnit
    };

bool ContainsTests(IEnumerable<TypeDeclaration> typeDeclarations)
{
    foreach (TypeDeclaration typeDeclaration in typeDeclarations)
    {
        foreach (EntityDeclaration method in typeDeclaration.Members.Where(x => x.EntityType == EntityType.Method))
        {
            foreach (AttributeSection attributeSection in method.Attributes)
            {
                foreach (Attribute atrribute in attributeSection.Attributes)
                {
                    var typeStr = atrribute.Type.ToString();
                    if (testAttributes.Contains(typeStr)) return true;
                }
            }
        }
    }

    return false;
}

NRefactory .cs文件解析示例:

var stream = new StreamReader("Class1.cs").ReadToEnd();
var syntaxTree = new CSharpParser().Parse(stream);
IEnumerable<TypeDeclaration> classes = syntaxTree.DescendantsAndSelf.OfType<TypeDeclaration>();

它对于编译项目非常有效,但我想避免编译。我可以编译,但这会使我的应用程序更耗时。我正在使用NRefactory,并且也许添加你上面提到的功能将是一个好方法。谢谢。 - Krzysztof Madej
@Krzysztof:添加了NRefactory示例。 - Dariusz Woźniak

1
我会寻找每个框架所代表的属性的用法,以确定它们各自的属性。使用反射来查找具有适当属性类型(例如Test/TestFixture)的类/方法。这个回答中有一个示例,您可以修改以满足您的需求:获取带有自定义属性的程序集中的所有类型

0

检查 *.csproj 中用于测试的特定 NuGet 引用。


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