Example #1
0
        private MethodInfo GetMethodInfoUsingRuntimeMethods(TestMethod testMethod, TestClassInfo testClassInfo)
        {
            MethodInfo testMethodInfo;

            var methodsInClass = testClassInfo.ClassType.GetRuntimeMethods().ToArray();

            if (testMethod.DeclaringClassFullName != null)
            {
                // Only find methods that match the given declaring name.
                testMethodInfo =
                    methodsInClass.Where(method => method.Name.Equals(testMethod.Name) &&
                                         method.DeclaringType.FullName.Equals(testMethod.DeclaringClassFullName) &&
                                         method.HasCorrectTestMethodSignature(true)).FirstOrDefault();
            }
            else
            {
                // Either the declaring class is the same as the test class, or
                // the declaring class information wasn't passed in the test case.
                // Prioritize the former while maintaining previous behavior for the latter.
                var className = testClassInfo.ClassType.FullName;
                testMethodInfo =
                    methodsInClass.Where(method => method.Name.Equals(testMethod.Name) && method.HasCorrectTestMethodSignature(true))
                    .OrderByDescending(method => method.DeclaringType.FullName.Equals(className)).FirstOrDefault();
            }

            return(testMethodInfo);
        }
Example #2
0
        /// <summary>
        /// Resolve the test method. The function will try to
        /// find a function that has the method name with 0 parameters. If the function
        /// cannot be found, or a function is found that returns non-void, the result is
        /// set to error.
        /// </summary>
        /// <param name="testMethod"> The test Method. </param>
        /// <param name="testClassInfo"> The test Class Info. </param>
        /// <param name="testContext"> The test Context. </param>
        /// <param name="captureDebugTraces"> Indicates whether the test method should capture debug traces.</param>
        /// <returns>
        /// The TestMethodInfo for the given test method. Null if the test method could not be found.
        /// </returns>
        private TestMethodInfo ResolveTestMethod(TestMethod testMethod, TestClassInfo testClassInfo, ITestContext testContext, bool captureDebugTraces)
        {
            Debug.Assert(testMethod != null, "testMethod is Null");
            Debug.Assert(testClassInfo != null, "testClassInfo is Null");

            var methodInfo = this.GetMethodInfoForTestMethod(testMethod, testClassInfo);

            if (methodInfo == null)
            {
                // Means the specified test method could not be found.
                return(null);
            }

            var expectedExceptionAttribute = this.reflectionHelper.ResolveExpectedExceptionHelper(methodInfo, testMethod);
            var timeout = this.GetTestTimeout(methodInfo, testMethod);

            var testMethodOptions = new TestMethodOptions()
            {
                Timeout = timeout, Executor = this.GetTestMethodAttribute(methodInfo, testClassInfo), ExpectedException = expectedExceptionAttribute, TestContext = testContext, CaptureDebugTraces = captureDebugTraces
            };
            var testMethodInfo = new TestMethodInfo(methodInfo, testClassInfo, testMethodOptions);

            this.SetCustomProperties(testMethodInfo, testContext);

            return(testMethodInfo);
        }
Example #3
0
        /// <summary>
        /// Resolves a method by using the method name.
        /// </summary>
        /// <param name="testMethod"> The test Method. </param>
        /// <param name="testClassInfo"> The test Class Info. </param>
        /// <returns> The <see cref="MethodInfo"/>. </returns>
        private MethodInfo GetMethodInfoForTestMethod(TestMethod testMethod, TestClassInfo testClassInfo)
        {
            var        methodsInClass = testClassInfo.ClassType.GetRuntimeMethods().ToArray();
            MethodInfo testMethodInfo;

            if (testMethod.DeclaringClassFullName != null)
            {
                // Only find methods that match the given declaring name.
                testMethodInfo =
                    methodsInClass.Where(method => method.Name.Equals(testMethod.Name) &&
                                         method.DeclaringType.FullName.Equals(testMethod.DeclaringClassFullName) &&
                                         method.HasCorrectTestMethodSignature(true)).FirstOrDefault();
            }
            else
            {
                // Either the declaring class is the same as the test class, or
                // the declaring class information wasn't passed in the test case.
                // Prioritize the former while maintaining previous behavior for the latter.
                var className = testClassInfo.ClassType.FullName;
                testMethodInfo =
                    methodsInClass.Where(method => method.Name.Equals(testMethod.Name) && method.HasCorrectTestMethodSignature(true))
                    .OrderByDescending(method => method.DeclaringType.FullName.Equals(className)).FirstOrDefault();
            }

            // if correct method is not found, throw appropriate
            // exception about what is wrong.
            if (testMethodInfo == null)
            {
                var errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_MethodDoesNotExists, testMethod.FullClassName, testMethod.Name);
                throw new TypeInspectionException(errorMessage);
            }

            return(testMethodInfo);
        }
