Search code examples
intellij-ideaspock

Spock 2.0 is reporting an extra test for data-driven tests


I'm upgrading a project from Spock 1.3 to 2.0, and I've noticed that data-driven tests seem to have an extra test that the IDE is reporting somewhere. For example, the "maximum of two numbers" data-driven example from the documentation shows 4 tests pass when there are only 3 rows:

class MathSpec extends Specification {
    def "maximum of two numbers"() {
        expect:
        Math.max(a, b) == c

        where:
        a | b | c
        1 | 3 | 3
        7 | 4 | 7
        0 | 0 | 0
    }
}

What is going on here?

enter image description here


Solution

  • Firstly, your question is an IntelliJ IDEA question as much as it is a Spock question, because you want to know why parametrised Spock 2 tests look like that in IDEA.

    Secondly, the code you posted is different from the code you ran in IntelliJ IDEA. Probably your feature method starts more like this in order to achieve the test iteration naming we see in your screenshot:

    def "maximum of #a and #b is #c"() {
      // ...
    }
    

    Having established that, next let me remind you of the very first sentence of the Spock 2.0 release notes:

    Spock is now a test engine based on the JUnit Platform

    This means that in contrast to Spock 1.x which was based on a JUnit 4 runner, Spock 2.0 sports its own JUnit test engine, i.e. the Spock engine is on the same level as the Jupiter engine, both running on the JUnit platform.

    The way parametrised tests are reported in IDEA is the same for JUnit 5 tests as for Spock 2 tests:

    Test class A
      - Test method x
          - parametrised method name 0
          - ...
          - parametrised method name n
      - Test method y
          - parametrised method name 0
          - ...
          - parametrised method name n
    Test class B
      - Test method z
          - parametrised method name 0
          - ...
          - parametrised method name n
    ...
    

    IDEA is not "reporting an extra test", it simply adds a level of grouping by method name to the test report.

    If for example you run this parametrised JUnit 5 test

    import org.junit.jupiter.params.ParameterizedTest;
    import org.junit.jupiter.params.provider.ValueSource;
    
    import static org.junit.jupiter.api.Assertions.assertTrue;
    
    public class NumbersTest {
      @ParameterizedTest(name = "{0} is an odd number")
      @ValueSource(ints = {1, 3, 5, -3, 15, Integer.MAX_VALUE}) // six numbers
      void isOdd_ShouldReturnTrueForOddNumbers(int number) {
        assertTrue(Numbers.isOdd(number));
      }
    
      public static class Numbers {
        public static boolean isOdd(int number) {
          return number % 2 != 0;
        }
      }
    }
    

    it looks like this in IDEA:

    JUnit 5 parametrised test report in IntelliJ IDEA

    I.e., what you see it to be expected for JUnit platform tests.