11package org.neotech.plugin.rootcoverage
22
33import com.google.common.truth.Truth.assertThat
4- import groovy.text.SimpleTemplateEngine
54import org.gradle.testkit.runner.BuildResult
65import org.gradle.testkit.runner.GradleRunner
7- import org.gradle.testkit.runner.TaskOutcome
86import org.junit.Assume
97import org.junit.Before
108import org.junit.Test
119import org.junit.runner.RunWith
1210import org.junit.runners.Parameterized
1311import org.neotech.plugin.rootcoverage.util.SimpleTemplate
1412import org.neotech.plugin.rootcoverage.util.SystemOutputWriter
13+ import org.neotech.plugin.rootcoverage.util.assertSuccessful
14+ import org.neotech.plugin.rootcoverage.util.assertTaskSuccess
1515import org.neotech.plugin.rootcoverage.util.createGradlePropertiesFile
1616import org.neotech.plugin.rootcoverage.util.createLocalPropertiesFile
17- import org.neotech.plugin.rootcoverage.util.getProperties
1817import org.neotech.plugin.rootcoverage.util.put
18+ import org.neotech.plugin.rootcoverage.util.readYaml
1919import org.neotech.plugin.rootcoverage.util.toGroovyString
2020import java.io.File
2121import java.util.Properties
@@ -29,23 +29,47 @@ class IntegrationTest(
2929 private val gradleVersion : String ,
3030) {
3131
32- private val configuration = configurationFile.getProperties ()
32+ private val configuration: TestConfiguration = configurationFile.readYaml ()
3333
3434 @Before
35- fun before (){
35+ fun before () {
3636 // Ignore tests that require Gradle Managed Devices on CI (because GitHub Actions does not seem to support these well).
37- val isGradleManagedDeviceTest = configuration.getProperty(" runOnGradleManagedDevices" , " false" ).toBoolean()
37+ val isGradleManagedDeviceTest =
38+ configuration.pluginConfiguration.getPropertyValue(" runOnGradleManagedDevices" )?.toBoolean() ? : false
3839 Assume .assumeFalse(System .getenv(" GITHUB_ACTIONS" ) != null && isGradleManagedDeviceTest)
3940 }
4041
4142 @Test
4243 fun execute () {
43- val template = SimpleTemplate ().apply {
44- putValue(" configuration" , configuration.toGroovyString())
45- }
4644
45+ val templateRootBuildGradleFile = SimpleTemplate ().apply {
46+ putValue(" configuration" , configuration.pluginConfiguration.properties.toGroovyString())
47+ }
4748 File (projectRoot, " build.gradle.tmp" ).inputStream().use {
48- File (projectRoot, " build.gradle" ).writeText(template.process(it, Charsets .UTF_8 ))
49+ File (projectRoot, " build.gradle" ).writeText(templateRootBuildGradleFile.process(it, Charsets .UTF_8 ))
50+ }
51+
52+ val templateAppBuildGradleFile = SimpleTemplate ().apply {
53+ putValue(
54+ " managedDevices" , if (configuration.projectConfiguration.addGradleManagedDevice) {
55+ """
56+ managedDevices {
57+ devices {
58+ nexusoneapi30 (com.android.build.api.dsl.ManagedVirtualDevice) {
59+ device = "Nexus One"
60+ apiLevel = 30
61+ systemImageSource = "aosp-atd"
62+ }
63+ }
64+ }
65+ """ .trimIndent()
66+ } else {
67+ " "
68+ }
69+ )
70+ }
71+ File (projectRoot, " app/build.gradle.tmp" ).inputStream().use {
72+ File (projectRoot, " app/build.gradle" ).writeText(templateAppBuildGradleFile.process(it, Charsets .UTF_8 ))
4973 }
5074
5175 createLocalPropertiesFile(projectRoot)
@@ -57,23 +81,31 @@ class IntegrationTest(
5781 })
5882 })
5983
84+ // Note: rootCodeCoverageReport is the old and deprecated name of the rootCoverageReport task, it is
85+ // used to check whether the old name properly aliases to the new task name.
86+ val gradleCommands = if (configuration.pluginConfiguration.getPropertyValue(" executeAndroidTests" ) == " false" ) {
87+ listOf (" clean" , " connectedDebugAndroidTest" , " coverageReport" , " rootCodeCoverageReport" , " --stacktrace" )
88+ } else {
89+ listOf (" clean" , " coverageReport" , " rootCodeCoverageReport" , " --stacktrace" )
90+ }
91+
6092 val runner = GradleRunner .create()
6193 .withProjectDir(projectRoot)
6294 .withGradleVersion(gradleVersion)
6395 .withPluginClasspath()
6496 .forwardStdOutput(SystemOutputWriter .out ())
6597 .forwardStdError(SystemOutputWriter .err())
66-
67- // Note: rootCodeCoverageReport is the old and deprecated name of the rootCoverageReport task, it is
68- // used to check whether the old name properly aliases to the new task name.
69- .withArguments(" clean" , " coverageReport" , " rootCodeCoverageReport" , " --stacktrace" )
98+ .withArguments(gradleCommands)
7099
71100 val result = runner.build()
72101
73- assertThat(result.output).contains(" BUILD SUCCESSFUL" )
102+ result.assertSuccessful()
103+
104+ // Assert whether the correct Android Test tasks are executed
105+ result.assertCorrectAndroidTestTasksAreExecuted()
74106
75107 // Assert whether the combined coverage report is what we expected
76- result.assertRootCoverageReport(File (projectRoot, " build/reports/jacoco.csv " ) )
108+ result.assertRootCoverageReport()
77109
78110 // Assert whether the per module coverage reports are what we expect
79111 result.assertAppCoverageReport()
@@ -82,13 +114,27 @@ class IntegrationTest(
82114 assertSourceFilesHaveBeenAddedToReport(File (projectRoot, " build/reports/jacoco" ))
83115 }
84116
85- private fun BuildResult.assertRootCoverageReport (file : File ) {
86- assertThat(task(" :rootCoverageReport" )!! .outcome).isEqualTo(TaskOutcome .SUCCESS )
117+ private fun BuildResult.assertCorrectAndroidTestTasksAreExecuted () {
118+ if (configuration.pluginConfiguration.getPropertyValue(" runOnGradleManagedDevices" , " false" ).toBoolean()) {
119+ // Assert that the tests have been run on Gradle Managed Devices
120+ val device = configuration.pluginConfiguration.getPropertyValue(" gradleManagedDeviceName" , " allDevices" )
121+ assertTaskSuccess(" :app:${device} DebugAndroidTest" )
122+ assertTaskSuccess(" :library_android:${device} DebugAndroidTest" )
123+
124+ } else {
125+ // Assert that the tests have been run on connected devices
126+ assertTaskSuccess(" :app:connectedDebugAndroidTest" )
127+ assertTaskSuccess(" :library_android:connectedDebugAndroidTest" )
128+ }
129+ }
130+
131+ private fun BuildResult.assertRootCoverageReport () {
132+ assertTaskSuccess(" :rootCoverageReport" )
87133
88- // Also check if the old task name is still exe
89- assertThat(task( " :rootCodeCoverageReport" ) !! .outcome).isEqualTo( TaskOutcome . SUCCESS )
134+ // Also check if the old task name is still executed
135+ assertTaskSuccess( " :rootCodeCoverageReport" )
90136
91- val report = CoverageReport .from(file )
137+ val report = CoverageReport .from(File (projectRoot, " build/reports/jacoco.csv " ) )
92138
93139 report.assertCoverage(" org.neotech.library.android" , " LibraryAndroidJava" )
94140 report.assertCoverage(" org.neotech.library.android" , " LibraryAndroidKotlin" )
@@ -98,19 +144,7 @@ class IntegrationTest(
98144 }
99145
100146 private fun BuildResult.assertAppCoverageReport () {
101- assertThat(task(" :app:coverageReport" )!! .outcome).isEqualTo(TaskOutcome .SUCCESS )
102-
103- if (configuration.getProperty(" runOnGradleManagedDevices" , " false" ).toBoolean()) {
104- // Assert that the tests have been run on Gradle Managed Devices
105- val device = configuration.getProperty(" gradleManagedDeviceName" , " allDevices" )
106- assertThat(task(" :app:${device} DebugAndroidTest" )!! .outcome).isEqualTo(TaskOutcome .SUCCESS )
107- assertThat(task(" :library_android:${device} DebugAndroidTest" )!! .outcome).isEqualTo(TaskOutcome .SUCCESS )
108- } else {
109- // Assert that the tests have been run on connected devices
110- assertThat(task(" :app:connectedDebugAndroidTest" )!! .outcome).isEqualTo(TaskOutcome .SUCCESS )
111- assertThat(task(" :library_android:connectedDebugAndroidTest" )!! .outcome).isEqualTo(TaskOutcome .SUCCESS )
112- }
113-
147+ assertTaskSuccess(" :app:coverageReport" )
114148 val report = CoverageReport .from(File (projectRoot, " app/build/reports/jacoco.csv" ))
115149
116150 report.assertNotInReport(" org.neotech.app" , " MustBeExcluded" )
@@ -120,7 +154,7 @@ class IntegrationTest(
120154 }
121155
122156 private fun BuildResult.assertAndroidLibraryCoverageReport () {
123- assertThat(task( " :library_android:coverageReport" ) !! .outcome).isEqualTo( TaskOutcome . SUCCESS )
157+ assertTaskSuccess( " :library_android:coverageReport" )
124158
125159 val report = CoverageReport .from(File (projectRoot, " library_android/build/reports/jacoco.csv" ))
126160
@@ -159,22 +193,38 @@ class IntegrationTest(
159193 @JvmStatic
160194 fun parameters (): List <Array <Any >> {
161195
162- val testFixtures =
163- File ( " src/test/test-fixtures " ).listFiles()?.filter { it.isDirectory } ? : error( " Could not list test fixture directories " )
196+ val fixture = File ( " src/test/test-fixtures/multi-module " )
197+
164198 val gradleVersions = arrayOf(" 7.5" , " 7.5.1" , " 7.6" , " 7.6.1" )
165- return testFixtures.flatMap { fixture ->
166- val configurations = File (fixture, " configurations" ).listFiles() ? : error(" Configurations folder not found in $fixture " )
167- configurations.flatMap { configuration ->
168- gradleVersions.map { gradleVersion ->
169- arrayOf(
170- " ${fixture.name} -${configuration.nameWithoutExtension} -$gradleVersion " ,
171- fixture,
172- configuration,
173- gradleVersion
174- )
175- }
199+
200+ val configurations = File (fixture, " configurations" ).listFiles() ? : error(" Configurations folder not found in $fixture " )
201+ return configurations.flatMap { configuration ->
202+ gradleVersions.map { gradleVersion ->
203+ arrayOf(
204+ " ${fixture.name} -${configuration.nameWithoutExtension} -$gradleVersion " ,
205+ fixture,
206+ configuration,
207+ gradleVersion
208+ )
176209 }
177210 }
178211 }
179212 }
213+
214+ data class TestConfiguration (
215+ val projectConfiguration : ProjectConfiguration ,
216+ val pluginConfiguration : PluginConfiguration
217+ ) {
218+ data class PluginConfiguration (val properties : List <Property > = emptyList()) {
219+
220+ fun getPropertyValue (name : String , defaultValue : String ): String = getPropertyValue(name) ? : defaultValue
221+
222+ fun getPropertyValue (name : String ): String? = properties.find { it.name == name }?.value
223+
224+
225+ data class Property (val name : String , val value : String )
226+ }
227+
228+ data class ProjectConfiguration (val addGradleManagedDevice : Boolean = true )
229+ }
180230}
0 commit comments