Example #4
0
        /// <summary>
        /// Update the classInfo if the parameter method is a testInitialize/cleanup method
        /// </summary>
        /// <param name="classInfo"> The class Info. </param>
        /// <param name="methodInfo"> The method Info. </param>
        /// <param name="isBase"> If this needs to validate in base class or not. </param>
        /// <param name="instanceMethods"> The instance Methods. </param>
        /// <param name="testInitializeAttributeType"> The test Initialize Attribute Type. </param>
        /// <param name="testCleanupAttributeType"> The test Cleanup Attribute Type. </param>
        private void UpdateInfoIfTestInitializeOrCleanupMethod(
            TestClassInfo classInfo,
            MethodInfo methodInfo,
            bool isBase,
            Dictionary <string, string> instanceMethods,
            Type testInitializeAttributeType,
            Type testCleanupAttributeType)
        {
            var hasTestInitialize = this.reflectionHelper.IsAttributeDefined(methodInfo, testInitializeAttributeType, inherit: false);
            var hasTestCleanup    = this.reflectionHelper.IsAttributeDefined(methodInfo, testCleanupAttributeType, inherit: false);

            if (!hasTestCleanup && !hasTestInitialize)
            {
                if (methodInfo.HasCorrectTestInitializeOrCleanupSignature())
                {
                    instanceMethods[methodInfo.Name] = null;
                }

                return;
            }

            if (!methodInfo.HasCorrectTestInitializeOrCleanupSignature())
            {
                var message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_TestInitializeAndCleanupMethodHasWrongSignature, methodInfo.DeclaringType.FullName, methodInfo.Name);
                throw new TypeInspectionException(message);
            }

            if (hasTestInitialize)
            {
                if (!isBase)
                {
                    classInfo.TestInitializeMethod = methodInfo;
                }
                else
                {
                    if (!instanceMethods.ContainsKey(methodInfo.Name))
                    {
                        classInfo.BaseTestInitializeMethodsQueue.Enqueue(methodInfo);
                    }
                }
            }

            if (hasTestCleanup)
            {
                if (!isBase)
                {
                    classInfo.TestCleanupMethod = methodInfo;
                }
                else
                {
                    if (!instanceMethods.ContainsKey(methodInfo.Name))
                    {
                        classInfo.BaseTestCleanupMethodsQueue.Enqueue(methodInfo);
                    }
                }
            }

            instanceMethods[methodInfo.Name] = null;
        }
Example #5
0
        /// <summary>
        /// Provides the Test Method Extension Attribute of the TestClass.
        /// </summary>
        /// <param name="methodInfo"> The method info. </param>
        /// <param name="testClassInfo"> The test class info. </param>
        /// <returns>Test Method Attribute</returns>
        private TestMethodAttribute GetTestMethodAttribute(MethodInfo methodInfo, TestClassInfo testClassInfo)
        {
            // Get the derived TestMethod attribute from reflection
            var testMethodAttribute = this.reflectionHelper.GetDerivedAttribute <TestMethodAttribute>(methodInfo, false);

            // Get the derived TestMethod attribute from Extended TestClass Attribute
            // If the extended TestClass Attribute doesn't have extended TestMethod attribute then base class returns back the original testMethod Attribute
            testMethodAttribute = testClassInfo.ClassAttribute.GetTestMethodAttribute(testMethodAttribute) ?? testMethodAttribute;

            return(testMethodAttribute);
        }
Example #6
0
        internal TestMethodInfo(
            MethodInfo testMethod,
            TestClassInfo parent,
            TestMethodOptions testmethodOptions)
        {
            Debug.Assert(testMethod != null, "TestMethod should not be null");
            Debug.Assert(parent != null, "Parent should not be null");

            this.TestMethod        = testMethod;
            this.Parent            = parent;
            this.TestMethodOptions = testmethodOptions;
        }
