124: Initial draft of screenshot testing setup r=msfjarvis a=Skrilltrax



Co-authored-by: Harsh Shandilya <me@msfjarvis.dev>
Co-authored-by: Aditya Wasan <adityawasan55@gmail.com>
This commit is contained in:
bors[bot] 2021-02-27 20:00:37 +00:00 committed by GitHub
commit 0f03ac28d8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 138 additions and 12 deletions

View file

@ -21,16 +21,13 @@ jobs:
with:
arguments: test --stacktrace
# - name: Run instrumentation tests
# uses: reactivecircus/android-emulator-runner@08b092e904025fada32a01b711af1e7ff7b7a4a3
# with:
# api-level: 23
# target: default
# script: |
# adb shell settings put global animator_duration_scale 0
# adb shell settings put global transition_animation_scale 0
# adb shell settings put global window_animation_scale 0
# ./gradlew :app:connectedDebugAndroidTest
- name: Run instrumentation tests
uses: reactivecircus/android-emulator-runner@08b092e904025fada32a01b711af1e7ff7b7a4a3
with:
api-level: 30
target: google_apis
script: |
./gradlew :app:connectedDebugAndroidTest
- name: (Fail-only) upload test report
if: failure()

View file

@ -3,6 +3,7 @@ plugins {
kotlin("android")
kotlin("kapt")
id("dagger.hilt.android.plugin")
id("shot")
`versioning-plugin`
`lobsters-plugin`
`core-library-desugaring`
@ -18,7 +19,7 @@ repositories {
android {
defaultConfig {
applicationId = "dev.msfjarvis.lobsters"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner = "com.karumi.shot.ShotTestRunner"
}
buildFeatures.compose = true

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="${applicationId}.test"
android:sharedUserId="${applicationId}.uid">
</manifest>

View file

@ -0,0 +1,22 @@
package dev.msfjarvis.lobsters.ui
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import dev.msfjarvis.lobsters.ui.theme.darkColors
import dev.msfjarvis.lobsters.ui.theme.lightColors
@Composable
fun LightTestTheme(children: @Composable () -> Unit) {
MaterialTheme(
colors = lightColors,
content = children,
)
}
@Composable
fun DarkTestTheme(children: @Composable () -> Unit) {
MaterialTheme(
colors = darkColors,
content = children,
)
}

View file

@ -0,0 +1,64 @@
package dev.msfjarvis.lobsters.ui.navigation
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.test.assertHasClickAction
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performClick
import com.karumi.shot.ScreenshotTest
import dev.msfjarvis.lobsters.ui.DarkTestTheme
import dev.msfjarvis.lobsters.ui.main.LobstersBottomNav
import dev.msfjarvis.lobsters.ui.theme.LobstersTheme
import org.junit.Rule
import org.junit.Test
class LobstersBottomNavTest : ScreenshotTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun bottomNavIsRenderedCorrectlyOnScreen() {
composeTestRule.setContent {
DarkTestTheme {
LobstersBottomNav(
currentDestination = Destination.startDestination,
navigateToDestination = { /*TODO*/ },
jumpToIndex = { /*TODO*/ }
)
}
}
compareScreenshot(composeTestRule.onRoot().captureToImage().asAndroidBitmap())
}
@Test
fun bottomNavUpdatesCorrectly() {
composeTestRule.setContent {
DarkTestTheme {
var destination by remember { mutableStateOf(Destination.startDestination) }
LobstersBottomNav(
currentDestination = destination,
navigateToDestination = { newDestination -> destination = newDestination },
jumpToIndex = { /*TODO*/ }
)
}
}
selectNode(Destination.Saved.name)
compareScreenshot(composeTestRule.onRoot().captureToImage().asAndroidBitmap())
}
private fun selectNode(testTag: String) = composeTestRule
.onNodeWithTag(testTag)
.assertHasClickAction()
.performClick()
}

View file

@ -0,0 +1,32 @@
package dev.msfjarvis.lobsters.ui.posts
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.test.captureToImage
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onRoot
import com.karumi.shot.ScreenshotTest
import dev.msfjarvis.lobsters.ui.DarkTestTheme
import org.junit.Rule
import org.junit.Test
class LobstersItemTest : ScreenshotTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun postsAreRenderedCorrectlyOnScreen() {
composeTestRule.setContent {
DarkTestTheme {
LobstersItem(
post = TEST_POST,
onClick = { /*TODO*/ },
onLongClick = { /*TODO*/ },
onSaveButtonClick = { /*TODO*/ },
isSaved = true,
)
}
}
compareScreenshot(composeTestRule.onRoot().captureToImage().asAndroidBitmap())
}
}

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.msfjarvis.lobsters">
package="dev.msfjarvis.lobsters"
android:sharedUserId="${applicationId}.uid">
<uses-permission android:name="android.permission.INTERNET" />

View file

@ -100,6 +100,7 @@ fun LobstersBottomNav(
},
label = { Text(stringResource(id = screen.labelRes)) },
selected = currentDestination == screen,
modifier = Modifier.testTag(screen.name),
alwaysShowLabel = false,
onClick = {
if (screen != currentDestination) {

View file

@ -34,5 +34,6 @@ dependencies {
implementation(Plugins.jsemver)
implementation(Plugins.lintModel)
implementation(Plugins.kotlin)
implementation(Plugins.shot)
implementation(Plugins.sqldelight)
}

View file

@ -11,6 +11,7 @@ object Plugins {
const val hilt = "com.google.dagger:hilt-android-gradle-plugin:${DAGGER_HILT_VERSION}"
const val kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.30"
const val jsemver = "com.github.zafarkhaja:java-semver:0.9.0"
const val shot = "com.karumi:shot:5.8.0"
const val sqldelight = "com.squareup.sqldelight:gradle-plugin:1.4.4"
}