Test not run when using TestNG and JUnit5

test-tag

(James Zhang) #1

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


(Stephen Friedrich) #2

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).


(James Zhang) #3

@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?


(Stephen Friedrich) #4

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