Example #7
0
        /// <summary>
        /// Update the classInfo with given initialize and cleanup methods.
        /// </summary>
        /// <param name="classInfo"> The Class Info. </param>
        /// <param name="initAndCleanupMethods"> An array with the Initialize and Cleanup Methods Info. </param>
        private void UpdateInfoWithInitializeAndCleanupMethods(
            TestClassInfo classInfo,
            ref MethodInfo[] initAndCleanupMethods)
        {
            if (initAndCleanupMethods.Any(x => x != null))
            {
                classInfo.BaseClassInitAndCleanupMethods.Enqueue(
                    new Tuple <MethodInfo, MethodInfo>(
                        initAndCleanupMethods.FirstOrDefault(),
                        initAndCleanupMethods.LastOrDefault()));
            }

            initAndCleanupMethods = new MethodInfo[2];
        }
Example #8
0
        internal TestMethodInfo(
            MethodInfo testMethod,
            TestClassInfo parent,
            TestMethodOptions testmethodOptions,
            TestExecutionRecorderWrapper testExecutionRecorder)
        {
            Debug.Assert(testMethod != null, "TestMethod should not be null");
            Debug.Assert(parent != null, "Parent should not be null");
            Debug.Assert(testExecutionRecorder != null, "TestExecutionRecorder should not be null");

            this.TestMethod            = testMethod;
            this.Parent                = parent;
            this.TestMethodOptions     = testmethodOptions;
            this.TestExecutionRecorder = testExecutionRecorder;
        }
Example #9
0
        /// <summary>
        /// Resolves a method by using the method name.
        /// </summary>
        /// <param name="testMethod"> The test Method. </param>
        /// <param name="testClassInfo"> The test Class Info. </param>
        /// <returns> The <see cref="MethodInfo"/>. </returns>
        private MethodInfo GetMethodInfoForTestMethod(TestMethod testMethod, TestClassInfo testClassInfo)
        {
            var testMethodInfo = testMethod.HasManagedMethodAndTypeProperties
                               ? this.GetMethodInfoUsingManagedNameHelper(testMethod, testClassInfo)
                               : this.GetMethodInfoUsingRuntimeMethods(testMethod, testClassInfo);

            // if correct method is not found, throw appropriate
            // exception about what is wrong.
            if (testMethodInfo == null)
            {
                var errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_MethodDoesNotExists, testMethod.FullClassName, testMethod.Name);
                throw new TypeInspectionException(errorMessage);
            }

            return(testMethodInfo);
        }
Example #10
0
        /// <summary>
        /// Update the classInfo with given initialize and cleanup methods.
        /// </summary>
        /// <param name="classInfo"> The Class Info. </param>
        /// <param name="initAndCleanupMethods"> An array with the Initialize and Cleanup Methods Info. </param>
        private void UpdateInfoWithInitializeAndCleanupMethods(
            TestClassInfo classInfo,
            ref MethodInfo[] initAndCleanupMethods)
        {
            if (initAndCleanupMethods is null)
            {
                return;
            }

            classInfo.BaseClassInitAndCleanupMethods.Enqueue(
                new Tuple <MethodInfo, MethodInfo>(
                    initAndCleanupMethods.FirstOrDefault(),
                    initAndCleanupMethods.LastOrDefault()));

            initAndCleanupMethods = null;
        }
