diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index 6cd0f3970b..ca75d26326 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -73,7 +73,7 @@ internal AssemblyEnumerationResult EnumerateAssembly(string assemblyFileName) Assembly assembly = PlatformServiceProvider.Instance.FileOperations.LoadAssembly(assemblyFileName, isReflectionOnly: false); - Type[] types = GetTypes(assembly, assemblyFileName, warnings); + Type?[] types = GetTypes(assembly, assemblyFileName, warnings); bool discoverInternals = ReflectHelper.GetDiscoverInternalsAttribute(assembly) != null; TestIdGenerationStrategy testIdGenerationStrategy = ReflectHelper.GetTestIdGenerationStrategy(assembly); @@ -103,7 +103,7 @@ internal AssemblyEnumerationResult EnumerateAssembly(string assemblyFileName) }, }; - foreach (Type type in types) + foreach (Type? type in types) { if (type == null) { @@ -125,7 +125,7 @@ internal AssemblyEnumerationResult EnumerateAssembly(string assemblyFileName) /// <param name="assemblyFileName">The file name of the assembly.</param> /// <param name="warningMessages">Contains warnings if any, that need to be passed back to the caller.</param> /// <returns>Gets the types defined in the provided assembly.</returns> - internal static Type[] GetTypes(Assembly assembly, string assemblyFileName, ICollection<string>? warningMessages) + internal static Type?[] GetTypes(Assembly assembly, string assemblyFileName, ICollection<string>? warningMessages) { try { @@ -136,7 +136,7 @@ internal static Type[] GetTypes(Assembly assembly, string assemblyFileName, ICol PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning($"MSTestExecutor.TryGetTests: {Resource.TestAssembly_AssemblyDiscoveryFailure}", assemblyFileName, ex); PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning(Resource.ExceptionsThrown); - if (ex.LoaderExceptions != null) + if (ex.LoaderExceptions.Any()) { // If not able to load all type, log a warning and continue with loaded types. string message = string.Format(CultureInfo.CurrentCulture, Resource.TypeLoadFailed, assemblyFileName, GetLoadExceptionDetails(ex)); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 55f1cc63c6..c9b19a99c6 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -384,14 +384,19 @@ private TestAssemblyInfo GetAssemblyInfo(Assembly assembly) { var assemblyInfo = new TestAssemblyInfo(assembly); - Type[] types = AssemblyEnumerator.GetTypes(assembly, assembly.FullName!, null); + Type?[] types = AssemblyEnumerator.GetTypes(assembly, assembly.FullName!, null); - foreach (Type t in types) + foreach (Type? type in types) { + if (type == null) + { + continue; + } + try { // Only examine classes which are TestClass or derives from TestClass attribute - if (!@this._reflectionHelper.IsDerivedAttributeDefined<TestClassAttribute>(t, inherit: false)) + if (!@this._reflectionHelper.IsDerivedAttributeDefined<TestClassAttribute>(type, inherit: false)) { continue; } @@ -401,14 +406,14 @@ private TestAssemblyInfo GetAssemblyInfo(Assembly assembly) // If we fail to discover type from an assembly, then do not abort. Pick the next type. PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning( "TypeCache: Exception occurred while checking whether type {0} is a test class or not. {1}", - t.FullName, + type.FullName, ex); continue; } // Enumerate through all methods and identify the Assembly Init and cleanup methods. - foreach (MethodInfo methodInfo in PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredMethods(t)) + foreach (MethodInfo methodInfo in PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredMethods(type)) { if (@this.IsAssemblyOrClassInitializeMethod<AssemblyInitializeAttribute>(methodInfo)) { diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs index 4a34f4c0bb..26f32908f8 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs @@ -94,7 +94,7 @@ public void GetTypesShouldReturnSetOfDefinedTypes() // Setup mocks mockAssembly.Setup(a => a.GetTypes()).Returns(expectedTypes); - IReadOnlyList<Type> types = AssemblyEnumerator.GetTypes(mockAssembly.Object, string.Empty, _warnings); + IReadOnlyList<Type?> types = AssemblyEnumerator.GetTypes(mockAssembly.Object, string.Empty, _warnings); Verify(expectedTypes.SequenceEqual(types)); } @@ -116,7 +116,7 @@ public void GetTypesShouldReturnReflectionTypeLoadExceptionTypesOnException() // Setup mocks mockAssembly.Setup(a => a.GetTypes()).Throws(new ReflectionTypeLoadException(reflectedTypes, null)); - IReadOnlyList<Type> types = AssemblyEnumerator.GetTypes(mockAssembly.Object, string.Empty, _warnings); + IReadOnlyList<Type?> types = AssemblyEnumerator.GetTypes(mockAssembly.Object, string.Empty, _warnings); Verify(types is not null); Verify(reflectedTypes.Equals(types)); @@ -131,7 +131,7 @@ public void GetTypesShouldLogWarningsWhenReflectionFailsWithLoaderExceptions() mockAssembly.Setup(a => a.GetTypes()).Throws(new ReflectionTypeLoadException(null, exceptions)); mockAssembly.Setup(a => a.GetTypes()).Throws(new ReflectionTypeLoadException(null, exceptions)); - IReadOnlyList<Type> types = AssemblyEnumerator.GetTypes(mockAssembly.Object, "DummyAssembly", _warnings); + IReadOnlyList<Type?> types = AssemblyEnumerator.GetTypes(mockAssembly.Object, "DummyAssembly", _warnings); Verify(_warnings.Count == 1); Verify(_warnings.ToList().Contains(