33using System . Linq ;
44using Microsoft . VisualStudio . TestPlatform . ObjectModel ;
55using Microsoft . VisualStudio . TestPlatform . ObjectModel . Adapter ;
6- using Microsoft . VisualStudio . TestPlatform . ObjectModel . Logging ;
76using Xunit . Abstractions ;
87using VsTestResult = Microsoft . VisualStudio . TestPlatform . ObjectModel . TestResult ;
98using VsTestResultMessage = Microsoft . VisualStudio . TestPlatform . ObjectModel . TestResultMessage ;
@@ -14,15 +13,18 @@ public class VsExecutionVisitor : TestMessageVisitor<ITestAssemblyFinished>
1413 {
1514 readonly Func < bool > cancelledThunk ;
1615 readonly ITestFrameworkExecutionOptions executionOptions ;
16+ readonly LoggerHelper logger ;
1717 readonly ITestExecutionRecorder recorder ;
1818 readonly Dictionary < ITestCase , TestCase > testCases ;
1919
2020 public VsExecutionVisitor ( ITestExecutionRecorder recorder ,
21+ LoggerHelper logger ,
2122 Dictionary < ITestCase , TestCase > testCases ,
2223 ITestFrameworkExecutionOptions executionOptions ,
2324 Func < bool > cancelledThunk )
2425 {
2526 this . recorder = recorder ;
27+ this . logger = logger ;
2628 this . testCases = testCases ;
2729 this . executionOptions = executionOptions ;
2830 this . cancelledThunk = cancelledThunk ;
@@ -38,13 +40,28 @@ TestCase FindTestCase(ITestCase testCase)
3840 if ( result != null )
3941 return result ;
4042
41- recorder . SendMessage ( TestMessageLevel . Error , String . Format ( "Result reported for unknown test case: {0}" , testCase . DisplayName ) ) ;
43+ logger . LogError ( testCase , "Result reported for unknown test case: {0}" , testCase . DisplayName ) ;
4244 return null ;
4345 }
4446
47+ private void TryAndReport ( string actionDescription , ITestCase testCase , Action action )
48+ {
49+ try
50+ {
51+ if ( executionOptions . GetDiagnosticMessagesOrDefault ( ) )
52+ logger . Log ( testCase , "Performing {0} for test case {1}" , actionDescription , testCase . DisplayName ) ;
53+
54+ action ( ) ;
55+ }
56+ catch ( Exception ex )
57+ {
58+ logger . LogError ( testCase , "Error occured while {0} for test case {1}: {2}" , actionDescription , testCase . DisplayName , ex ) ;
59+ }
60+ }
61+
4562 protected override bool Visit ( IErrorMessage error )
4663 {
47- recorder . SendMessage ( TestMessageLevel . Error , String . Format ( "Catastrophic failure: {0}" , ExceptionUtility . CombineMessages ( error ) ) ) ;
64+ logger . LogError ( "Catastrophic failure: {0}" , ExceptionUtility . CombineMessages ( error ) ) ;
4865
4966 return ! cancelledThunk ( ) ;
5067 }
@@ -57,9 +74,10 @@ protected override bool Visit(ITestFailed testFailed)
5774 result . ErrorMessage = ExceptionUtility . CombineMessages ( testFailed ) ;
5875 result . ErrorStackTrace = ExceptionUtility . CombineStackTraces ( testFailed ) ;
5976
60- recorder . RecordEnd ( result . TestCase , result . Outcome ) ;
61- recorder . RecordResult ( result ) ;
77+ TryAndReport ( "RecordResult (Fail)" , testFailed . TestCase , ( ) => recorder . RecordResult ( result ) ) ;
6278 }
79+ else
80+ logger . LogWarning ( testFailed . TestCase , "(Fail) Could not find VS test case for {0} (ID = {1})" , testFailed . TestCase . DisplayName , testFailed . TestCase . UniqueID ) ;
6381
6482 return ! cancelledThunk ( ) ;
6583 }
@@ -68,10 +86,9 @@ protected override bool Visit(ITestPassed testPassed)
6886 {
6987 var result = MakeVsTestResult ( TestOutcome . Passed , testPassed ) ;
7088 if ( result != null )
71- {
72- recorder . RecordEnd ( result . TestCase , result . Outcome ) ;
73- recorder . RecordResult ( result ) ;
74- }
89+ TryAndReport ( "RecordResult (Pass)" , testPassed . TestCase , ( ) => recorder . RecordResult ( result ) ) ;
90+ else
91+ logger . LogWarning ( testPassed . TestCase , "(Pass) Could not find VS test case for {0} (ID = {1})" , testPassed . TestCase . DisplayName , testPassed . TestCase . UniqueID ) ;
7592
7693 return ! cancelledThunk ( ) ;
7794 }
@@ -80,51 +97,63 @@ protected override bool Visit(ITestSkipped testSkipped)
8097 {
8198 var result = MakeVsTestResult ( TestOutcome . Skipped , testSkipped ) ;
8299 if ( result != null )
83- {
84- recorder . RecordEnd ( result . TestCase , result . Outcome ) ;
85- recorder . RecordResult ( result ) ;
86- }
100+ TryAndReport ( "RecordResult (Skip)" , testSkipped . TestCase , ( ) => recorder . RecordResult ( result ) ) ;
101+ else
102+ logger . LogWarning ( testSkipped . TestCase , "(Skip) Could not find VS test case for {0} (ID = {1})" , testSkipped . TestCase . DisplayName , testSkipped . TestCase . UniqueID ) ;
103+
104+ return ! cancelledThunk ( ) ;
105+ }
106+
107+ protected override bool Visit ( ITestCaseStarting testCaseStarting )
108+ {
109+ var vsTestCase = FindTestCase ( testCaseStarting . TestCase ) ;
110+ if ( vsTestCase != null )
111+ TryAndReport ( "RecordStart" , testCaseStarting . TestCase , ( ) => recorder . RecordStart ( vsTestCase ) ) ;
112+ else
113+ logger . LogWarning ( testCaseStarting . TestCase , "(Starting) Could not find VS test case for {0} (ID = {1})" , testCaseStarting . TestCase . DisplayName , testCaseStarting . TestCase . UniqueID ) ;
87114
88115 return ! cancelledThunk ( ) ;
89116 }
90117
91- protected override bool Visit ( ITestStarting testStarting )
118+ protected override bool Visit ( ITestCaseFinished testCaseFinished )
92119 {
93- var vsTestCase = FindTestCase ( testStarting . TestCase ) ;
120+ var vsTestCase = FindTestCase ( testCaseFinished . TestCase ) ;
94121 if ( vsTestCase != null )
95- recorder . RecordStart ( vsTestCase ) ;
122+ TryAndReport ( "RecordEnd" , testCaseFinished . TestCase , ( ) => recorder . RecordEnd ( vsTestCase , TestOutcome . Passed ) ) ; // TODO: Don't have an aggregate outcome here!
123+ else
124+ logger . LogWarning ( testCaseFinished . TestCase , "(Finished) Could not find VS test case for {0} (ID = {1})" , testCaseFinished . TestCase . DisplayName , testCaseFinished . TestCase . UniqueID ) ;
96125
97126 return ! cancelledThunk ( ) ;
98127 }
99128
100129 protected override bool Visit ( ITestAssemblyCleanupFailure cleanupFailure )
101130 {
102- return WriteError ( String . Format ( "Test Assembly Cleanup Failure ({0})" , cleanupFailure . TestAssembly . Assembly . AssemblyPath ) , cleanupFailure , cleanupFailure . TestCases ) ;
131+ return WriteError ( string . Format ( "Test Assembly Cleanup Failure ({0})" , cleanupFailure . TestAssembly . Assembly . AssemblyPath ) , cleanupFailure , cleanupFailure . TestCases ) ;
103132 }
104133
105134 protected override bool Visit ( ITestCaseCleanupFailure cleanupFailure )
106135 {
107- return WriteError ( String . Format ( "Test Case Cleanup Failure ({0})" , cleanupFailure . TestCase . DisplayName ) , cleanupFailure , cleanupFailure . TestCases ) ;
136+ return WriteError ( string . Format ( "Test Case Cleanup Failure ({0})" , cleanupFailure . TestCase . DisplayName ) , cleanupFailure , cleanupFailure . TestCases ) ;
108137 }
109138
110139 protected override bool Visit ( ITestClassCleanupFailure cleanupFailure )
111140 {
112- return WriteError ( String . Format ( "Test Class Cleanup Failure ({0})" , cleanupFailure . TestClass . Class . Name ) , cleanupFailure , cleanupFailure . TestCases ) ;
141+ return WriteError ( string . Format ( "Test Class Cleanup Failure ({0})" , cleanupFailure . TestClass . Class . Name ) , cleanupFailure , cleanupFailure . TestCases ) ;
113142 }
114143
115144 protected override bool Visit ( ITestCollectionCleanupFailure cleanupFailure )
116145 {
117- return WriteError ( String . Format ( "Test Collection Cleanup Failure ({0})" , cleanupFailure . TestCollection . DisplayName ) , cleanupFailure , cleanupFailure . TestCases ) ;
146+ return WriteError ( string . Format ( "Test Collection Cleanup Failure ({0})" , cleanupFailure . TestCollection . DisplayName ) , cleanupFailure , cleanupFailure . TestCases ) ;
118147 }
119148
120149 protected override bool Visit ( ITestCleanupFailure cleanupFailure )
121150 {
122- return WriteError ( String . Format ( "Test Cleanup Failure ({0})" , cleanupFailure . Test . DisplayName ) , cleanupFailure , cleanupFailure . TestCases ) ;
151+ return WriteError ( string . Format ( "Test Cleanup Failure ({0})" , cleanupFailure . Test . DisplayName ) , cleanupFailure , cleanupFailure . TestCases ) ;
123152 }
124153
125154 protected override bool Visit ( ITestMethodCleanupFailure cleanupFailure )
126155 {
127- return WriteError ( String . Format ( "Test Method Cleanup Failure ({0})" , cleanupFailure . TestMethod . Method . Name ) , cleanupFailure , cleanupFailure . TestCases ) ;
156+ return WriteError ( string . Format ( "Test Method Cleanup Failure ({0})" , cleanupFailure . TestMethod . Method . Name ) , cleanupFailure , cleanupFailure . TestCases ) ;
128157 }
129158
130159 protected bool WriteError ( string failureName , IFailureInformation failureInfo , IEnumerable < ITestCase > testCases )
@@ -134,12 +163,14 @@ protected bool WriteError(string failureName, IFailureInformation failureInfo, I
134163 var result = MakeVsTestResult ( TestOutcome . Failed , testCase , testCase . DisplayName ) ;
135164 if ( result != null )
136165 {
137- result . ErrorMessage = String . Format ( "[{0}]: {1}" , failureName , ExceptionUtility . CombineMessages ( failureInfo ) ) ;
166+ result . ErrorMessage = string . Format ( "[{0}]: {1}" , failureName , ExceptionUtility . CombineMessages ( failureInfo ) ) ;
138167 result . ErrorStackTrace = ExceptionUtility . CombineStackTraces ( failureInfo ) ;
139168
140- recorder . RecordEnd ( result . TestCase , result . Outcome ) ;
141- recorder . RecordResult ( result ) ;
169+ TryAndReport ( "RecordEnd (Failure)" , testCase , ( ) => recorder . RecordEnd ( result . TestCase , result . Outcome ) ) ;
170+ TryAndReport ( "RecordResult (Failure)" , testCase , ( ) => recorder . RecordResult ( result ) ) ;
142171 }
172+ else
173+ logger . LogWarning ( testCase , "(Failure) Could not find VS test case for {0} (ID = {1})" , testCase . DisplayName , testCase . UniqueID ) ;
143174 }
144175
145176 return ! cancelledThunk ( ) ;
@@ -170,7 +201,7 @@ private VsTestResult MakeVsTestResult(TestOutcome outcome, ITestCase testCase, s
170201 if ( result . Duration . TotalMilliseconds == 0 )
171202 result . Duration = TimeSpan . FromMilliseconds ( 1 ) ;
172203
173- if ( ! String . IsNullOrEmpty ( output ) )
204+ if ( ! string . IsNullOrEmpty ( output ) )
174205 result . Messages . Add ( new VsTestResultMessage ( VsTestResultMessage . StandardOutCategory , output ) ) ;
175206
176207 return result ;
0 commit comments