1
1
package org.neotech.plugin.rootcoverage
2
2
3
3
import com.google.common.truth.Truth.assertThat
4
- import groovy.text.SimpleTemplateEngine
5
4
import org.gradle.testkit.runner.BuildResult
6
5
import org.gradle.testkit.runner.GradleRunner
7
- import org.gradle.testkit.runner.TaskOutcome
8
6
import org.junit.Assume
9
7
import org.junit.Before
10
8
import org.junit.Test
11
9
import org.junit.runner.RunWith
12
10
import org.junit.runners.Parameterized
13
11
import org.neotech.plugin.rootcoverage.util.SimpleTemplate
14
12
import org.neotech.plugin.rootcoverage.util.SystemOutputWriter
13
+ import org.neotech.plugin.rootcoverage.util.assertSuccessful
14
+ import org.neotech.plugin.rootcoverage.util.assertTaskSuccess
15
15
import org.neotech.plugin.rootcoverage.util.createGradlePropertiesFile
16
16
import org.neotech.plugin.rootcoverage.util.createLocalPropertiesFile
17
- import org.neotech.plugin.rootcoverage.util.getProperties
18
17
import org.neotech.plugin.rootcoverage.util.put
18
+ import org.neotech.plugin.rootcoverage.util.readYaml
19
19
import org.neotech.plugin.rootcoverage.util.toGroovyString
20
20
import java.io.File
21
21
import java.util.Properties
@@ -29,23 +29,47 @@ class IntegrationTest(
29
29
private val gradleVersion : String ,
30
30
) {
31
31
32
- private val configuration = configurationFile.getProperties ()
32
+ private val configuration: TestConfiguration = configurationFile.readYaml ()
33
33
34
34
@Before
35
- fun before (){
35
+ fun before () {
36
36
// 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
38
39
Assume .assumeFalse(System .getenv(" GITHUB_ACTIONS" ) != null && isGradleManagedDeviceTest)
39
40
}
40
41
41
42
@Test
42
43
fun execute () {
43
- val template = SimpleTemplate ().apply {
44
- putValue(" configuration" , configuration.toGroovyString())
45
- }
46
44
45
+ val templateRootBuildGradleFile = SimpleTemplate ().apply {
46
+ putValue(" configuration" , configuration.pluginConfiguration.properties.toGroovyString())
47
+ }
47
48
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 ))
49
73
}
50
74
51
75
createLocalPropertiesFile(projectRoot)
@@ -57,23 +81,31 @@ class IntegrationTest(
57
81
})
58
82
})
59
83
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
+
60
92
val runner = GradleRunner .create()
61
93
.withProjectDir(projectRoot)
62
94
.withGradleVersion(gradleVersion)
63
95
.withPluginClasspath()
64
96
.forwardStdOutput(SystemOutputWriter .out ())
65
97
.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)
70
99
71
100
val result = runner.build()
72
101
73
- assertThat(result.output).contains(" BUILD SUCCESSFUL" )
102
+ result.assertSuccessful()
103
+
104
+ // Assert whether the correct Android Test tasks are executed
105
+ result.assertCorrectAndroidTestTasksAreExecuted()
74
106
75
107
// Assert whether the combined coverage report is what we expected
76
- result.assertRootCoverageReport(File (projectRoot, " build/reports/jacoco.csv " ) )
108
+ result.assertRootCoverageReport()
77
109
78
110
// Assert whether the per module coverage reports are what we expect
79
111
result.assertAppCoverageReport()
@@ -82,13 +114,27 @@ class IntegrationTest(
82
114
assertSourceFilesHaveBeenAddedToReport(File (projectRoot, " build/reports/jacoco" ))
83
115
}
84
116
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" )
87
133
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" )
90
136
91
- val report = CoverageReport .from(file )
137
+ val report = CoverageReport .from(File (projectRoot, " build/reports/jacoco.csv " ) )
92
138
93
139
report.assertCoverage(" org.neotech.library.android" , " LibraryAndroidJava" )
94
140
report.assertCoverage(" org.neotech.library.android" , " LibraryAndroidKotlin" )
@@ -98,19 +144,7 @@ class IntegrationTest(
98
144
}
99
145
100
146
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" )
114
148
val report = CoverageReport .from(File (projectRoot, " app/build/reports/jacoco.csv" ))
115
149
116
150
report.assertNotInReport(" org.neotech.app" , " MustBeExcluded" )
@@ -120,7 +154,7 @@ class IntegrationTest(
120
154
}
121
155
122
156
private fun BuildResult.assertAndroidLibraryCoverageReport () {
123
- assertThat(task( " :library_android:coverageReport" ) !! .outcome).isEqualTo( TaskOutcome . SUCCESS )
157
+ assertTaskSuccess( " :library_android:coverageReport" )
124
158
125
159
val report = CoverageReport .from(File (projectRoot, " library_android/build/reports/jacoco.csv" ))
126
160
@@ -159,22 +193,38 @@ class IntegrationTest(
159
193
@JvmStatic
160
194
fun parameters (): List <Array <Any >> {
161
195
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
+
164
198
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
+ )
176
209
}
177
210
}
178
211
}
179
212
}
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
+ }
180
230
}
0 commit comments