@@ -10,6 +10,7 @@ import { IRunTestContext, TestLevel, TestResultState } from '../../java-test-run
1010const TEST_START : string = 'testStarted' ;
1111const TEST_FAIL : string = 'testFailed' ;
1212const TEST_FINISH : string = 'testFinished' ;
13+ const TEST_ERROR : string = 'error' ;
1314
1415export class TestNGRunnerResultAnalyzer extends RunnerResultAnalyzer {
1516
@@ -47,15 +48,25 @@ export class TestNGRunnerResultAnalyzer extends RunnerResultAnalyzer {
4748 try {
4849 this . processData ( match [ 1 ] ) ;
4950 } catch ( error ) {
50- this . testContext . testRun . appendOutput ( `[ERROR] Failed to parse output data: ${ match [ 1 ] } \n` ) ;
51+ this . testContext . testRun . appendOutput ( `[ERROR] Failed to parse output data: ${ match [ 1 ] } \r\ n` ) ;
5152 }
5253 }
5354 }
5455
5556 public processData ( data : string ) : void {
5657 const outputData : ITestNGOutputData = JSON . parse ( data ) as ITestNGOutputData ;
5758
58- const id : string = `${ this . projectName } @${ outputData . attributes . name } ` ;
59+ if ( outputData . name === TEST_ERROR ) {
60+ this . processRunnerError ( outputData . attributes ) ;
61+ return ;
62+ }
63+
64+ const attributes : ITestNGAttributes | undefined = outputData . attributes ;
65+ if ( ! attributes ?. name ) {
66+ return ;
67+ }
68+
69+ const id : string = `${ this . projectName } @${ attributes . name } ` ;
5970 if ( outputData . name === TEST_START ) {
6071 this . initializeCache ( ) ;
6172 const item : TestItem | undefined = this . getTestItem ( id ) ;
@@ -66,7 +77,6 @@ export class TestNGRunnerResultAnalyzer extends RunnerResultAnalyzer {
6677 this . currentTestState = TestResultState . Running ;
6778 this . testContext . testRun . started ( item ) ;
6879 this . updateParentOnChildStart ( item ) ;
69- this . markItemStarted ( item ) ;
7080 } else if ( outputData . name === TEST_FAIL ) {
7181 const item : TestItem | undefined = this . getTestItem ( id ) ;
7282 if ( ! item ) {
@@ -75,11 +85,11 @@ export class TestNGRunnerResultAnalyzer extends RunnerResultAnalyzer {
7585 this . currentTestState = TestResultState . Failed ;
7686 const testMessages : TestMessage [ ] = [ ] ;
7787
78- if ( outputData . attributes . trace ) {
88+ if ( attributes . trace ) {
7989 const markdownTrace : MarkdownString = new MarkdownString ( ) ;
8090 markdownTrace . isTrusted = true ;
8191 markdownTrace . supportHtml = true ;
82- for ( const line of outputData . attributes . trace . split ( / \r ? \n / ) ) {
92+ for ( const line of attributes . trace . split ( / \r ? \n / ) ) {
8393 this . processStackTrace ( line , markdownTrace , this . currentItem , this . projectName ) ;
8494 }
8595
@@ -92,19 +102,18 @@ export class TestNGRunnerResultAnalyzer extends RunnerResultAnalyzer {
92102 }
93103 testMessages . push ( testMessage ) ;
94104 }
95- const duration : number = Number . parseInt ( outputData . attributes . duration , 10 ) ;
105+ const duration : number | undefined = this . parseDuration ( attributes . duration ) ;
96106 setTestState ( this . testContext . testRun , item , this . currentTestState , testMessages , duration ) ;
97107 } else if ( outputData . name === TEST_FINISH ) {
98- const item : TestItem | undefined = this . getTestItem ( data ) ;
108+ const item : TestItem | undefined = this . getTestItem ( id ) ;
99109 if ( ! item ) {
100110 return ;
101111 }
102112 if ( this . currentTestState === TestResultState . Running ) {
103113 this . currentTestState = TestResultState . Passed ;
104114 }
105- const duration : number = Number . parseInt ( outputData . attributes . duration , 10 ) ;
115+ const duration : number | undefined = this . parseDuration ( attributes . duration ) ;
106116 setTestState ( this . testContext . testRun , item , this . currentTestState , undefined , duration ) ;
107- this . markItemFinished ( item ) ;
108117 const itemData : ITestItemData | undefined = dataCache . get ( item ) ;
109118 if ( itemData ?. testLevel === TestLevel . Method ) {
110119 this . updateParentOnChildComplete ( item , this . currentTestState ) ;
@@ -126,6 +135,26 @@ export class TestNGRunnerResultAnalyzer extends RunnerResultAnalyzer {
126135 this . currentItem = undefined ;
127136 }
128137
138+ private processRunnerError ( attributes : ITestNGAttributes | undefined ) : void {
139+ let message : string = attributes ?. message || 'Failed to run TestNG tests.' ;
140+ if ( attributes ?. trace ) {
141+ message += `\n${ attributes . trace } ` ;
142+ }
143+ const testMessage : TestMessage = new TestMessage ( message ) ;
144+ for ( const item of this . testContext . testItems ) {
145+ this . testContext . testRun . errored ( item , testMessage ) ;
146+ }
147+ }
148+
149+ private parseDuration ( duration : string | undefined ) : number | undefined {
150+ if ( ! duration ) {
151+ return undefined ;
152+ }
153+
154+ const parsed : number = Number . parseInt ( duration , 10 ) ;
155+ return Number . isNaN ( parsed ) ? undefined : parsed ;
156+ }
157+
129158 protected getStacktraceFilter ( ) : string [ ] {
130159 return [
131160 'com.microsoft.java.test.runner.' ,
@@ -142,20 +171,14 @@ export class TestNGRunnerResultAnalyzer extends RunnerResultAnalyzer {
142171}
143172
144173interface ITestNGOutputData {
145- attributes : ITestNGAttributes ;
146- type : TestOutputType ;
174+ attributes ?: ITestNGAttributes ;
147175 name : string ;
148176}
149177
150- enum TestOutputType {
151- Info ,
152- Error ,
153- }
154-
155178interface ITestNGAttributes {
156- name : string ;
157- duration : string ;
158- location : string ;
159- message : string ;
160- trace : string ;
179+ name ? : string ;
180+ duration ? : string ;
181+ location ? : string ;
182+ message ? : string ;
183+ trace ? : string ;
161184}
0 commit comments