How to cleanly fail a test after parsing stdout event message


(Warren Muller) #1

I have a task of type test (dustTest). It executes custom unit test extensions. All works fine except as part of the test startup it might throw some errors to stdout not stderr resulting in the test passing. In some cases this is valid and in other cases not. I want to catch the stdout during the test, parse it for the ‘**** error’ text and fail the test in the cleanest way, so I can identify the failed tests in the reports as if it was a valid failure - although in some cases it might just be a configuration/startup failure. I can achieve this by throwing a GradleExecption in the test’s doLast {} but then the report does not tell me which test failed. So I want hook into the test infrastructure by failing the test as is if it was a genuine failure.

Whats the best way to fire the test failed event.

task dustTest(type: Test) {
 ...
      def errorInStdOut=false
      testLogging {
        events "started","failed","standard_error","standard_out","passed"
        onOutput { descriptor, event ->
          logger.info("Event=${event.destination}")
          if (event.destination == TestOutputEvent.Destination.StdOut) {
            if (event.message.contains('**** error')) {
              errorInStdOut=true
            }
                        }
        }
      }
        doLast {
        if (errorInStdOut) {
          throw new GradleException("Error(s) found in DUST output.")
        }
      }
 ...
}

(Luke Daley) #2

There’s no way to do this from the outside. The logging/listening stuff is designed for passive observers.

You might be better off hijacking System.out inside your test and failing from there. You can use something like common-io’s TeeOutputStream to wiretap the output.


(Warren Muller) #3

Great, thanks for the clarification!