public override TestResult Execute() { TestItems children = Children; if (children != null && children.Count > 0) { // this is not a leaf node, just invoke all the children's execute foreach (object child in children) { TestCase tc = child as TestCase; if (tc != null) { if (TestInput.IsTestCaseSelected(tc.Name)) { Console.WriteLine("TestCase:{0} - {1}", tc.Attribute.Name, tc.Attribute.Desc); tc.Init(); tc.Execute(); } } } } Console.WriteLine("Pass:{0}, Fail:{1}, Skip:{2}", PassCount, FailCount, SkipCount); return(TestResult.Passed); }
TestResult ITestItem.Terminate() { //Enter OnEnter(TestMethod.Terminate); TestResult result = TestResult.Passed; //NOTE: Since exceptions are a way-of-life in C#, and the fact that they are just //caught by the runtime before passed back to LTM, we lose the entire stack and just //an unknown error code is returned. //To help solve this we will wrap the call in a try catch and actually //log the exception to the LTM output window... try { //Skipped if (this.Skipped || !this.Implemented) { result = TestResult.Skipped; } else { this.Terminate(); } //Before exiting make sure we reset our CurChild to null, to prevent incorrect uses if (Parent != null) { Parent.CurrentChild = null; } } catch (Exception e) { HandleException(e); } try { //Clear any previous existing info (in the static class). if (_testtype == TestType.TestModule) { //Note: We actually have to clear these "statics" since they are not cleaned up //until the process exits. Which means that if you run again, in an apartment model //thread it will try to release these when setting them which is not allowed to //call a method on an object created in another apartment TestInput.Dispose(); TestLog.Dispose(); } } catch (Exception e) { result = HandleException(e); } //This is also a good point to hint to the GC to free up any unused memory //at the end of each TestCase and the end of each module. GC.Collect(); GC.WaitForPendingFinalizers(); //Leave OnLeave(TestMethod.Terminate); return(result); }