Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NUnit3: change the way test name is created so that it doesn't change between discovery and execution #709

Merged
merged 1 commit into from Oct 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -62,8 +62,12 @@
<Compile Include="NoAutoPropertiesAttributeTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Scenario.cs" />
<Compile Include="TestNameStrategiesFixture.cs" />
<Compile Include="TestNameStrategiesTest.cs" />
<Compile Include="ThrowingStubFixture.cs" />
<Compile Include="TypeWithCustomizationAttributes.cs" />
<Compile Include="FixedNameTestMethodBuilderTest.cs" />
<Compile Include="VolatileNameTestMethodBuilderTest.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AutoFixture.NUnit3\AutoFixture.NUnit3.csproj">
Expand Down
22 changes: 22 additions & 0 deletions Src/AutoFixture.NUnit3.UnitTest/FixedNameTestMethodBuilderTest.cs
@@ -0,0 +1,22 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using System;

namespace Ploeh.AutoFixture.NUnit3.UnitTest
{
public class FixedNameTestMethodBuilderTest
{
[Test]
public void FixedNameTestMethodBuilderIsResilientToFactoryException()
{
// Fixture setup
var dummyMethod = new MethodWrapper(typeof(TestNameStrategiesFixture), nameof(TestNameStrategiesFixture.FixedNameDecoratedMethod));
var sut = new FixedNameTestMethodBuilder();
// Exercise system
var testMethod = sut.Build(dummyMethod, null, () => throw new Exception(), 0);
// Verify outcome
Assert.That(testMethod.Name, Is.EqualTo(nameof(TestNameStrategiesFixture.FixedNameDecoratedMethod)));
// Teardown
}
}
}
2 changes: 1 addition & 1 deletion Src/AutoFixture.NUnit3.UnitTest/Scenario.cs
Expand Up @@ -378,7 +378,7 @@ public void InlineAutoDataCanBeUsedWithFrozen(int p1, int p2, [Frozen]string p3,

[Theory, AutoData]
public void NoAutoPropertiesAttributeLeavesPropertiesUnset(
[NoAutoProperties]PropertyHolder<object> ph1,
[NoAutoProperties]PropertyHolder<object> ph1,
[NoAutoProperties]PropertyHolder<string> ph2,
[NoAutoProperties]PropertyHolder<int> ph3
)
Expand Down
68 changes: 68 additions & 0 deletions Src/AutoFixture.NUnit3.UnitTest/TestNameStrategiesFixture.cs
@@ -0,0 +1,68 @@
namespace Ploeh.AutoFixture.NUnit3.UnitTest
{
public class TestNameStrategiesFixture
{
private static IFixture CreateFixtureWithInjectedValues()
{
var result = new Fixture();
// Make so that fixed values will be returned
result.Inject(42);
result.Inject("foo");
return result;
}

public class AutoDataFixedNameAttribute : AutoDataAttribute
{
public AutoDataFixedNameAttribute()
{
TestMethodBuilder = new FixedNameTestMethodBuilder();
}
}

public class AutoDataVolatileNameAttribute : AutoDataAttribute
{
public AutoDataVolatileNameAttribute() : base(CreateFixtureWithInjectedValues())
{
TestMethodBuilder = new VolatileNameTestMethodBuilder();
}
}

public class InlineAutoDataFixedNameAttribute : InlineAutoDataAttribute
{
public InlineAutoDataFixedNameAttribute(params object[] arguments)
: base(arguments)
{
TestMethodBuilder = new FixedNameTestMethodBuilder();
}
}

public class InlineAutoDataVolatileNameAttribute : InlineAutoDataAttribute
{
public InlineAutoDataVolatileNameAttribute(params object[] arguments)
: base(CreateFixtureWithInjectedValues(), arguments)
{
TestMethodBuilder = new VolatileNameTestMethodBuilder();
}
}

[AutoDataFixedName]
public void FixedNameDecoratedMethod(int expectedNumber, MyClass sut)
{
}

[AutoDataVolatileName]
public void VolatileNameDecoratedMethod(int expectedNumber, string value)
{
}

[InlineAutoDataFixedName("alpha", "beta")]
public void InlineFixedNameDecoratedMethod(string p1, string p2, string p3)
{
}

[InlineAutoDataVolatileNameAttribute("alpha", "beta")]
public void InlineVolatileNameDecoratedMethod(string p1, string p2, string p3)
{
}
}
}
139 changes: 139 additions & 0 deletions Src/AutoFixture.NUnit3.UnitTest/TestNameStrategiesTest.cs
@@ -0,0 +1,139 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using System;
using System.Linq;
using static Ploeh.AutoFixture.NUnit3.UnitTest.TestNameStrategiesFixture;

namespace Ploeh.AutoFixture.NUnit3.UnitTest
{
public class TestNameStrategiesTest
{
[Test]
public void AutoDataAttributeUsesRealValueByDefault()
{
// Fixture setup
// Exercise system
var sut = new AutoDataAttribute();
// Verify outcome
Assert.That(sut.TestMethodBuilder,
Is.TypeOf<VolatileNameTestMethodBuilder>());
// Teardown
}

[Test]
public void InlineAutoDataAttributeUsesRealValueByDefault()
{
// Fixture setup
// Exercise system
var sut = new InlineAutoDataAttribute();
// Verify outcome
Assert.That(sut.TestMethodBuilder,
Is.TypeOf<VolatileNameTestMethodBuilder>());
// Teardown
}

[Test]
public void AutoDataUsesFixedValuesForTestName()
{
// Fixture setup
// Exercise system
var testMethod = GetTestMethod<AutoDataFixedNameAttribute>(nameof(TestNameStrategiesFixture.FixedNameDecoratedMethod));
// Verify outcome
Assert.That(testMethod.Name,
Is.EqualTo(@"FixedNameDecoratedMethod(auto<Int32>,auto<MyClass>)"));
// Teardown
}

[Test]
public void AutoDataFixedNameUsesFixedValuesForTestFullName()
{
// Fixture setup
// Exercise system
var testMethod = GetTestMethod<AutoDataFixedNameAttribute>(nameof(TestNameStrategiesFixture.FixedNameDecoratedMethod));
// Verify outcome
Assert.That(testMethod.FullName,
Is.EqualTo(@"Ploeh.AutoFixture.NUnit3.UnitTest.TestNameStrategiesFixture.FixedNameDecoratedMethod(auto<Int32>,auto<MyClass>)"));
// Teardown
}

[Test]
public void AutoDataVolatileNameUsesRealValuesForTestName()
{
// Fixture setup
// Exercise system
var testMethod = GetTestMethod<AutoDataVolatileNameAttribute>(nameof(TestNameStrategiesFixture.VolatileNameDecoratedMethod));
// Verify outcome
Assert.That(testMethod.Name,
Is.EqualTo(@"VolatileNameDecoratedMethod(42,""foo"")"));
// Teardown
}

[Test]
public void AutoDataVolatileNameUsesRealValuesForTestFullName()
{
// Fixture setup
// Exercise system
var testMethod = GetTestMethod<AutoDataVolatileNameAttribute>(nameof(TestNameStrategiesFixture.VolatileNameDecoratedMethod));
// Verify outcome
Assert.That(testMethod.FullName,
Is.EqualTo(@"Ploeh.AutoFixture.NUnit3.UnitTest.TestNameStrategiesFixture.VolatileNameDecoratedMethod(42,""foo"")"));
// Teardown
}

[Test]
public void InlineAutoDataUsesFixedValuesForTestName()
{
// Fixture setup
// Exercise system
var testMethod = GetTestMethod<InlineAutoDataFixedNameAttribute>(nameof(TestNameStrategiesFixture.InlineFixedNameDecoratedMethod));
// Verify outcome
Assert.That(testMethod.Name,
Is.EqualTo(@"InlineFixedNameDecoratedMethod(""alpha"",""beta"",auto<String>)"));
// Teardown
}

[Test]
public void InlineAutoDataFixedNameUsesFixedValuesForTestFullName()
{
// Fixture setup
// Exercise system
var testMethod = GetTestMethod<InlineAutoDataFixedNameAttribute>(nameof(TestNameStrategiesFixture.InlineFixedNameDecoratedMethod));
// Verify outcome
Assert.That(testMethod.FullName,
Is.EqualTo(@"Ploeh.AutoFixture.NUnit3.UnitTest.TestNameStrategiesFixture.InlineFixedNameDecoratedMethod(""alpha"",""beta"",auto<String>)"));
// Teardown
}

[Test]
public void InlineAutoDataVolatileNameUsesRealValuesForTestName()
{
// Fixture setup
// Exercise system
var testMethod = GetTestMethod<InlineAutoDataVolatileNameAttribute>(nameof(TestNameStrategiesFixture.InlineVolatileNameDecoratedMethod));
// Verify outcome
Assert.That(testMethod.Name,
Is.EqualTo(@"InlineVolatileNameDecoratedMethod(""alpha"",""beta"",""foo"")"));
// Teardown
}

[Test]
public void InlineAutoDataVolatileNameUsesRealValuesForFullName()
{
// Fixture setup
// Exercise system
var testMethod = GetTestMethod<InlineAutoDataVolatileNameAttribute>(nameof(TestNameStrategiesFixture.InlineVolatileNameDecoratedMethod));
// Verify outcome
Assert.That(testMethod.FullName,
Is.EqualTo(@"Ploeh.AutoFixture.NUnit3.UnitTest.TestNameStrategiesFixture.InlineVolatileNameDecoratedMethod(""alpha"",""beta"",""foo"")"));
// Teardown
}

private static TestMethod GetTestMethod<TAttribute>(string testName) where TAttribute : Attribute, NUnit.Framework.Interfaces.ITestBuilder
{
var method = new MethodWrapper(typeof(TestNameStrategiesFixture), testName);
var inlineAttribute = (TAttribute)Attribute.GetCustomAttribute(method.MethodInfo, typeof(TAttribute));
var testMethod = inlineAttribute.BuildFrom(method, null).Single();
return testMethod;
}
}
}
@@ -0,0 +1,22 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using System;

namespace Ploeh.AutoFixture.NUnit3.UnitTest
{
public class VolatileNameTestMethodBuilderTest
{
[Test]
public void VolatileNameTestMethodBuilderIsResilientToFactoryException()
{
// Fixture setup
var anyMethod = new MethodWrapper(typeof(TestNameStrategiesFixture), nameof(TestNameStrategiesFixture.VolatileNameDecoratedMethod));
var sut = new VolatileNameTestMethodBuilder();
// Exercise system
var testMethod = sut.Build(anyMethod, null, () => throw new Exception(), 0);
// Verify outcome
Assert.That(testMethod.Name, Is.EqualTo(nameof(TestNameStrategiesFixture.VolatileNameDecoratedMethod)));
// Teardown
}
}
}
37 changes: 16 additions & 21 deletions Src/AutoFixture.NUnit3/AutoDataAttribute.cs
Expand Up @@ -5,19 +5,31 @@
using NUnit.Framework.Internal;
using NUnit.Framework.Internal.Builders;
using Ploeh.AutoFixture.Kernel;
using System.Diagnostics.CodeAnalysis;

namespace Ploeh.AutoFixture.NUnit3
{
/// <summary>
/// This attribute uses AutoFixture to generate values for unit test parameters.
/// This implementation is based on TestCaseAttribute of NUnit3
/// </summary>
[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
Justification = "This attribute is the root of a potential attribute hierarchy.")]
[AttributeUsage(AttributeTargets.Method)]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is the root of a potential attribute hierarchy.")]
public class AutoDataAttribute : Attribute, ITestBuilder
{
private readonly IFixture _fixture;

private ITestMethodBuilder _testMethodBuilder = new VolatileNameTestMethodBuilder();
/// <summary>
/// Gets or sets the current <see cref="ITestMethodBuilder"/> strategy.
/// </summary>
public ITestMethodBuilder TestMethodBuilder
{
get => _testMethodBuilder;
set => _testMethodBuilder = value ?? throw new ArgumentNullException(nameof(value));
}

/// <summary>
/// Construct a <see cref="AutoDataAttribute"/>
/// </summary>
Expand Down Expand Up @@ -49,31 +61,14 @@ protected AutoDataAttribute(IFixture fixture)
/// <returns>One or more TestMethods</returns>
public IEnumerable<TestMethod> BuildFrom(IMethodInfo method, Test suite)
{
var test = new NUnitTestCaseBuilder().BuildTestMethod(method, suite, this.GetParametersForMethod(method));
var test = this.TestMethodBuilder.Build(method, suite, () => GetParameterValues(method).ToArray(), 0);

yield return test;
}

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method is always expected to return an instance of the TestCaseParameters class.")]
private TestCaseParameters GetParametersForMethod(IMethodInfo method)
{
try
{
var parameters = method.GetParameters();

var parameterValues = this.GetParameterValues(parameters);

return new TestCaseParameters(parameterValues.ToArray());
}
catch (Exception ex)
{
return new TestCaseParameters(ex);
}
}

private IEnumerable<object> GetParameterValues(IEnumerable<IParameterInfo> parameters)
private IEnumerable<object> GetParameterValues(IMethodInfo method)
{
return parameters.Select(Resolve);
return method.GetParameters().Select(Resolve);
}

private object Resolve(IParameterInfo parameterInfo)
Expand Down
3 changes: 3 additions & 0 deletions Src/AutoFixture.NUnit3/AutoFixture.NUnit3.csproj
Expand Up @@ -71,6 +71,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="FixedNameTestMethodBuilder.cs" />
<Compile Include="InlineAutoDataAttribute.cs" />
<Compile Include="AutoDataAttribute.cs" />
<Compile Include="CustomizeAttribute.cs" />
Expand All @@ -84,6 +85,8 @@
<Compile Include="ModestAttribute.cs" />
<Compile Include="NoAutoPropertiesAttribute.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VolatileNameTestMethodBuilder.cs" />
<Compile Include="ITestMethodBuilder.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AutoFixture\AutoFixture.csproj">
Expand Down