bobmarksie
bobmarksie

Reputation: 3636

Customising Junit5 test output via Gradle

I'm trying to output BDD from my junit tests like the following: -

Feature: Adv Name Search

  Scenario: Search by name v1

    Given I am at the homepage                         
     When I search for name Brad Pitt 
      And I click the search button2  
     Then I expect to see results with name 'Brad Pitt'

When running in IntelliJ IDE, this displays nicely but when running in Gradle nothing is displayed. I did some research and enabled the test showStandardStreams boolean i.e.

In my build.gradle file I've added ...

test {
    useJUnitPlatform()
    testLogging {
        showStandardStreams = true
    }
}

This produces ...

> Task :test

Adv Name Search STANDARD_OUT
    Feature: Adv Name Search

      Tests the advanced name search feature in IMDB


Adv Name Search > Search by name v1 STANDARD_OUT
      Scenario: Search by name v1

        Given I am at the homepage                          
         When I search for name Brad Pitt                   
          And I click the search button2                    
         Then I expect to see results with name 'Brad Pitt' 

... which is pretty close but I don't really want to see the output from gradle (the lines with STANDARD_OUT + extra blank lines).

Adv Name Search STANDARD_OUT

Is there a way to not show the additional Gradle logging in the test section?

Or maybe my tests shouldn't be using System.out.println at all, but rather use proper logging (eg. log4j) + gradle config to display these?

Any help / advice is appreciated.

Update (1)

I've created a minimum reproducable example at https://github.com/bobmarks/stackoverflow-junit5-gradle if anyone wants to quickly clone and ./gradlew clean test.

Upvotes: 1

Views: 1453

Answers (2)

Chriki
Chriki

Reputation: 16338

You can replace your test { … } configuration with the following to get what you need:

test {
    useJUnitPlatform()
    systemProperty "file.encoding", "utf-8"
    test {
        onOutput { descriptor, event ->
            if (event.destination == TestOutputEvent.Destination.StdOut) {
                logger.lifecycle(event.message.replaceFirst(/\s+$/, ''))
            }
        }
    }
}

See also the docs for onOutput.


FWIW, I had originnaly posted the following (incomplete) answer which turned out to be focusing on the wrong approach of configuring the test logging:

I hardly believe that this is possible. Let me try to explain why.

Looking at the code which produces the lines that you don’t want to see, it doesn’t seem possible to simply configure this differently:

  1. Here’s the code that runs when something is printed to standard out in a test.
  2. The method it calls next unconditionally adds the test descriptor and event name (→ STANDARD_OUT) which you don’t want to see. There’s no way to switch this off.

So changing how standard output is logged can probably not be changed.

What about using a proper logger in the tests, though? I doubt that this will work either:

  1. Running tests basically means running some testing tool – JUnit 5 in your case – in a separate process.
  2. This tool doesn’t know anything/much about who runs it; and it probably shouldn’t care either. Even if the tool should provide a logger or if you create your own logger and run it as part of the tests, then the logger still has to print its log output somewhere.
    • The most obvious “somewhere” for the testing tool process is standard out again, in which case we wouldn’t win anything.
    • Even if there was some interprocess communication between Gradle and the testing tool for exchanging log messages, then you’d still have to find some configuration possibility on the Gradle side which configures how Gradle prints the received log messages to the console. I don’t think such configuration possibility (let alone the IPC for log messages) exists.

Upvotes: 1

Nullish Byte
Nullish Byte

Reputation: 396

One thing that can be done is to set the displayGranuality property in testLogging Options

From the documentation

"The display granularity of the events to be logged. For example, if set to 0, a method-level event will be displayed as "Test Run > Test Worker x > org.SomeClass > org.someMethod". If set to 2, the same event will be displayed as "org.someClass > org.someMethod".

Upvotes: 1

Related Questions