Skip to content

Commit 33a7ad8

Browse files
committed
Optimized test assembly discovery (#135 #168)
1 parent ef0a4c9 commit 33a7ad8

File tree

1 file changed

+60
-75
lines changed

1 file changed

+60
-75
lines changed

src/MyTested.AspNetCore.Mvc.Abstractions/Internal/Application/TestApplication.cs

Lines changed: 60 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,12 @@ public static class TestApplication
4747

4848
private static bool initialiazed;
4949

50-
private static string testAssemblyName;
5150
private static IConfigurationBuilder configurationBuilder;
5251
private static TestConfiguration configuration;
5352

5453
private static IHostingEnvironment environment;
5554

5655
private static Type startupType;
57-
private static string startupAssemblyName;
5856

5957
private static volatile IServiceProvider serviceProvider;
6058
private static volatile IServiceProvider routingServiceProvider;
@@ -70,11 +68,7 @@ static TestApplication()
7068
RoutingServiceRegistrationPlugins = new HashSet<IRoutingServiceRegistrationPlugin>();
7169
InitializationPlugins = new HashSet<IInitializationPlugin>();
7270

73-
#if NET451
7471
FindTestAssembly();
75-
#endif
76-
77-
FindTestAssemblyName();
7872
}
7973

8074
public static IServiceProvider Services
@@ -142,19 +136,6 @@ internal static Type StartupType
142136

143137
internal static Action<IRouteBuilder> AdditionalRouting { get; set; }
144138

