1

In a maven project with lots of JUnit 4 tests, surefire-junit47 is not executing the tests.

There are no testng tests in this project, and there is no testng in the pom. But this project has a dependency on another project that does have testng in the pom. You can see it import testng in the mvn -X output below.

For reference sake, here is the documentation I'm working from: https://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html

Here are a couple of pom configurations that show the problem.

Given this test class organization:

- src/main/test/
   - com.mycomp.qc.core.account
     - CopyAccountTests.java
     - CreateAccountTests.java
     - DeleteAccountTests.java
     - ListAccountTests.java
     - ReadAccountTests.java
     - UpdateAccountTests.java
   - com.mycomp.qc.core.product
     - CopyProductTests.java
     - CreateProductTests.java
     - DeleteProductTests.java
     - ListProductTests.java
     - ReadProductTests.java
     - UpdateProductTests.java
   - ..... and 300 more packages .....

And given this test class structure:

package com.mycomp.qc.core.account;

import org.junit.Assert;
import org.junit.Test;
.... and more ....

public class CopyAccountTests {

    @Test
    public void copyAccount1() {
        Assert.assertTrue("pass", true);
    }

    @Test
    public void copyAccount2() {
        Assert.assertTrue("fail", false);
    }

.... and more ....

}

pom config 1: Specifically include Account tests, by pattern

Runs all the Account tests, just as the documentation indicates.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit47</artifactId>
            <version>${surefire.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <testFailureIgnore>true</testFailureIgnore>
        <includes>
            <include>*Account*</include>
        </includes>
        <threadCount>1</threadCount>
    </configuration>
    <executions>
        <execution>
            <id>default-test</id>
            <phase>test</phase>
            <goals>
                <goal>test</goal>
            </goals>
        </execution>
    </executions>
</plugin>

pom config 2: Specifically include Account tests, by pattern

Runs all the Account and Product tests, just as the documentation indicates.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit47</artifactId>
            <version>${surefire.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <testFailureIgnore>true</testFailureIgnore>
        <includes>
            <include>*Account*</include>
            <include>*Product*</include>
        </includes>
        <threadCount>1</threadCount>
    </configuration>
    <executions>
        <execution>
            <id>default-test</id>
            <phase>test</phase>
            <goals>
                <goal>test</goal>
            </goals>
        </execution>
    </executions>
</plugin>

pom config 3: Include all tests, based on default surefire

Finds and initializes test classes, but does not execute any @Test methods.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit47</artifactId>
            <version>${surefire.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <testFailureIgnore>true</testFailureIgnore>
        <threadCount>1</threadCount>
    </configuration>
    <executions>
        <execution>
            <id>default-test</id>
            <phase>test</phase>
            <goals>
                <goal>test</goal>
            </goals>
        </execution>
    </executions>
</plugin>

pom config 4: Include all tests, by pattern

Finds and initializes test classes, but does not execute any @Test methods.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire.version}</version>
    <dependencies>
        <dependency>
            <groupId>org.apache.maven.surefire</groupId>
            <artifactId>surefire-junit47</artifactId>
            <version>${surefire.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <testFailureIgnore>true</testFailureIgnore>
        <includes>
            <include>*Test*</include>
        </includes>
        <threadCount>1</threadCount>
    </configuration>
    <executions>
        <execution>
            <id>default-test</id>
            <phase>test</phase>
            <goals>
                <goal>test</goal>
            </goals>
        </execution>
    </executions>
</plugin>

What I've tried:

  1. Obviously, from the examples, I've tried different include patterns in the pom. See the results outlined above.

  2. Configured a new project, with all the same imports and just a few small tests. All the include patterns above behaved as outlined in the documentation.

  3. Switched the surefire provider to surefire-junit4. This, in fact, executed all tests, but we ran into other problems.

  4. Ran mvn -X, mainly to look for testng problems, based on this answer: Surefire is not picking up Junit 4 tests.

  5. mvn -X showed that the default maven-resources-plugin pulls in junit 3.8.x, which the doc says might cause problems. Updated resources to 3.1.0, but it didn't fix my problem.

mnv -X output

Is way too big to include. If you want part of it, please ask.

bobanahalf
  • 829
  • 1
  • 11
  • 23
  • Why do you feel the need to add the `surefire-junit47` dependency at all? It is not normally needed. – Steve C Jul 10 '19 at 15:11
  • We have testng included as a dependency in another project, which is in turn a dependency of this one. With testng on the classpath, surefire tries to execute tests through testng. So we're configuring our test execution based on this page: https://maven.apache.org/surefire/maven-surefire-plugin/examples/testng.html – bobanahalf Jul 10 '19 at 17:12
  • Does it work just to exclude the testng transitive dependency from the other dependency, if it's not going to be used by the current project build? – user944849 Jul 10 '19 at 18:59
  • Project test dependencies should be independent of each other. Are they all scoped as `test`? – Steve C Jul 10 '19 at 23:21

1 Answers1

1

Turns out that maven is, in fact, running the tests. The reason I thought it was not running the tests is because of changes in how JunitCore() works in 4.7+.

It seems that junit4 processes test class statics (and static @Parameters methods) class by class, where junit47 processes all statics, then runs all tests. So you'd get:

junit4
- ClassA
  - staticField1
  - staticMethod1
  - testMethod1
- ClassB
  - staticField2
  - staticMethod2
  - testMethod2


junit47
- Initialize:
  - ClassA
    - staticField1
    - staticMethod1
  - ClassB
    - staticField2
    - staticMethod2
- ClassA
  - testMethod1
- ClassB
  - testMethod2

More detail on this, from someone who understands it better than me, in this thread: https://issues.apache.org/jira/browse/SUREFIRE-1676?filter=-2

bobanahalf
  • 829
  • 1
  • 11
  • 23