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

Friendly test names #466

Merged
merged 10 commits into from
Dec 17, 2019
6 changes: 5 additions & 1 deletion src/Adapter/MSTest.CoreAdapter/Discovery/TypeEnumerator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery
Expand Down Expand Up @@ -204,6 +204,10 @@ internal UnitTestElement GetTestFromMethod(MethodInfo method, bool isDeclaredInT
this.type,
warnings);

// get DisplayName from TestMethodAttribute
var testMethodAttribute = this.reflectHelper.GetAttribute<TestMethodAttribute>(method);
testElement.DisplayName = testMethodAttribute?.DisplayName ?? method.Name;

return testElement;
}
}
Expand Down
15 changes: 9 additions & 6 deletions src/Adapter/MSTest.CoreAdapter/Extensions/TestCaseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,22 @@ internal static UnitTestElement ToUnitTestElement(this TestCase testCase, string
var testClassName = testCase.GetPropertyValue(Constants.TestClassNameProperty) as string;
var declaringClassName = testCase.GetPropertyValue(Constants.DeclaringClassNameProperty) as string;

TestMethod testMethod = new TestMethod(testCase.DisplayName, testClassName, source, isAsync);
var parts = testCase.FullyQualifiedName.Split('.');
var name = parts[parts.Length - 1];
TestMethod testMethod = new TestMethod(name, testClassName, source, isAsync);

if (declaringClassName != null && declaringClassName != testClassName)
{
testMethod.DeclaringClassFullName = declaringClassName;
}

UnitTestElement testElement = new UnitTestElement(testMethod)
{
IsAsync = isAsync,
TestCategory = testCase.GetPropertyValue(Constants.TestCategoryProperty) as string[],
Priority = testCase.GetPropertyValue(Constants.PriorityProperty) as int?
};
{
IsAsync = isAsync,
TestCategory = testCase.GetPropertyValue(Constants.TestCategoryProperty) as string[],
Priority = testCase.GetPropertyValue(Constants.PriorityProperty) as int?,
DisplayName = testCase.DisplayName
};

return testElement;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ public UnitTestElement(TestMethod testMethod)
/// </summary>
public KeyValuePair<string, string>[] DeploymentItems { get; set; }

/// <summary>
/// Gets or sets the DisplayName
/// </summary>
public string DisplayName { get; set; }

/// <summary>
/// Gets or sets the compiler generated type name for async test method.
/// </summary>
Expand Down Expand Up @@ -110,7 +115,7 @@ internal TestCase ToTestCase()
this.TestMethod.Name);

TestCase testCase = new TestCase(fullName, TestAdapter.Constants.ExecutorUri, this.TestMethod.AssemblyName);
testCase.DisplayName = this.TestMethod.Name;
testCase.DisplayName = string.IsNullOrEmpty(this.DisplayName) ? this.TestMethod.Name : this.DisplayName;

testCase.SetPropertyValue(TestAdapter.Constants.TestClassNameProperty, this.TestMethod.FullClassName);

Expand Down
24 changes: 24 additions & 0 deletions src/TestFramework/MSTest.Core/Attributes/VSTestAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,30 @@ public virtual TestMethodAttribute GetTestMethodAttribute(TestMethodAttribute te
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class TestMethodAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="TestMethodAttribute"/> class.
/// </summary>
public TestMethodAttribute()
: this(null)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="TestMethodAttribute"/> class.
/// </summary>
/// <param name="displayName">
/// Message specifies reason for ignoring.
/// </param>
public TestMethodAttribute(string displayName)
{
this.DisplayName = displayName;
}

/// <summary>
/// Gets display Name for the Test Window
/// </summary>
public string DisplayName { get; private set; }

/// <summary>
/// Executes a test method.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Discovery
using TestCleanup = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute;
using TestInitialize = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute;
using TestMethod = FrameworkV1::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute;
using TestMethodV2 = FrameworkV2::Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute;
using UTF = FrameworkV2::Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
Expand Down Expand Up @@ -529,6 +530,32 @@ public void GetTestFromMethodShouldSetDeclaringAssemblyName()
Assert.AreEqual(otherAssemblyName, testElement.TestMethod.DeclaringAssemblyName);
}

[TestMethod]
public void GetTestFromMethodShouldSetDisplayNameToTestMethodNameIfDisplayNameIsNotPresent()
{
this.SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true);
TypeEnumerator typeEnumerator = this.GetTypeEnumeratorInstance(typeof(DisplayNameTestClass), "DummyAssemblyName");
var methodInfo = typeof(DisplayNameTestClass).GetMethod(nameof(DisplayNameTestClass.TestMethodWithoutDisplayName));

var testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, this.warnings);

Assert.IsNotNull(testElement);
Assert.AreEqual("TestMethodWithoutDisplayName", testElement.DisplayName);
}

[TestMethod]
public void GetTestFromMethodShouldSetDisplayNameFromAttribute()
{
this.SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true);
TypeEnumerator typeEnumerator = this.GetTypeEnumeratorInstance(typeof(DisplayNameTestClass), "DummyAssemblyName");
var methodInfo = typeof(DisplayNameTestClass).GetMethod(nameof(DisplayNameTestClass.TestMethodWithDisplayName));

var testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, this.warnings);

Assert.IsNotNull(testElement);
Assert.AreEqual("Test method display name.", testElement.DisplayName);
}

#endregion

#region private methods
Expand Down Expand Up @@ -601,5 +628,18 @@ public class DummySecondHidingTestClass : DummyOverridingTestClass
}
}

internal abstract class DisplayNameTestClass
{
[TestMethodV2]
public void TestMethodWithoutDisplayName()
{
}

[TestMethodV2("Test method display name.")]
public void TestMethodWithDisplayName()
{
}
}

#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public void ToUnitTestElementShouldReturnUnitTestElementWithFieldsSet()
Assert.AreEqual(true, resultUnitTestElement.IsAsync);
Assert.AreEqual(2, resultUnitTestElement.Priority);
Assert.AreEqual(testCategories, resultUnitTestElement.TestCategory);
Assert.AreEqual("DummyDisplayName", resultUnitTestElement.TestMethod.Name);
Assert.AreEqual("DummyDisplayName", resultUnitTestElement.DisplayName);
Assert.AreEqual("DummyMethod", resultUnitTestElement.TestMethod.Name);
Assert.AreEqual("DummyClassName", resultUnitTestElement.TestMethod.FullClassName);
Assert.AreEqual(true, resultUnitTestElement.TestMethod.IsAsync);
Assert.IsNull(resultUnitTestElement.TestMethod.DeclaringClassFullName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ public void ToTestCaseShouldSetDisplayName()
Assert.AreEqual("M", testCase.DisplayName);
}

[TestMethodV1]
public void ToTestCaseShouldSetDisplayNameIfPresent()
{
this.unitTestElement.DisplayName = "Display Name";
var testCase = this.unitTestElement.ToTestCase();

Assert.AreEqual("Display Name", testCase.DisplayName);
}

[TestMethodV1]
public void ToTestCaseShouldSetTestClassNameProperty()
{
Expand Down