145-
internal static string StartupAssemblyName
146-
{
147-
get
148-
{
149-
if (string.IsNullOrWhiteSpace(startupAssemblyName))
150-
{
151-
startupAssemblyName = StartupType?.GetTypeInfo().Assembly.GetName().Name;
152-
}
153-
154-
return startupAssemblyName;
155-
}
156-
}
157-
158139
internal static IHostingEnvironment Environment
159140
{
160141
get
@@ -170,10 +151,8 @@ internal static IHostingEnvironment Environment
170151

171152
internal static string ApplicationName
172153
=> Configuration().General().ApplicationName()
173-
?? TestAssembly?.GetName().Name
174-
?? StartupAssemblyName
175-
?? PlatformServices.Default.Application.ApplicationName;
176-
154+
?? TestAssembly.GetName().Name;
155+
177156
public static TestConfiguration Configuration()
178157
{
179158
if (configuration == null || AdditionalConfiguration != null)
@@ -224,20 +203,7 @@ public static void TryInitialize()
224203
}
225204

226205
internal static DependencyContext LoadDependencyContext()
227-
{
228-
DependencyContext dependencyContext = null;
229-
if (TestAssembly != null)
230-
{
231-
dependencyContext = DependencyContext.Load(TestAssembly);
232-
}
233-
234-
if (dependencyContext == null)
235-
{
236-
dependencyContext = DependencyContext.Default;
237-
}
238-
239-
return dependencyContext;
240-
}
206+
=> DependencyContext.Load(TestAssembly) ?? DependencyContext.Default;
241207

242208
internal static void LoadPlugins(DependencyContext dependencyContext)
243209
{
@@ -296,23 +262,25 @@ internal static void LoadPlugins(DependencyContext dependencyContext)
296262

297263
internal static Type TryFindDefaultStartupType()
298264
{
299-
var applicationAssembly = TestAssembly ?? Assembly.Load(new AssemblyName(testAssemblyName));
265+
EnsureTestAssembly();
300266

301267
var defaultStartupType = Configuration().General().StartupType() ?? $"{Environment.EnvironmentName}Startup";
302268

303269
// check root of the test project
304270
var startup =
305-
applicationAssembly.GetType(defaultStartupType) ??
306-
applicationAssembly.GetType($"{applicationAssembly.GetName().Name}.{defaultStartupType}");
271+
TestAssembly.GetType(defaultStartupType) ??
272+
TestAssembly.GetType($"{TestAssembly.GetName().Name}.{defaultStartupType}");
307273

308274
return startup;
309275
}
310276

311277
private static void Initialize()
312278
{
279+
EnsureTestAssembly();
280+
313281
if (StartupType == null && !Configuration().General().NoStartup())
314282
{
315-
throw new InvalidOperationException($"The test configuration ('testconfig.json' file by default) contained 'false' value for the 'General.NoStartup' option but a Startup class was not provided. Either add {Environment.EnvironmentName}Startup class to the root of the test project or set it by calling 'StartsFrom<TStartup>(). Additionally, if you do not want to use a global test application for all test cases in this project, you may change the test configuration option to 'true'.");
283+
throw new InvalidOperationException($"The test configuration ('testconfig.json' file by default) contained 'false' value for the 'General.NoStartup' option but a Startup class was not provided. Either add {Environment.EnvironmentName}Startup class to the root of the test project or set it by calling 'StartsFrom<TStartup>()'. Additionally, if you do not want to use a global test application for all test cases in this project, you may change the test configuration option to 'true'.");
316284
}
317285

318286
PrepareLicensing();
@@ -328,28 +296,16 @@ private static void Initialize()
328296

329297
initialiazed = true;
330298
}
331-
332-
private static void FindTestAssemblyName()
333-
{
334-
testAssemblyName = Configuration().General().TestAssemblyName()
335-
?? TestAssembly?.GetName().Name
336-
?? DependencyContext
337-
.Default
338-
.GetDefaultAssemblyNames()
339-
.First()
340-
.Name;
341-
}
342299

343300
private static void PrepareLicensing()
344301
{
345-
TestCounter.SetLicenseData(
346-
Configuration().Licenses(),
347-
DateTime.ParseExact(ReleaseDate, "yyyy-MM-dd", CultureInfo.InvariantCulture),
348-
TestAssembly?.GetName().Name ?? StartupAssemblyName ?? DependencyContext
349-
.Default
350-
.GetDefaultAssemblyNames()
351-
.First()
352-
.Name);
302+
if (TestAssembly != null)
303+
{
304+
TestCounter.SetLicenseData(
305+
Configuration().Licenses(),
306+
DateTime.ParseExact(ReleaseDate, "yyyy-MM-dd", CultureInfo.InvariantCulture),
307+
TestAssembly.GetName().Name);
308+
}
353309
}
354310

355311
private static IHostingEnvironment PrepareEnvironment()
@@ -561,28 +517,57 @@ private static void Reset()
561517
InitializationPlugins.Clear();
562518
LicenseValidator.ClearLicenseDetails();
563519
}
564-
565-
#if NET451
520+
566521
private static void FindTestAssembly()
567522
{
568-
var executingAssembly = Assembly.GetExecutingAssembly();
569-
570-
var stackTrace = new StackTrace(false);
571-
572-
foreach (var frame in stackTrace.GetFrames())
523+
var testAssemblyName = Configuration().General().TestAssemblyName();
524+
if (testAssemblyName != null)
525+
{
526+
TestAssembly = Assembly.Load(new AssemblyName(testAssemblyName));
527+
}
528+
else
573529
{
574-
var method = frame.GetMethod();
575-
var methodAssembly = method?.DeclaringType?.Assembly;
530+
#if NET451
531+
var executingAssembly = Assembly.GetExecutingAssembly();
532+
533+
var stackTrace = new StackTrace(false);
576534

577-
if (methodAssembly != null
578-
&& methodAssembly != executingAssembly
579-
&& !methodAssembly.FullName.StartsWith(TestFrameworkName))
535+
foreach (var frame in stackTrace.GetFrames())
580536
{
581-
TestAssembly = methodAssembly;
582-
return;
537+
var method = frame.GetMethod();
538+
var methodAssembly = method?.DeclaringType?.Assembly;
539+
540+
if (methodAssembly != null
541+
&& methodAssembly != executingAssembly
542+
&& !methodAssembly.FullName.StartsWith(TestFrameworkName))
543+
{
544+
TestAssembly = methodAssembly;
545+
break;
546+
}
583547
}
548+
#endif
549+
#if NETSTANDARD1_6
550+
var assemblyName = DependencyContext
551+
.Default
552+
.GetDefaultAssemblyNames()
553+
.First();
554+
555+
TestAssembly = Assembly.Load(assemblyName);
556+
#endif
557+
}
558+
}
559+
560+
private static void EnsureTestAssembly()
561+
{
562+
if (TestAssembly == null)
563+
{
564+
FindTestAssembly();
565+
}
566+
567+
if (TestAssembly == null)
568+
{
569+
throw new InvalidOperationException("Test assembly could not be loaded. You can specify it explicitly in the test configuration ('testconfig.json' file by default) by providing a value for the 'General.TestAssemblyName' option or set it by calling '.StartsFrom<TStartup>().WithTestAssembly(this)'.");
584570
}
585571
}
586-
#endif
587572
}
588573
}

0 commit comments

Comments
 (0)