Test not run when using TestNG and JUnit5

Hi, Gradle
I use macOS and Gradle 4.10, one of my war project uses TestNG and JUnit5 and has the standard java directories. When I run gradle test -i --rerun-tasks, I can see the test compile is good but test running is zero. I don’t know where did I miss and how can I see the details of test?

Here is part of my build.gradle:

apply plugin: 'war'

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    testCompile("org.junit.jupiter:junit-jupiter-api:5.3.0")
    testRuntime("org.junit.jupiter:junit-jupiter-engine:5.3.0")
    testCompile "org.testng:testng:6.10"
}
test {
    testLogging.showStandardStreams = true
    useTestNG()
    useJUnitPlatform {
        includeEngines 'junit-jupiter'
    }
}

Cheers

I think gradle can run either JUnit or TestNG tests, but not both of them in a single test task.
What we did was creating a second task for TestNG tests:

		task testNg(type: Test) {
			useTestNG()
			// Make the task show up in "verification" category, in "gradle tasks" output and in IDEA's gradle toolwindow
			group = 'Verification'
			description = 'Runs the TestNG tests'
		}
		check.dependsOn testNg

But I am not if this is really your problem, because neither sort of tests run for you (but maybe that is because using both useTestNG() and useJUnitPlatform in a single test task).

1 Like

@eekboom Thanks a lot. It works. And I add one more task for JUnit:

task testJUnit(type: Test){
    useJUnitPlatform {
        includeEngines 'junit-jupiter'
    }
}

Now, I can run them separately. Greet!
Only one little thing left: testNG seems not writing to the report after running. Any idea to fix it?

You can create another test task for JUnit, but you could also just configure the existing test task:

test {
    useJUnitPlatform {
        includeEngines 'junit-jupiter'
    }
}

As for the test reports: We configure both test tasks with

reports.html.enabled = false

Then use this to generate a consolidated report:

task testReport(type: TestReport) {
	destinationDir = file("$buildDir/reports/tests")
	reportOn testNg, test
	group = 'Verification'
	description = 'Generates a consolidated test report for both JUnit and TestNG tests'
}
check.dependsOn testReport

(then you can remove the “check.dependsOn testNG”)

One last trick (hack?) that we did: We want to always execute both types of tests (continue with TestNG tests even if there were test failures with JUnit tests). This is our solution (don’t know if there’s a better way):

	// We have both Spock (TestNG) and JUnit tests.
	// gradle can run only one type of test per test task.
	// We want both types of test to be run, even if tests of one type fail.
	// So the two test tasks are configured to continue on test failure.
	// To fail the build if any tests fail, this variable is updated via a test listener
	def allTestsOk = true

	def testListener = { TestDescriptor testDescriptor, TestResult testResult ->
		allTestsOk &= (testResult.resultType != TestResult.ResultType.FAILURE)
	}
	// Explicitly fail the build if there were any test failures in JUnit or TestNG tests
	check {
		doLast {
			if (!allTestsOk) {
				throw new GradleException("""
#######################################################################################################################
There were test failures. See console output or test report at ${new File(testReportDir, 'index.html')}.
############################################################################ #######################################
"""
				)
			}
		}
	}

Then add this to both test tasks:

		// so that the other test task (JUNit vs. TestNG) still runs, if failures occur:
		test.ignoreFailures true