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

#1742 Improved the error reporting when the DefaultTestCaseDescriptorProvider fails. #3067

Open
wants to merge 1 commit into
base: v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Xunit.Abstractions;

namespace Xunit
Expand All @@ -10,11 +11,13 @@ namespace Xunit
public class DefaultTestCaseDescriptorProvider : ITestCaseDescriptorProvider
{
readonly ITestFrameworkDiscoverer discoverer;
readonly IMessageSink diagnosticMessageSink;

/// <summary/>
public DefaultTestCaseDescriptorProvider(ITestFrameworkDiscoverer discoverer)
public DefaultTestCaseDescriptorProvider(ITestFrameworkDiscoverer discoverer, IMessageSink diagnosticMessageSink)
{
this.discoverer = discoverer;
this.diagnosticMessageSink = diagnosticMessageSink;
}

/// <inheritdoc/>
Expand All @@ -24,26 +27,55 @@ public List<TestCaseDescriptor> GetTestCaseDescriptors(List<ITestCase> testCases

foreach (var testCase in testCases)
{
var serialization = includeSerialization && discoverer != null ? discoverer.Serialize(testCase) : null;
var sourceInformation = testCase.SourceInformation;
var testMethod = testCase.TestMethod;
var className = testMethod.TestClass.Class.Name;
var methodName = testMethod.Method.Name;

var displayName = $"{className}.{methodName}";
Dictionary<string, List<string>> traits = null;

try
{
var serialization = includeSerialization && discoverer != null ? discoverer.Serialize(testCase) : null;
displayName = testCase.DisplayName;
traits = testCase.Traits;

results.Add(new TestCaseDescriptor
{
ClassName = testMethod.TestClass.Class.Name,
DisplayName = testCase.DisplayName,
MethodName = testMethod.Method.Name,
ClassName = className,
DisplayName = displayName,
MethodName = methodName,
Serialization = serialization,
SkipReason = testCase.SkipReason,
SourceFileName = sourceInformation?.FileName,
SourceLineNumber = sourceInformation?.LineNumber,
Traits = testCase.Traits ?? new Dictionary<string, List<string>>(),
Traits = traits ?? new Dictionary<string, List<string>>(),
UniqueID = testCase.UniqueID
});
}
catch (Exception) { }
catch (Exception e)
{
diagnosticMessageSink.OnMessage(
new DiagnosticMessage(
"Creating the descriptor for '{0}' threw '{1}': {2}{3}{4}",
displayName,
e.GetType().FullName,
e.Message,
Environment.NewLine,
e.StackTrace
)
);

results.Add(new TestCaseDescriptor
{
ClassName = className,
DisplayName = displayName,
MethodName = methodName,
SkipReason = e.Message,
Traits = traits ?? new Dictionary<string, List<string>>(),
});
}
}

return results;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ void EnsureInitialized()
if (innerController == null)
{
innerController = CreateInnerController();
descriptorProvider = (innerController as ITestCaseDescriptorProvider) ?? new DefaultTestCaseDescriptorProvider(innerController);
descriptorProvider = (innerController as ITestCaseDescriptorProvider) ?? new DefaultTestCaseDescriptorProvider(innerController, diagnosticMessageSink);
bulkDeserializer = (innerController as ITestCaseBulkDeserializer) ?? new DefaultTestCaseBulkDeserializer(innerController);
toDispose.Push(innerController);
}
Expand Down
2 changes: 1 addition & 1 deletion src/xunit.runner.utility/Frameworks/v2/Xunit2Discoverer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public List<TestCaseDescriptor> GetTestCaseDescriptors(List<ITestCase> testCases
catch (TypeLoadException) { } // Only be willing to eat "Xunit.Sdk.TestCaseDescriptorFactory" doesn't exist
}

defaultTestCaseDescriptorProvider = new DefaultTestCaseDescriptorProvider(RemoteDiscoverer);
defaultTestCaseDescriptorProvider = new DefaultTestCaseDescriptorProvider(RemoteDiscoverer, DiagnosticMessageSink);
}

return defaultTestCaseDescriptorProvider.GetTestCaseDescriptors(testCases, includeSerialization);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;

public class DefaultTestCaseDescriptorProviderTests
{
Expand All @@ -14,7 +17,7 @@ public DefaultTestCaseDescriptorProviderTests()
discoverer = Substitute.For<ITestFrameworkDiscoverer>();
discoverer.Serialize(null).ReturnsForAnyArgs(callInfo => $"Serialization of test case ID '{callInfo.Arg<ITestCase>().UniqueID}'");

provider = new DefaultTestCaseDescriptorProvider(discoverer);
provider = new DefaultTestCaseDescriptorProvider(discoverer, new Xunit.NullMessageSink());
}

[Fact]
Expand Down Expand Up @@ -82,4 +85,15 @@ public void PopulatedTestCase()
}
);
}

[Fact]
public void ThrowingTestCase()
{
var testCase = Substitute.For<ITestCase>();
testCase.UniqueID.Throws(new ArgumentException("test exception"));
var results = provider.GetTestCaseDescriptors(new List<ITestCase> { testCase }, false);
var result = Assert.Single(results);

Assert.Equal("test exception", result.SkipReason);
}
}