forked from xunit/xunit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
XunitTestFrameworkDiscoverer.cs
133 lines (115 loc) · 6.67 KB
/
XunitTestFrameworkDiscoverer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Xunit.Abstractions;
namespace Xunit.Sdk
{
/// <summary>
/// The implementation of <see cref="ITestFrameworkDiscoverer"/> that supports discovery
/// of unit tests linked against xunit.core.dll, using xunit.execution.dll.
/// </summary>
public class XunitTestFrameworkDiscoverer : TestFrameworkDiscoverer
{
/// <summary>
/// Gets the display name of the xUnit.net v2 test framework.
/// </summary>
public static readonly string DisplayName = String.Format(CultureInfo.InvariantCulture, "xUnit.net {0}", typeof(XunitTestFrameworkDiscoverer).Assembly.GetName().Version);
readonly Dictionary<Type, IXunitTestCaseDiscoverer> discovererCache = new Dictionary<Type, IXunitTestCaseDiscoverer>();
/// <summary>
/// Initializes a new instance of the <see cref="XunitTestFrameworkDiscoverer"/> class.
/// </summary>
/// <param name="assemblyInfo">The test assembly.</param>
/// <param name="sourceProvider">The source information provider.</param>
public XunitTestFrameworkDiscoverer(IAssemblyInfo assemblyInfo, ISourceInformationProvider sourceProvider)
: this(assemblyInfo, sourceProvider, null, null) { }
/// <summary>
/// Initializes a new instance of the <see cref="XunitTestFrameworkDiscoverer"/> class.
/// </summary>
/// <param name="assemblyInfo">The test assembly.</param>
/// <param name="sourceProvider">The source information provider.</param>
/// <param name="collectionFactory">The test collection factory used to look up test collections.</param>
/// <param name="messageAggregator">The message aggregator to receive environmental warnings from.</param>
public XunitTestFrameworkDiscoverer(IAssemblyInfo assemblyInfo,
ISourceInformationProvider sourceProvider,
IXunitTestCollectionFactory collectionFactory,
IMessageAggregator messageAggregator)
: base(assemblyInfo, sourceProvider, messageAggregator)
{
var collectionBehaviorAttribute = assemblyInfo.GetCustomAttributes(typeof(CollectionBehaviorAttribute)).SingleOrDefault();
var disableParallelization = collectionBehaviorAttribute == null ? false : collectionBehaviorAttribute.GetNamedArgument<bool>("DisableTestParallelization");
TestCollectionFactory = collectionFactory ?? ExtensibilityPointFactory.GetXunitTestCollectionFactory(collectionBehaviorAttribute, AssemblyInfo);
TestFrameworkDisplayName = String.Format("{0} [{1}, {2}]",
DisplayName,
TestCollectionFactory.DisplayName,
disableParallelization ? "non-parallel" : "parallel");
}
/// <summary>
/// Gets the test collection factory that makes test collections.
/// </summary>
public IXunitTestCollectionFactory TestCollectionFactory { get; private set; }
/// <summary>
/// Finds the tests on a test method.
/// </summary>
/// <param name="testCollection">The test collection that the test method belongs to.</param>
/// <param name="type">The test class that the test method belongs to.</param>
/// <param name="method">The test method.</param>
/// <param name="includeSourceInformation">Set to <c>true</c> to indicate that source information should be included.</param>
/// <param name="messageBus">The message bus to report discovery messages to.</param>
/// <returns>Return <c>true</c> to continue test discovery, <c>false</c>, otherwise.</returns>
protected virtual bool FindTestsForMethod(ITestCollection testCollection, ITypeInfo type, IMethodInfo method, bool includeSourceInformation, IMessageBus messageBus)
{
var factAttribute = method.GetCustomAttributes(typeof(FactAttribute)).FirstOrDefault();
if (factAttribute == null)
return true;
var testCaseDiscovererAttribute = factAttribute.GetCustomAttributes(typeof(XunitTestCaseDiscovererAttribute)).FirstOrDefault();
if (testCaseDiscovererAttribute == null)
return true;
var args = testCaseDiscovererAttribute.GetConstructorArguments().Cast<string>().ToList();
var discovererType = Reflector.GetType(args[1], args[0]);
if (discovererType == null)
return true;
var discoverer = GetDiscoverer(discovererType);
if (discoverer == null)
return true;
foreach (var testCase in discoverer.Discover(testCollection, AssemblyInfo, type, method, factAttribute))
if (!ReportDiscoveredTestCase(testCase, includeSourceInformation, messageBus))
return false;
return true;
}
/// <inheritdoc/>
protected override bool FindTestsForType(ITypeInfo type, bool includeSourceInformation, IMessageBus messageBus)
{
foreach (var method in type.GetMethods(includePrivateMethods: true))
{
var testCollection = TestCollectionFactory.Get(method);
if (!FindTestsForMethod(testCollection, type, method, includeSourceInformation, messageBus))return false;
}
return true;
}
/// <summary>
/// Gets the test case discover instance for the given discoverer type. The instances are cached
/// and reused, since they should not be stateful.
/// </summary>
/// <param name="discovererType">The discoverer type.</param>
/// <returns>Returns the test case discoverer instance.</returns>
protected IXunitTestCaseDiscoverer GetDiscoverer(Type discovererType)
{
IXunitTestCaseDiscoverer result;
if (!discovererCache.TryGetValue(discovererType, out result))
{
try
{
result = ExtensibilityPointFactory.GetXunitTestCaseDiscoverer(discovererType);
}
catch (Exception ex)
{
result = null;
Aggregator.Add(new EnvironmentalWarning { Message = String.Format("Discoverer type '{0}' could not be created or does not implement IXunitTestCaseDiscoverer: {1}", discovererType.FullName, ex) });
}
discovererCache[discovererType] = result;
}
return result;
}
}
}