Skip to content

Commit e4504f9

Browse files
author
Marcel Schnelle
authored
Implement includeAndroidResources & returnDefaultValues API (#80)
1 parent e5e1a7e commit e4504f9

File tree

6 files changed

+239
-27
lines changed

6 files changed

+239
-27
lines changed

android-junit5-tests/build.gradle

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,12 @@ processTestResources {
4646
}
4747
}
4848

49-
test.testLogging {
50-
events "passed", "skipped", "failed"
51-
exceptionFormat = "full"
49+
test {
50+
failFast = true
51+
testLogging {
52+
events "passed", "skipped", "failed"
53+
exceptionFormat = "full"
54+
}
5255
}
5356

5457
junitPlatform {

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

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,82 @@ class FunctionalSpec extends Specification {
283283
result.output.contains("KotlinAdderTest")
284284
}
285285

286+
def "Returns default values successfully"() {
287+
given:
288+
androidPlugin()
289+
junit5Plugin("""
290+
unitTests {
291+
returnDefaultValues = true
292+
}
293+
""")
294+
test(language: FileLanguage.Java,
295+
content: """
296+
package de.mannodermaus.app;
297+
298+
import static org.junit.jupiter.api.Assertions.assertNull;
299+
300+
import org.junit.jupiter.api.Test;
301+
import android.content.Intent;
302+
303+
class AndroidTest {
304+
@Test
305+
void test() {
306+
Intent intent = new Intent();
307+
assertNull(intent.getAction());
308+
}
309+
}
310+
""")
311+
GradleRunner runner = runGradle()
312+
313+
when:
314+
BuildResult result = runner
315+
.withArguments("junitPlatformTestDebug")
316+
.build()
317+
318+
then:
319+
result.task(":junitPlatformTestDebug").outcome == TaskOutcome.SUCCESS
320+
result.output.contains("1 tests successful")
321+
result.output.contains("AndroidTest")
322+
}
323+
324+
def "Includes Android resources successfully"() {
325+
given:
326+
androidPlugin()
327+
junit5Plugin("""
328+
unitTests {
329+
includeAndroidResources = true
330+
}
331+
""")
332+
test(language: FileLanguage.Java,
333+
content: """
334+
package de.mannodermaus.app;
335+
336+
import static org.junit.jupiter.api.Assertions.assertNotNull;
337+
338+
import org.junit.jupiter.api.Test;
339+
import java.io.InputStream;
340+
341+
class AndroidTest {
342+
@Test
343+
void test() {
344+
InputStream is = getClass().getResourceAsStream("/com/android/tools/test_config.properties");
345+
assertNotNull(is);
346+
}
347+
}
348+
""")
349+
GradleRunner runner = runGradle()
350+
351+
when:
352+
BuildResult result = runner
353+
.withArguments("junitPlatformTestDebug")
354+
.build()
355+
356+
then:
357+
result.task(":junitPlatformTestDebug").outcome == TaskOutcome.SUCCESS
358+
result.output.contains("1 tests successful")
359+
result.output.contains("AndroidTest")
360+
}
361+
286362
/*
287363
* ===============================================================================================
288364
* Helpers, Factories & Utilities
@@ -357,13 +433,14 @@ class FunctionalSpec extends Specification {
357433
"""
358434
}
359435

360-
protected final def junit5Plugin() {
436+
protected final def junit5Plugin(String extraConfig = "") {
361437
buildFile << """
362438
apply plugin: "de.mannodermaus.android-junit5"
363439
364440
android.testOptions {
365441
junitPlatform {
366442
details "flat"
443+
$extraConfig
367444
}
368445
}
369446

android-junit5-tests/src/test/kotlin/de/mannodermaus/gradle/plugins/junit5/PluginSpec.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,56 @@ class PluginSpec : Spek({
455455
}
456456
}
457457

458+
context("unitTests.returnDefaultValues") {
459+
val project by memoized { testProjectBuilder.build() }
460+
461+
listOf(true, false).forEach { state ->
462+
on("set to $state") {
463+
project.android.testOptions.junitPlatform.unitTests {
464+
returnDefaultValues = state
465+
}
466+
467+
project.evaluate()
468+
469+
it("configures the AGP setting correctly") {
470+
assertThat(project.android.testOptions.unitTests.isReturnDefaultValues)
471+
.isEqualTo(state)
472+
}
473+
474+
it("generates a mockable android.jar with the correct suffix") {
475+
val variant = ProjectConfig(project).unitTestVariants.first()
476+
val file = variant.variantData.scope.globalScope.mockableAndroidJarFile
477+
val assertion = assertThat(file.name)
478+
479+
if (state) {
480+
assertion.contains("default-values")
481+
} else {
482+
assertion.doesNotContain("default-values")
483+
}
484+
}
485+
}
486+
}
487+
}
488+
489+
context("unitTests.includeAndroidResources") {
490+
val project by memoized { testProjectBuilder.build() }
491+
492+
listOf(true, false).forEach { state ->
493+
on("set to $state") {
494+
project.android.testOptions.junitPlatform.unitTests {
495+
includeAndroidResources = state
496+
}
497+
498+
project.evaluate()
499+
500+
it("configures the AGP setting correctly") {
501+
assertThat(project.android.testOptions.unitTests.isIncludeAndroidResources)
502+
.isEqualTo(state)
503+
}
504+
}
505+
}
506+
}
507+
458508
context("jacoco integration") {
459509
beforeEachTest { testProjectBuilder.applyJacocoPlugin() }
460510

android-junit5/src/main/kotlin/de/mannodermaus/gradle/plugins/junit5/Dsl.kt

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ open class AndroidJUnitPlatformExtension(private val project: Project) {
4343
* The version of JUnit Platform to use
4444
*/
4545
var platformVersion: String? = null
46+
4647
fun platformVersion(version: String?) {
4748
this.platformVersion = version
4849
}
@@ -51,6 +52,7 @@ open class AndroidJUnitPlatformExtension(private val project: Project) {
5152
* The version of JUnit Jupiter to use
5253
*/
5354
var jupiterVersion: String? = null
55+
5456
fun jupiterVersion(version: String?) {
5557
this.jupiterVersion = version
5658
}
@@ -59,6 +61,7 @@ open class AndroidJUnitPlatformExtension(private val project: Project) {
5961
* The version of JUnit Vintage to use
6062
*/
6163
var vintageVersion: String? = null
64+
6265
fun vintageVersion(version: String?) {
6366
this.vintageVersion = version
6467
}
@@ -67,6 +70,7 @@ open class AndroidJUnitPlatformExtension(private val project: Project) {
6770
* The directory for the test report files
6871
*/
6972
var reportsDir: File? = null
73+
7074
fun reportsDir(reportsDir: File?) {
7175
// Work around for https://discuss.gradle.org/t/bug-in-project-file-on-windows/19917
7276
if (reportsDir is File) {
@@ -82,6 +86,7 @@ open class AndroidJUnitPlatformExtension(private val project: Project) {
8286
* system property to this value
8387
*/
8488
var logManager: String? = null
89+
8590
fun logManager(logManager: String?) {
8691
this.logManager = logManager
8792
}
@@ -90,6 +95,7 @@ open class AndroidJUnitPlatformExtension(private val project: Project) {
9095
* Whether or not the standard Gradle {@code test} task should be enabled
9196
*/
9297
var enableStandardTestTask = false
98+
9399
fun enableStandardTestTask(state: Boolean) {
94100
this.enableStandardTestTask = state
95101
}
@@ -98,6 +104,7 @@ open class AndroidJUnitPlatformExtension(private val project: Project) {
98104
* Select test execution plan details mode
99105
*/
100106
var details = Details.NONE
107+
101108
fun details(details: Details) {
102109
this.details = details
103110
}
@@ -157,7 +164,7 @@ open class AndroidJUnitPlatformExtension(private val project: Project) {
157164
*
158165
* @since 1.0.23
159166
*/
160-
val unitTests = UnitTestOptions()
167+
val unitTests = UnitTestOptions(project)
161168

162169
/**
163170
* Configures unit test options
@@ -462,7 +469,7 @@ open class IncludeExcludeContainer {
462469
/**
463470
* Options for controlling how JUnit 5 Unit Tests should be executed
464471
*/
465-
class UnitTestOptions {
472+
class UnitTestOptions(private val project: Project) {
466473

467474
operator fun invoke(config: UnitTestOptions.() -> Unit) {
468475
this.config()
@@ -482,10 +489,58 @@ class UnitTestOptions {
482489
* - environment variables
483490
*/
484491
var applyDefaultTestOptions = true
492+
485493
fun applyDefaultTestOptions(state: Boolean) {
486494
this.applyDefaultTestOptions = state
487495
}
488496

497+
/**
498+
* Whether unmocked methods from android.jar should throw exceptions or return default
499+
* values (i.e. zero or null).
500+
*
501+
* Defaults to false, which will throw exceptions on unmocked method invocations
502+
*
503+
* @since 1.0.32
504+
*/
505+
var returnDefaultValues: Boolean
506+
get() = project.android.testOptions.unitTests.isReturnDefaultValues
507+
set(value) {
508+
project.android.testOptions.unitTests.isReturnDefaultValues = value
509+
}
510+
511+
/**
512+
* Enables unit tests to use Android resources, assets, and manifests.
513+
* <p>
514+
* If you enable this setting, the Android Gradle Plugin performs resource, asset,
515+
* and manifest merging before running your unit tests. Your tests can then inspect a file
516+
* called {@code com/android/tools/test_config.properties} on the classpath, which is a Java
517+
* properties file with the following keys:
518+
*
519+
* <ul>
520+
* <li><code>android_sdk_home</code>: the absolute path to the Android SDK.
521+
* <li><code>android_merged_resources</code>: the absolute path to the merged resources
522+
* directory, which contains all the resources from this subproject and all its
523+
* dependencies.
524+
* <li><code>android_merged_assets</code>: the absolute path to the merged assets
525+
* directory. For app subprojects, the merged assets directory contains assets from
526+
* this subproject and its dependencies. For library subprojects, the merged assets
527+
* directory contains only the assets from this subproject.
528+
* <li><code>android_merged_manifest</code>: the absolute path to the merged manifest
529+
* file. Only app subprojects merge manifests of its dependencies. So, library
530+
* subprojects won't include manifest components from their dependencies.
531+
* <li><code>android_custom_package</code>: the package name of the final R class. If you
532+
* modify the application ID in your build scripts, this package name may not match
533+
* the <code>package</code> attribute in the final app manifest.
534+
* </ul>
535+
*
536+
* @since 1.0.32
537+
*/
538+
var includeAndroidResources: Boolean
539+
get() = project.android.testOptions.unitTests.isIncludeAndroidResources
540+
set(value) {
541+
project.android.testOptions.unitTests.isIncludeAndroidResources = value
542+
}
543+
489544
/**
490545
* Applies the provided config closure to all JUnit 5 test tasks,
491546
* and any task that'll be added in the future
@@ -535,6 +590,7 @@ class InstrumentationTestOptions {
535590
* Whether or not to enable support for JUnit 5 instrumentation tests
536591
*/
537592
var enabled: Boolean = true
593+
538594
fun enabled(state: Boolean) {
539595
this.enabled = state
540596
}
@@ -543,6 +599,7 @@ class InstrumentationTestOptions {
543599
* The version of the instrumentation companion library to use
544600
*/
545601
var version: String? = null
602+
546603
fun version(version: String?) {
547604
this.version = version
548605
}
@@ -562,6 +619,7 @@ class JacocoOptions {
562619
* Whether or not to enable Jacoco task integration
563620
*/
564621
var taskGenerationEnabled = true
622+
565623
fun taskGenerationEnabled(state: Boolean) {
566624
this.taskGenerationEnabled = state
567625
}
@@ -620,13 +678,15 @@ class JacocoOptions {
620678
* By default, this will exclude R.class & BuildConfig.class
621679
*/
622680
var excludedClasses = mutableListOf("**/R.class", "**/R$*.class", "**/BuildConfig.*")
681+
623682
fun excludedClasses(vararg classes: String) = excludedClasses.addAll(classes)
624683

625684
/**
626685
* List of source name patterns that should be excluded from being processed by Jacoco.
627686
* By default, this is an empty list
628687
*/
629688
var excludedSources = mutableListOf<String>()
689+
630690
fun excludedSources(vararg sources: String) = excludedSources.addAll(sources)
631691

632692
class Report {
@@ -639,6 +699,7 @@ class JacocoOptions {
639699
* Whether or not this report should be generated
640700
*/
641701
var enabled: Boolean = true
702+
642703
fun enabled(state: Boolean) {
643704
this.enabled = state
644705
}
@@ -649,6 +710,7 @@ class JacocoOptions {
649710
* each variant will be assigned a distinct folder if necessary
650711
*/
651712
var destination: File? = null
713+
652714
fun destination(file: File?) {
653715
this.destination = file
654716
}

0 commit comments

Comments
 (0)