Skip to content

Commit

Permalink
Merge pull request OpenCover#744 from sawilde/issue_742_nested_tests
Browse files Browse the repository at this point in the history
OpenCover#742 support nested test classes and methods
  • Loading branch information
sawilde committed Aug 19, 2017
2 parents 37b6e19 + bbe2d4c commit 4853d9c
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 137 deletions.
6 changes: 3 additions & 3 deletions main/OpenCover.Extensions/Strategy/TrackMSTestTestMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ namespace OpenCover.Extensions.Strategy
/// </summary>
public class TrackMSTestTestMethods : TrackedMethodStrategyBase
{
private const string MsTestStrategyName = "MSTestTest";
private const string MsTestAttributeName = "Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute";
private const string MSTestStrategyName = "MSTestTest";
private const string MSTestAttributeName = "Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute";

public TrackMSTestTestMethods()
: base(MsTestStrategyName, MsTestAttributeName)
: base(MSTestStrategyName, MSTestAttributeName)
{
}
}
Expand Down
30 changes: 15 additions & 15 deletions main/OpenCover.Extensions/Strategy/TrackXUnitTestMethods.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
using System.Collections.Generic;

namespace OpenCover.Extensions.Strategy
{
/// <summary>
/// Track xUnit test methods
/// </summary>
public class TrackXUnitTestMethods : TrackedMethodStrategyBase
namespace OpenCover.Extensions.Strategy
{
/// <summary>
/// Track xUnit test methods
/// </summary>
public class TrackXUnitTestMethods : TrackedMethodStrategyBase
{
private const string xUnitStrategyName = "xUnitTest";
private const string XUnitStrategyName = "xUnitTest";

private static readonly IList<string> TrackedAttributeTypeNames = new List<string>
{
"Xunit.FactAttribute",
"Xunit.TheoryAttribute",
private static readonly IList<string> TrackedAttributeTypeNames = new List<string>
{
"Xunit.FactAttribute",
"Xunit.TheoryAttribute",
};

public TrackXUnitTestMethods() : base(xUnitStrategyName, TrackedAttributeTypeNames)
{
}
}
public TrackXUnitTestMethods() : base(XUnitStrategyName, TrackedAttributeTypeNames)
{
}
}
}
45 changes: 31 additions & 14 deletions main/OpenCover.Extensions/Strategy/TrackedMethodStrategyBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Mono.Cecil;
using OpenCover.Framework.Model;
Expand All @@ -8,39 +9,55 @@ namespace OpenCover.Extensions.Strategy
{
public abstract class TrackedMethodStrategyBase : ITrackedMethodStrategy
{
private readonly ISet<string> acceptedAttributes;
private readonly ISet<string> _acceptedAttributes;

public string StrategyName { get; private set; }
public string StrategyName { get; }

protected TrackedMethodStrategyBase(string strategyName, IEnumerable<string> attributeNames)
{
StrategyName = strategyName;
acceptedAttributes = new HashSet<string>(attributeNames);
_acceptedAttributes = new HashSet<string>(attributeNames);
}

protected TrackedMethodStrategyBase(string strategyName, string attribute)
{
StrategyName = strategyName;
acceptedAttributes = new HashSet<string> { attribute };
_acceptedAttributes = new HashSet<string> { attribute };
}

protected IEnumerable<TrackedMethod> GetTrackedMethodsByAttribute(IEnumerable<TypeDefinition> typeDefinitions)
{
return (from typeDefinition in typeDefinitions
from methodDefinition in typeDefinition.Methods
from customAttribute in methodDefinition.CustomAttributes
where acceptedAttributes.Contains(customAttribute.AttributeType.FullName)
select new TrackedMethod
{
MetadataToken = methodDefinition.MetadataToken.ToInt32(),
FullName = methodDefinition.FullName,
Strategy = StrategyName
});
from methodDefinition in typeDefinition.Methods
from customAttribute in methodDefinition.CustomAttributes
where _acceptedAttributes.Contains(customAttribute.AttributeType.FullName)
select new TrackedMethod
{
MetadataToken = methodDefinition.MetadataToken.ToInt32(),
FullName = methodDefinition.FullName,
Strategy = StrategyName
});
}

public IEnumerable<TrackedMethod> GetTrackedMethods(IEnumerable<TypeDefinition> typeDefinitions)
{
return GetTrackedMethodsByAttribute(typeDefinitions);
var allTypes = GetAllTypes(typeDefinitions);

return GetTrackedMethodsByAttribute(allTypes);
}

private static IEnumerable<TypeDefinition> GetAllTypes(IEnumerable<TypeDefinition> typeDefinitions)
{
var types = new List<TypeDefinition>();
foreach (var typeDefinition in typeDefinitions)
{
types.Add(typeDefinition);
if (typeDefinition.HasNestedTypes)
{
types.AddRange(GetAllTypes(typeDefinition.NestedTypes));
}
}
return types;
}
}
}
150 changes: 81 additions & 69 deletions main/OpenCover.Test/Extensions/Strategy/TrackNUnitTestMethodsTests.cs
Original file line number Diff line number Diff line change
@@ -1,81 +1,93 @@
using System.Linq;
using NUnit.Framework;
using OpenCover.Extensions.Strategy;

