Browse Source

Housekeeping/7 integration testing

enhancement/speed-up-pipelines
Ryan Harg 3 years ago
parent
commit
7ddff0843f
  1. 12
      .gitlab-ci.yml
  2. 56
      app/build.gradle.kts
  3. 2
      app/src/main/java/audio/funkwhale/ffa/FFA.kt
  4. 27
      app/src/test/java/audio/funkwhale/ffa/activities/SplashActivityTest.kt
  5. 14
      build.gradle.kts
  6. 2
      buildSrc/src/main/java/Versions.kt

12
.gitlab-ci.yml

@ -1,7 +1,9 @@
image: jangrewe/gitlab-ci-android image: jangrewe/gitlab-ci-android
variables: variables:
JACOCO_CSV_LOCATION: '$CI_PROJECT_DIR/app/build/reports/jacoco/debug/jacoco.csv' COBERTURA_REPORT: '$CI_PROJECT_DIR/app/build/reports/cobertura.xml'
JACOCO_CSV_LOCATION: '$CI_PROJECT_DIR/app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.csv'
JACOCO_XML_LOCATION: '$CI_PROJECT_DIR/app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml'
stages: stages:
- test - test
@ -33,26 +35,26 @@ test:
extends: .gradle-default extends: .gradle-default
stage: test stage: test
script: script:
- ./gradlew test jacocoTestReportDebug - ./gradlew test jacocoTestReport
- awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print covered, "/", instructions, " instructions covered"; print 100*covered/instructions, "% covered" }' $JACOCO_CSV_LOCATION - awk -F"," '{ instructions += $4 + $5; covered += $5 } END { print covered, "/", instructions, " instructions covered"; print 100*covered/instructions, "% covered" }' $JACOCO_CSV_LOCATION
artifacts: artifacts:
reports: reports:
junit: app/build/test-results/test**/TEST-*.xml junit: app/build/test-results/test**/TEST-*.xml
paths: paths:
- app/build/reports/jacoco/debug/jacoco.xml - $JACOCO_XML_LOCATION
coverage: coverage:
stage: visualize stage: visualize
image: gjrtimmer/jacoco2cobertura:1.0.8 image: gjrtimmer/jacoco2cobertura:1.0.8
script: script:
# convert report from jacoco to cobertura, use relative project path # convert report from jacoco to cobertura, use relative project path
- 'python /opt/cover2cover.py app/build/reports/jacoco/debug/jacoco.xml $CI_PROJECT_DIR/app/src/main/java > app/build/reports/cobertura.xml' - 'python /opt/cover2cover.py $JACOCO_XML_LOCATION $CI_PROJECT_DIR/app/src/main/java > app/build/reports/cobertura.xml'
needs: [ "test" ] needs: [ "test" ]
dependencies: dependencies:
- test - test
artifacts: artifacts:
reports: reports:
cobertura: app/build/reports/cobertura.xml cobertura: $COBERTURA_REPORT
build-develop: build-develop:
extends: .build extends: .build

56
app/build.gradle.kts

