private void InvokeSteps(Type type, Object instance) { MethodInfo[] mInfos = type.GetMethods(); IScenarioData scenarioData = new ScenarioData(); List <MethodInfo> listMI = new List <MethodInfo>(); IDictionary <int, MethodInfo> dictRollbackScenario = new Dictionary <int, MethodInfo>(); Type scenraioAttrType = typeof(ScenarioAttribute); Type rollbackAttrType = typeof(RollbackScenarioAttribute); ScenarioAttribute lastRunScenario = null; List <ScenarioAttribute> rollBackScenariosCompareList = new List <ScenarioAttribute>(); #region Get all methods set ScenarioAttribute and RollbackScenario foreach (MethodInfo mi in mInfos) { foreach (ScenarioAttribute sa in mi.GetCustomAttributes(typeof(ScenarioAttribute), true)) { if (sa.Enabled) { listMI.Add(mi); } scenarioData.Add(sa.SID, ETestResult.NotRun); } foreach (RollbackScenarioAttribute rbsa in mi.GetCustomAttributes(typeof(RollbackScenarioAttribute), true)) { if (rbsa.Enabled) { dictRollbackScenario.Add(rbsa.SID, mi); } } } if (type.GetProperty(ETestUsage.ScenarioData.ToString()) != null) { type.InvokeMember(ETestUsage.ScenarioData.ToString(), BindingFlags.SetProperty, null, instance, new object[] { scenarioData }); } #endregion try { #region Invoke Init() InvokeTestInitialize(type, instance); #endregion #region Invoke enabled scenario methods and rollback methods if failed or bloced if (listMI.Count > 0) { listMI.Sort( delegate(MethodInfo m1, MethodInfo m2) { return(((ScenarioAttribute)(m1.GetCustomAttributes(scenraioAttrType, true))[0]).SID.CompareTo(((ScenarioAttribute)(m2.GetCustomAttributes(scenraioAttrType, true))[0]).SID)); } ); foreach (MethodInfo m in listMI) { ScenarioAttribute scenarioAttr = (ScenarioAttribute)m.GetCustomAttributes(true)[0]; if (scenarioAttr.Enabled) { _reporter.BeginScenario(scenarioAttr.SID, string.IsNullOrEmpty(scenarioAttr.Description) ? m.Name : scenarioAttr.Description); ETestResult retVal = ETestResult.Fail; try { var result = type.InvokeMember(m.Name, BindingFlags.InvokeMethod, null, instance, new Object[0]); if (result == null) { _reporter.LogWarning("Scenario [{0}] returned void .", scenarioAttr.SID); LogEndScenario(scenarioAttr.SID, ETestResult.Warning); continue; } else if (result is ETestResult) { retVal = (ETestResult)result; scenarioData[scenarioAttr.SID] = retVal; LogEndScenario(scenarioAttr.SID, retVal); if (retVal == ETestResult.Skipped || retVal == ETestResult.NotRun) { continue; } if (retVal == ETestResult.Fail) { lastRunScenario = scenarioAttr; throw new TestFailException(scenarioAttr.SID); } if (retVal == ETestResult.Blocked) { lastRunScenario = scenarioAttr; throw new TestBlockedException(scenarioAttr.SID); } } else { _reporter.LogWarning("Scenario [{0}] retuned value was not 'ETestResult' type.", scenarioAttr.SID); LogEndScenario(scenarioAttr.SID, ETestResult.Warning); } lastRunScenario = scenarioAttr; } catch (TestFailException failEx) { _reporter.LogError("{0}", failEx); Rollback(type, instance, dictRollbackScenario, lastRunScenario.SID); throw failEx; } catch (TestBlockedException blockedEx) { _reporter.LogError("{0}", blockedEx); Rollback(type, instance, dictRollbackScenario, lastRunScenario.SID); throw blockedEx; } catch (Exception e) { _reporter.LogError("{0}", e); if (e.InnerException != null) { _reporter.LogError("{0}", e.InnerException); if (e.InnerException.InnerException != null) { _reporter.LogError("{0}", e.InnerException.InnerException); } } LogEndScenario(scenarioAttr.SID, ETestResult.Fail); scenarioData[scenarioAttr.SID] = ETestResult.Fail; Rollback(type, instance, dictRollbackScenario, scenarioAttr.SID); throw e; } #region Rollback required scenarios when all test scenario has executed. finally { ScenarioAttribute lastExpectedScenario = (ScenarioAttribute)listMI.Last().GetCustomAttributes(true)[0]; if (null != lastRunScenario && lastRunScenario.SID.Equals(lastExpectedScenario.SID)) { Rollback(type, instance, dictRollbackScenario, lastExpectedScenario.SID); } } #endregion } else { _reporter.LogDisabledScenario(scenarioAttr.SID); LogEndScenario(scenarioAttr.SID, ETestResult.Skipped); } } } #endregion } finally { #region Invoke End() InvokeTestCleanup(type, instance); #endregion } }