namespace OpenCover.Test.Extensions.Strategy
{
[TestFixture]
public class TrackNUnitTestMethodsTests
{
private TrackNUnitTestMethods strategy;
private Mono.Cecil.AssemblyDefinition assemblyDefinition;

[SetUp]
public void SetUp()
{
strategy = new TrackNUnitTestMethods();
assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(typeof(TrackNUnitTestMethodsTests).Assembly.Location);
}

[Test]
public void Can_Identify_Methods()
{
// arrange

// act
var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types);

// assert
Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::ASingleTest()")));
}

[Test]
public void TestAttribute_Is_Recognized()
{
// arrange

// act
var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types);

// assert
Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::ASingleTestCase()")));
}


[Test]
public void TheoryAttribute_Is_Recognized()
{
// arrange

// act
var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types);

// assert
Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::TheoryTest(System.Double)")));
}

using System.Linq;
using NUnit.Framework;
using OpenCover.Extensions.Strategy;

namespace OpenCover.Test.Extensions.Strategy
{
[TestFixture]
public class TrackNUnitTestMethodsTests
{
private TrackNUnitTestMethods _strategy;
private Mono.Cecil.AssemblyDefinition _assemblyDefinition;

[SetUp]
public void SetUp()
{
_strategy = new TrackNUnitTestMethods();
_assemblyDefinition = Mono.Cecil.AssemblyDefinition.ReadAssembly(typeof(TrackNUnitTestMethodsTests).Assembly.Location);
}

[Test]
public void Can_Identify_Methods()
{
// arrange

// act
var methods = _strategy.GetTrackedMethods(_assemblyDefinition.MainModule.Types);

// assert
Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::ASingleTest()")));
}

[Test]
public void TestAttribute_Is_Recognized()
{
// arrange

// act
var methods = _strategy.GetTrackedMethods(_assemblyDefinition.MainModule.Types);

// assert
Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::ASingleTestCase()")));
}


[Test]
public void TheoryAttribute_Is_Recognized()
{
// arrange

// act
var methods = _strategy.GetTrackedMethods(_assemblyDefinition.MainModule.Types);

// assert
Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::TheoryTest(System.Double)")));
}

[Test]
public void TestCaseSourceAttribute_Is_Recognized()
{
// arrange

// act
var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types);
var methods = _strategy.GetTrackedMethods(_assemblyDefinition.MainModule.Types);

// assert
Assert.True(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::DivideTest(System.Int32,System.Int32,System.Int32)")));
}

[Test]
public void Repeat_Is_Not_Recognized()
{
// arrange

// act
var methods = strategy.GetTrackedMethods(assemblyDefinition.MainModule.Types);

// assert
Assert.False(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::RepeatWithoutTest()")));
}
}
[Test]
public void Repeat_Is_Not_Recognized()
{
// arrange

// act
var methods = _strategy.GetTrackedMethods(_assemblyDefinition.MainModule.Types);

// assert
Assert.False(methods.Any(x => x.FullName.EndsWith("SimpleNUnit::RepeatWithoutTest()")));
}

[Test]
public void Can_Identify_Methods_InNestedClasses()
{
// arrange

// act
var methods = _strategy.GetTrackedMethods(_assemblyDefinition.MainModule.Types);

// assert
Assert.True(methods.Any(x => x.FullName.EndsWith(".Samples.ComplexNUnit/InnerTests::InnerExecuteMethod()")));
}
}
}
1 change: 1 addition & 0 deletions main/OpenCover.Test/OpenCover.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@
<Compile Include="MoqFramework\UnityAutoMockContainerBaseTests.cs" />
<Compile Include="MoqFramework\UnityAutoMockContainerTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Samples\ComplexNUnit.cs" />
<Compile Include="Samples\Samples.cs" />
<Compile Include="Samples\SimpleMsTest.cs" />
<Compile Include="Samples\SimpleNUnit.cs" />
Expand Down
17 changes: 17 additions & 0 deletions main/OpenCover.Test/Samples/ComplexNUnit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using NUnit.Framework;

namespace OpenCover.Test.Samples
{
[TestFixture]
public class ComplexNUnit
{
[TestFixture]
public class InnerTests
{
[Test]
public void InnerExecuteMethod()
{
}
}
}
}
Loading

0 comments on commit 4853d9c

Please sign in to comment.