Skip to content

Commit 6f1db59

Browse files
authored
DSL Polishing & Migration (#39)
* Completed migration to new DSL location for junitPlatform & dependency handlers Dependency Handlers: * Replaced junit5() with junit5.unitTests() * Replaced junit5Params() with junit5.parameterized() * Replaced junit5EmbeddedRuntime() with junit5.unitTestsRuntime() * Added junit5.instrumentationTests() (Backwards-compatible versions of the old handlers are still available, however they log a warning when used.) Moved junitPlatform DSL from <root> to android.testOptions (Backwards-compatible usage of the old DSL location is still allowed, however that logs a warning when used.) * Move Jacoco-related DSL to the new format * Move instrumentationTest "enabled" property to function invocation as well * Update renamed Gradle property * Sample module still referred to old property * Rename travis dir * Fix testenv * Upgraded README with the new info * Small brush-ups * Even more small brush-ups * ...and a typo * Release next version fixes #37, #38
1 parent c415fbc commit 6f1db59

File tree

22 files changed

+793
-273
lines changed

22 files changed

+793
-273
lines changed

.travis.yml

-5
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,6 @@ script: ./gradlew check --stacktrace
4343
after_success:
4444
- ./scripts/deploy_snapshot.sh
4545

46-
after_failure:
47-
- cat $TRAVIS_BUILD_DIR/tests/testCommon/build/reports/tests/test/index.html
48-
- cat $TRAVIS_BUILD_DIR/tests/testAgp2x/build/reports/tests/test/index.html
49-
- cat $TRAVIS_BUILD_DIR/tests/testAgp3x/build/reports/tests/test/index.html
50-
5146
deploy:
5247
provider: script
5348
script: ./scripts/deploy_release.sh

README.md

+99-56
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,26 @@
44

55
A Gradle plugin that allows for the execution of [JUnit 5][junit5gh] tests in Android environments.
66

7+
## Why a separate plugin?
8+
9+
The JUnit Platform team provides a Gradle plugin for running JUnit 5 on the JVM. However,
10+
this plugin is tailored to the needs of a "purely Java" application, and doesn't work in
11+
the context of the multi-variant world that we live in on Android. Therefore, this plugin was born.
12+
13+
It configures a `junitPlatformTest` task for each registered build variant of a project.
14+
Furthermore, it automatically attaches both the Jupiter & Vintage Engines
15+
during the execution phase of your tests as well, so there's very little configuration
16+
necessary to get your project up-and-running on the JUnit Platform.
17+
18+
Instructions on how to write JUnit 5 tests can be found [in their User Guide][junit5ug].
19+
Furthermore, this repository provides a small showcase of the functionality provided by JUnit 5 [here][sampletests].
20+
721
## Download
822

923
```groovy
1024
buildscript {
1125
dependencies {
12-
classpath "de.mannodermaus.gradle.plugins:android-junit5:1.0.21"
26+
classpath "de.mannodermaus.gradle.plugins:android-junit5:1.0.22"
1327
}
1428
}
1529
```
@@ -23,32 +37,99 @@ apply plugin: "com.android.application"
2337
apply plugin: "de.mannodermaus.android-junit5"
2438
2539
dependencies {
26-
testImplementation junit5()
40+
// (Required) Writing and executing Unit Tests on the JUnit Platform.
41+
testImplementation junit5.unitTests()
2742
28-
// (Optional) If you need "parameterized tests"
29-
testImplementation junit5Params()
43+
// (Optional) If you need "Parameterized Tests".
44+
testImplementation junit5.parameterized()
3045
31-
// (Optional) For running tests inside Android Studio 3.x (see below for details)
32-
testCompileOnly junit5EmbeddedRuntime()
46+
// (Optional) For running tests inside Android Studio 3.x
47+
// Please refer to the "Android Studio Workarounds" section for more insight on this.
48+
testCompileOnly junit5.unitTestsRuntime()
49+
50+
// (Optional) Writing and executing Instrumented Tests with the JUnit Platform Runner.
51+
//
52+
// IMPORTANT:
53+
// By declaring this dependency, you have to use a minSdkVersion
54+
// of at least 26, since the nature of JUnit 5 relies on APIs that aren't
55+
// available on Android devices before then.
56+
// Additionally, you are required to explicitly enable support for instrumented tests in the
57+
// "junitPlatform" configuration closure (see the section below for details).
58+
androidTestImplementation junit5.instrumentationTests()
3359
}
3460
```
3561

36-
## Usage
62+
## Configuration
3763

38-
This plugin configures a `junitPlatformTest` task for each registered build variant of a project.
39-
It automatically attaches both the Jupiter & Vintage Engines during the execution phase of your tests as well.
64+
The plugin applies a configuration closure to your module's `android.testOptions`.
65+
Inside it, you can use [all properties available through the default JUnit 5 Gradle plugin][junit5config].
66+
However, there are a few more parameters that allow for more customization of the JUnit Platform
67+
in your Android project. These are detailed below, alongside their default values:
4068

41-
More instructions on how to write JUnit 5 tests can be found [in their User Guide][junit5ug].
42-
Furthermore, this repository provides a small showcase of the functionality provided by JUnit 5 [here][sampletests].
69+
```groovy
70+
android {
71+
testOptions {
72+
// Configuration closure added by the plugin;
73+
// all configurable parameters related to JUnit 5 can be found here
74+
junitPlatform {
75+
// The JUnit Jupiter dependency version to use
76+
jupiterVersion "5.0.2"
77+
78+
// The JUnit Vintage Engine dependency version to use
79+
vintageVersion "4.12.2"
80+
81+
// Whether or not JUnit 5 test tasks should be affected by
82+
// JVM Arguments, System Properties & Environment Variables
83+
// declared through "unitTests.all" closures
84+
applyDefaultTestOptions true
85+
86+
// Options related to running instrumented tests with JUnit 5.
87+
// This is an incubating feature which utilizes the backwards-compatibility
88+
// of the JUnit Platform in order to enhance the default Test Instrumentation Runner
89+
// with new power. However, because of their experimental nature and steep minSdkVersion requirement,
90+
// they are turned off by default. If you choose to enable them, you also have to declare
91+
// the library dependency in your androidTest scope. Please refer to the "Setup"
92+
// section for more details.
93+
instrumentationTests {
94+
enabled false
95+
96+
// The Android-Instrumentation-Test dependency version to use
97+
version "0.1.0"
98+
}
99+
100+
// Configuration of companion tasks for JaCoCo Reports,
101+
// associated with each JUnit 5 task generated by the plugin.
102+
// Just like the companion tasks themselves, these properties
103+
// will only have an effect if your module declares the "jacoco" plugin as well.
104+
// For each of the available report types, you can toggle the availability
105+
// and destination folders that they write to.
106+
jacoco {
107+
xml {
108+
enabled true
109+
destination project.file()
110+
}
111+
html {
112+
enabled true
113+
destination project.file()
114+
}
115+
csv {
116+
enabled true
117+
destination project.file()
118+
}
119+
}
120+
}
121+
}
122+
}
123+
```
43124

44125
## Android Studio Workarounds
45126

46127
> **Note:**
47-
>
128+
>
48129
> The following section deals with fixing Test Execution within **Android Studio 3**.
49130
> Running your JUnit 5 tests directly from Android Studio 2.3.3 and earlier **will not work**:
50131
> You will encounter an `AbstractMethodError` when trying to do so ([more information here][as2issue]).
51-
>
132+
>
52133
> The cause of this error is similar in nature to the one described below, and related to outdated APIs.
53134
> Unlike that issue though, we can't fix the `AbstractMethodError` inside IntelliJ's internal runtime
54135
> in the same way. Therefore, please resort to using Gradle for unit testing in Android Studio 2.
@@ -73,52 +154,13 @@ To use this, add the following line alongside the other `junit5()` dependencies:
73154

74155
```groovy
75156
dependencies {
76-
testCompileOnly junit5EmbeddedRuntime()
77-
}
78-
```
79-
80-
## Extras
81-
82-
### Override Dependency Versions
83-
84-
Inside the configuration closure applied by the plugin, you can specify the same properties as you would
85-
for a Java-based project with the JUnit Platform Gradle plugin.
86-
However, there are some additional properties that you can apply:
87-
88-
```groovy
89-
junitPlatform {
90-
// The JUnit Jupiter dependency version to use; matches the platform's version by default
91-
jupiterVersion "5.0.2"
92-
// The JUnit Vintage Engine dependency version to use; matches the platform's version by default
93-
vintageVersion "4.12.2"
94-
}
95-
```
96-
97-
### JaCoCo Integration
98-
99-
If the plugin detects the usage of [JaCoCo][jacoco] inside a project that it's being applied to,
100-
it will automatically configure additional tasks to report the unit test coverage
101-
of your application based on its JUnit 5 tests.
102-
There is no additional setup required to enable this behaviour.
103-
You can however customize the reports JaCoCo should generate.
104-
105-
Configuration is applied through the `jacoco` clause inside the plugin's DSL:
106-
107-
```groovy
108-
apply plugin: "jacoco"
109-
110-
junitPlatform {
111-
jacoco {
112-
csvReport true
113-
xmlReport true
114-
htmlReport true
115-
}
157+
testCompileOnly junit5.unitTestsRuntime()
116158
}
117159
```
118160

119161
## Licenses
120162

121-
#### `android-junit5-embedded-runtime`
163+
#### android-junit5-embedded-runtime:
122164

123165
```
124166
Copyright 2000-2016 JetBrains s.r.o.
@@ -138,7 +180,7 @@ limitations under the License.
138180

139181
See also the [full License text](android-junit5-embedded-runtime/LICENSE).
140182

141-
#### Others:
183+
#### Everything else:
142184

143185
```
144186
Copyright 2017 Marcel Schnelle
@@ -161,7 +203,8 @@ See also the [full License text](LICENSE).
161203

162204

163205
[junit5gh]: https://github.com/junit-team/junit5
164-
[junit5ug]: http://junit.org/junit5/docs/current/user-guide
206+
[junit5ug]: https://junit.org/junit5/docs/current/user-guide
207+
[junit5config]: http://junit.org/junit5/docs/current/user-guide/#running-tests-build-gradle-junit-configure
165208
[travisci]: https://travis-ci.org/mannodermaus/android-junit5
166209
[as2issue]: https://github.com/mannodermaus/android-junit5/issues/19
167210
[jacoco]: http://www.eclemma.org/jacoco

android-junit5-tests/common.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ tasks.withType(WriteClasspathResource).all {
3535

3636
test.testLogging {
3737
events "passed", "skipped", "failed"
38+
exceptionFormat = "full"
3839
}
3940

4041
dependencies {

android-junit5-tests/testAgp2x/src/test/groovy/de/mannodermaus/gradle/plugins/junit5/AGP2PluginSpec.groovy

+11-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import de.mannodermaus.gradle.plugins.junit5.tasks.AndroidJUnit5JacocoReport
44
import de.mannodermaus.gradle.plugins.junit5.tasks.AndroidJUnit5UnitTest
55
import de.mannodermaus.gradle.plugins.junit5.util.TaskUtils
66
import org.gradle.api.Project
7+
import org.gradle.api.ProjectConfigurationException
78

89
/*
910
* Unit testing the integration of JUnit 5
@@ -78,33 +79,28 @@ class AGP2PluginSpec extends BasePluginSpec {
7879
expectedVariantTasks.each { assert runAllTask.getDependsOn().contains(it) }
7980
}
8081

81-
def "Instrumentation Test Integration: Works with Product Flavors"() {
82+
def "Instrumentation Test Integration: Attempting to use library without enabling throws Exception"() {
8283
when:
8384
Project project = factory.newProject(rootProject())
8485
.asAndroidApplication()
8586
.applyJunit5Plugin()
8687
.build()
8788

8889
project.android {
89-
productFlavors {
90-
paid {
91-
junit5InstrumentedTestsEnabled false
92-
}
93-
free {
94-
junit5InstrumentedTestsEnabled true
95-
}
90+
testOptions.junitPlatform.instrumentationTests {
91+
enabled = false
9692
}
9793
}
9894

95+
project.dependencies {
96+
androidTestCompile junit5.instrumentationTests()
97+
}
98+
9999
project.evaluate()
100100

101101
then:
102-
def enabledFlavor = project.android.productFlavors.getByName("free")
103-
def enabledArgs = enabledFlavor.getTestInstrumentationRunnerArguments()
104-
assert enabledArgs.containsKey("runnerBuilder")
105-
106-
def disabledFlavor = project.android.productFlavors.getByName("paid")
107-
def disabledArgs = disabledFlavor.getTestInstrumentationRunnerArguments()
108-
assert !disabledArgs.containsKey("runnerBuilder")
102+
def expect = thrown(ProjectConfigurationException)
103+
expect.message.contains("The JUnit 5 Instrumentation Test library can only be used " +
104+
"if support for them is explicitly enabled as well.")
109105
}
110106
}

android-junit5-tests/testAgp3x/src/test/groovy/de/mannodermaus/gradle/plugins/junit5/AGP3PluginSpec.groovy

+11-20
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import de.mannodermaus.gradle.plugins.junit5.tasks.AndroidJUnit5JacocoReport
44
import de.mannodermaus.gradle.plugins.junit5.tasks.AndroidJUnit5UnitTest
55
import de.mannodermaus.gradle.plugins.junit5.util.TaskUtils
66
import org.gradle.api.Project
7+
import org.gradle.api.ProjectConfigurationException
78

89
/*
910
* Unit testing the integration of JUnit 5
@@ -144,38 +145,28 @@ class AGP3PluginSpec extends BasePluginSpec {
144145
project.tasks.findByName("jacocoTestReportRelease") == null
145146
}
146147

147-
def "Instrumentation Test Integration: Works with Product Flavors"() {
148+
def "Instrumentation Test Integration: Attempting to use library without enabling throws Exception"() {
148149
when:
149150
Project project = factory.newProject(rootProject())
150151
.asAndroidApplication()
151152
.applyJunit5Plugin()
152153
.build()
153154

154155
project.android {
155-
// "All flavors must now belong to a named flavor dimension"
156-
flavorDimensions "price"
157-
158-
productFlavors {
159-
paid {
160-
dimension "price"
161-
junit5InstrumentedTestsEnabled false
162-
}
163-
free {
164-
dimension "price"
165-
junit5InstrumentedTestsEnabled true
166-
}
156+
testOptions.junitPlatform.instrumentationTests {
157+
enabled = false
167158
}
168159
}
169160

161+
project.dependencies {
162+
androidTestImplementation junit5.instrumentationTests()
163+
}
164+
170165
project.evaluate()
171166

172167
then:
173-
def enabledFlavor = project.android.productFlavors.getByName("free")
174-
def enabledArgs = enabledFlavor.getTestInstrumentationRunnerArguments()
175-
assert enabledArgs.containsKey("runnerBuilder")
176-
177-
def disabledFlavor = project.android.productFlavors.getByName("paid")
178-
def disabledArgs = disabledFlavor.getTestInstrumentationRunnerArguments()
179-
assert !disabledArgs.containsKey("runnerBuilder")
168+
def expect = thrown(ProjectConfigurationException)
169+
expect.message.contains("The JUnit 5 Instrumentation Test library can only be used " +
170+
"if support for them is explicitly enabled as well.")
180171
}
181172
}

0 commit comments

Comments
 (0)