How can I check if project is a Test Project? (NUnit, MSTest, xUnit)

mstest, nunit, testing, visual-studio, xunit.net

Solution

One of the way is to check if assembly contains test methods. Attributes for test methods are as following:

- NUnit: `[Test]`

- MSTest: `[TestMethod]`

- xUnit.net: `[Fact]`

Iterate over assemblies and check if assembly contains class with test methods. Example code:

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;
}

You can also add more assumptions:

- check if classes contains TestFixture method,

- check if classes / test methods are public.

EDIT:

If you need to use C# Parser, here is a sample of NRefactory code for checking if a .cs file contains classes with tests:

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;
}

Example of NRefactory .cs file parsing:

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

Problem

I want to check if selected project (I have source code) is a TestProject for one of the following framework: NUnit, MSTest, xUnit. For MSTest it is simple. I can check .csproj and tag. If I have there {3AC096D0-A1C2-E12C-1390-A8335801FDAB} than it means it is Test project. The problem are NUnit and xUnit. I can check for this cases references in .csproj. If I have nunit.framework or xunit it will be obvious. But I wondering if is possible to check this in diffrent way. Do you know different way to recognize test projects?

Original source

Related problems