Example #11
0
        /// <summary>
        /// Update the classInfo if the parameter method is a classInitialize/cleanup method
        /// </summary>
        /// <param name="classInfo"> The Class Info. </param>
        /// <param name="methodInfo"> The Method Info. </param>
        /// <param name="isBase"> Flag to check whether base class needs to be validated. </param>
        /// <param name="initAndCleanupMethods"> An array with Initialize/Cleanup methods. </param>
        /// <param name="classInitializeAttributeType"> The Class Initialize Attribute Type. </param>
        /// <param name="classCleanupAttributeType"> The Class Cleanup Attribute Type. </param>
        private void UpdateInfoIfClassInitializeOrCleanupMethod(
            TestClassInfo classInfo,
            MethodInfo methodInfo,
            bool isBase,
            ref MethodInfo[] initAndCleanupMethods,
            Type classInitializeAttributeType,
            Type classCleanupAttributeType)
        {
            var isInitializeMethod = this.IsAssemblyOrClassInitializeMethod(methodInfo, classInitializeAttributeType);
            var isCleanupMethod    = this.IsAssemblyOrClassCleanupMethod(methodInfo, classCleanupAttributeType);

            if (isInitializeMethod)
            {
                if (isBase)
                {
                    if (((ClassInitializeAttribute)this.reflectionHelper.GetCustomAttribute(methodInfo, classInitializeAttributeType))
                        .InheritanceBehavior == InheritanceBehavior.BeforeEachDerivedClass)
                    {
                        initAndCleanupMethods[0] = methodInfo;
                    }
                }
                else
                {
                    // update class initialize method
                    classInfo.ClassInitializeMethod = methodInfo;
                }
            }

            if (isCleanupMethod)
            {
                if (isBase)
                {
                    if (((ClassCleanupAttribute)this.reflectionHelper.GetCustomAttribute(methodInfo, classCleanupAttributeType))
                        .InheritanceBehavior == InheritanceBehavior.BeforeEachDerivedClass)
                    {
                        initAndCleanupMethods[1] = methodInfo;
                    }
                }
                else
                {
                    // update class cleanup method
                    classInfo.ClassCleanupMethod = methodInfo;
                }
            }
        }
Example #12
0
        internal TestMethodInfo(
            MethodInfo testMethod,
            int timeout,
            TestMethodAttribute executor,
            ExpectedExceptionBaseAttribute expectedException,
            TestClassInfo parent,
            ITestContext testContext)
        {
            Debug.Assert(testMethod != null, "TestMethod should not be null");
            Debug.Assert(parent != null, "Parent should not be null");

            this.TestMethod        = testMethod;
            this.Timeout           = timeout;
            this.Parent            = parent;
            this.ExpectedException = expectedException;
            this.Executor          = executor;
            this.testContext       = testContext;
        }
Example #13
0
        /// <summary>
        /// Resolves a method by using the method name.
        /// </summary>
        /// <param name="testMethod"> The test Method. </param>
        /// <param name="testClassInfo"> The test Class Info. </param>
        /// <returns> The <see cref="MethodInfo"/>. </returns>
        private MethodInfo GetMethodInfoForTestMethod(TestMethod testMethod, TestClassInfo testClassInfo)
        {
            var methodsInClass = testClassInfo.ClassType.GetRuntimeMethods().ToArray();

            var testMethodInfo =
                methodsInClass.Where(method => method.Name.Equals(testMethod.Name))
                .FirstOrDefault(method => method.HasCorrectTestMethodSignature(true));

            // if correct method is not found, throw appropriate
            // exception about what is wrong.
            if (testMethodInfo == null)
            {
                var errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_MethodDoesNotExists, testMethod.FullClassName, testMethod.Name);
                throw new TypeInspectionException(errorMessage);
            }

            return(testMethodInfo);
        }
Example #14
0
        /// <summary>
        /// Resolves a method by using the method name.
        /// </summary>
        /// <param name="testMethod"> The test Method. </param>
        /// <param name="testClassInfo"> The test Class Info. </param>
        /// <returns> The <see cref="MethodInfo"/>. </returns>
        private MethodInfo GetMethodInfoForTestMethod(TestMethod testMethod, TestClassInfo testClassInfo)
        {
            var discoverInternals = this.discoverInternalsCache.GetOrAdd(
                testMethod.AssemblyName,
                _ => testClassInfo.Parent.Assembly.GetCustomAttribute <DiscoverInternalsAttribute>() != null);

            var testMethodInfo = testMethod.HasManagedMethodAndTypeProperties
                               ? this.GetMethodInfoUsingManagedNameHelper(testMethod, testClassInfo, discoverInternals)
                               : this.GetMethodInfoUsingRuntimeMethods(testMethod, testClassInfo, discoverInternals);

            // if correct method is not found, throw appropriate
            // exception about what is wrong.
            if (testMethodInfo == null)
            {
                var errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_MethodDoesNotExists, testMethod.FullClassName, testMethod.Name);
                throw new TypeInspectionException(errorMessage);
            }

            return(testMethodInfo);
        }