@ -12,11 +12,6 @@ plugins {
id("de.mobilej.unmock") id("de.mobilej.unmock")
id("com.github.ben-manes.versions") id("com.github.ben-manes.versions")
jacoco jacoco
id("com.vanniktech.android.junit.jacoco")
}
junitJacoco {
jacocoVersion = Versions.jacoco
} }
val props = Properties().apply { val props = Properties().apply {
@ -41,6 +36,10 @@ android {
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
} }
testCoverage {
version = Versions.jacoco
}
kotlinOptions { kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString() jvmTarget = JavaVersion.VERSION_1_8.toString()
} }
@ -50,7 +49,7 @@ android {
} }
lint { lint {
disable += listOf("MissingTranslation","ExtraTranslation") disable += listOf("MissingTranslation", "ExtraTranslation")
} }
compileSdk = 30 compileSdk = 30
@ -104,6 +103,8 @@ android {
isDebuggable = true isDebuggable = true
applicationIdSuffix = ".dev" applicationIdSuffix = ".dev"
isTestCoverageEnabled = true
if (project.hasProperty("signing.store")) { if (project.hasProperty("signing.store")) {
signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.getByName("debug")
} }
@ -191,17 +192,58 @@ dependencies {
testImplementation("io.mockk:mockk:1.12.0") testImplementation("io.mockk:mockk:1.12.0")
testImplementation("androidx.test:core:1.4.0") testImplementation("androidx.test:core:1.4.0")
testImplementation("io.strikt:strikt-core:${Versions.strikt}") testImplementation("io.strikt:strikt-core:${Versions.strikt}")
testImplementation("org.robolectric:robolectric:${Versions.robolectric}")
androidTestImplementation("io.mockk:mockk-android:${Versions.mockk}") androidTestImplementation("io.mockk:mockk-android:${Versions.mockk}")
} }
project.afterEvaluate { project.afterEvaluate {
tasks.withType<JacocoReport> { tasks.withType<Test> {
configure<JacocoTaskExtension> {
isIncludeNoLocationClasses = true
excludes = listOf("jdk.internal.*")
}
}
tasks.create("jacocoTestReport", type = JacocoReport::class) {
dependsOn("testDebugUnitTest", "createDebugCoverageReport")
group = "Verification"
description = "Creates a Jacoco Coverage report"
reports { reports {
xml.required.set(true) xml.required.set(true)
csv.required.set(true) csv.required.set(true)
html.required.set(true) html.required.set(true)
} }
val fileFilter = listOf(
"**/R.class",
"**/R$*.class",
"**/BuildConfig.*",
"**/Manifest*.*",
"**/*Test*.*",
"android/**/*.*",
"**/*$[0-9].*"
)
val debugTree = fileTree("${project.buildDir}/tmp/kotlin-classes/debug") {
setExcludes(fileFilter)
}
val mainSrc = "${project.projectDir}/src/main/java"
sourceDirectories.setFrom(files(listOf(mainSrc)))
classDirectories.setFrom(files(listOf(debugTree)))
executionData.setFrom(fileTree(project.buildDir) {
setIncludes(
listOf(
"outputs/unit_test_code_coverage/debugUnitTest/*.exec",
"outputs/code_coverage/debugAndroidTest/connected/**/*.ec"
)
)
})
} }
} }

2
app/src/main/java/audio/funkwhale/ffa/FFA.kt

@ -72,6 +72,8 @@ class FFA : Application() {
instance = this instance = this
PowerPreference.init(this)
when (PowerPreference.getDefaultFile().getString("night_mode")) { when (PowerPreference.getDefaultFile().getString("night_mode")) {
"on" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) "on" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
"off" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) "off" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)

27
app/src/test/java/audio/funkwhale/ffa/activities/SplashActivityTest.kt

@ -0,0 +1,27 @@
package audio.funkwhale.ffa.activities
import android.content.Intent
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import audio.funkwhale.ffa.FFA
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows
import strikt.api.expectThat
import strikt.assertions.isEqualTo
@RunWith(RobolectricTestRunner::class)
class SplashActivityTest {
@Test
fun `unauthorized and nonAnonymous request should redirect to LoginActivity`() {
val scenario = ActivityScenario.launch(SplashActivity::class.java)
scenario.onActivity { activity ->
val expectedIntent = Intent(activity, LoginActivity::class.java)
val appContext = Shadows.shadowOf(ApplicationProvider.getApplicationContext<FFA>())
expectThat(appContext.nextStartedActivity.component).isEqualTo(expectedIntent.component)
}
}
}

14
build.gradle.kts

@ -10,8 +10,8 @@ buildscript {
classpath("com.android.tools.build:gradle:${Versions.androidGradlePlugin}") classpath("com.android.tools.build:gradle:${Versions.androidGradlePlugin}")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}")
classpath("com.github.bjoernq:unmockplugin:${Versions.unmock}") classpath("com.github.bjoernq:unmockplugin:${Versions.unmock}")
classpath("com.vanniktech:gradle-android-junit-jacoco-plugin:${Versions.gradleAndroidJUnitJacocoPlugin}")
classpath("com.github.ben-manes:gradle-versions-plugin:${Versions.gradleDependencyPlugin}") classpath("com.github.ben-manes:gradle-versions-plugin:${Versions.gradleDependencyPlugin}")
classpath("org.jacoco:org.jacoco.core:${Versions.jacoco}")
} }
} }
@ -24,6 +24,18 @@ allprojects {
} }
} }
subprojects {
configurations.all {
resolutionStrategy {
eachDependency {
if (this.requested.group == "org.jacoco") {
this.useVersion("0.8.7")
}
}
}
}
}
tasks { tasks {
val clean by registering(Delete::class) { val clean by registering(Delete::class) {
delete(buildDir) delete(buildDir)

2
buildSrc/src/main/java/Constants.kt → buildSrc/src/main/java/Versions.kt

@ -15,4 +15,6 @@ object Versions {
const val mockk = "1.12.0" const val mockk = "1.12.0"
const val strikt = "0.31.0" const val strikt = "0.31.0"
const val androidXTest = "1.4.0"
const val robolectric = "4.6.1"
} }
Loading…
Cancel
Save