Example #15
0
        private MethodInfo GetMethodInfoUsingManagedNameHelper(TestMethod testMethod, TestClassInfo testClassInfo)
        {
            MethodInfo testMethodInfo = null;
            var        methodBase     = ManagedNameHelper.GetMethod(testClassInfo.Parent.Assembly, testMethod.ManagedTypeName, testMethod.ManagedMethodName);

            if (methodBase is MethodInfo mi)
            {
                testMethodInfo = mi;
            }
            else if (methodBase != null)
            {
                var parameters = methodBase.GetParameters().Select(i => i.ParameterType).ToArray();
                testMethodInfo = methodBase.DeclaringType.GetRuntimeMethod(methodBase.Name, parameters);
            }

            testMethodInfo = testMethodInfo?.HasCorrectTestMethodSignature(true) ?? false
                           ? testMethodInfo
                           : null;

            return(testMethodInfo);
        }
Example #16
0
        /// <summary>
        /// Create the class Info
        /// </summary>
        /// <param name="classType"> The class Type. </param>
        /// <param name="testMethod"> The test Method. </param>
        /// <returns> The <see cref="TestClassInfo"/>. </returns>
        private TestClassInfo CreateClassInfo(Type classType, TestMethod testMethod)
        {
            var constructors = classType.GetTypeInfo().DeclaredConstructors;
            var constructor  = constructors.FirstOrDefault(ctor => ctor.GetParameters().Length == 0 && ctor.IsPublic);

            if (constructor == null)
            {
                var message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_NoDefaultConstructor, testMethod.FullClassName);
                throw new TypeInspectionException(message);
            }

            var testContextProperty = this.ResolveTestContext(classType);

            var assemblyInfo = this.GetAssemblyInfo(classType);

            var classInfo = new TestClassInfo(classType, constructor, testContextProperty, this.reflectionHelper.GetDerivedAttribute <TestClassAttribute>(classType, false), assemblyInfo);

            var testInitializeAttributeType  = typeof(TestInitializeAttribute);
            var testCleanupAttributeType     = typeof(TestCleanupAttribute);
            var classInitializeAttributeType = typeof(ClassInitializeAttribute);
            var classCleanupAttributeType    = typeof(ClassCleanupAttribute);

            // List holding the instance of the initialize/cleanup methods
            // to be passed into the tuples' queue  when updating the class info.
            var initAndCleanupMethods = new MethodInfo[2];

            // List of instance methods present in the type as well its base type
            // which is used to decide whether TestInitialize/TestCleanup methods
            // present in the base type should be used or not. They are not used if
            // the method is overridden in the derived type.
            var instanceMethods = new Dictionary <string, string>();

            foreach (var methodInfo in classType.GetTypeInfo().DeclaredMethods)
            {
                // Update test initialize/cleanup method
                this.UpdateInfoIfTestInitializeOrCleanupMethod(classInfo, methodInfo, isBase: false, instanceMethods: instanceMethods, testInitializeAttributeType: testInitializeAttributeType, testCleanupAttributeType: testCleanupAttributeType);

                // Update class initialize/cleanup method
                this.UpdateInfoIfClassInitializeOrCleanupMethod(classInfo, methodInfo, false, ref initAndCleanupMethods, classInitializeAttributeType, classCleanupAttributeType);
            }

            var baseType = classType.GetTypeInfo().BaseType;

            while (baseType != null)
            {
                foreach (var methodInfo in baseType.GetTypeInfo().DeclaredMethods)
                {
                    if (methodInfo.IsPublic && !methodInfo.IsStatic)
                    {
                        // Update test initialize/cleanup method from base type.
                        this.UpdateInfoIfTestInitializeOrCleanupMethod(classInfo, methodInfo, true, instanceMethods, testInitializeAttributeType, testCleanupAttributeType);
                    }

                    if (methodInfo.IsPublic && methodInfo.IsStatic)
                    {
                        this.UpdateInfoIfClassInitializeOrCleanupMethod(classInfo, methodInfo, true, ref initAndCleanupMethods, classInitializeAttributeType, classCleanupAttributeType);
                    }
                }

                this.UpdateInfoWithInitializeAndCleanupMethods(classInfo, ref initAndCleanupMethods);
                baseType = baseType.GetTypeInfo().BaseType;
            }

            return(classInfo);
        }