From 8fe4b5f3e182caf7a5da39eb2fd87ce07b9ff768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Santos?= Date: Tue, 30 Jul 2024 17:52:20 +0100 Subject: [PATCH 1/3] Add UI and ViewModel tests --- .github/workflows/validate.yml | 21 ++++++++++ README.md | 22 ++++++++-- composeApp/build.gradle.kts | 7 ++++ .../ooni/probe/ui/result/ResultScreenTest.kt | 42 +++++++++++++++++++ .../probe/ui/result/ResultViewModelTest.kt | 21 ++++++++++ 5 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 composeApp/src/commonTest/kotlin/org/ooni/probe/ui/result/ResultScreenTest.kt create mode 100644 composeApp/src/commonTest/kotlin/org/ooni/probe/ui/result/ResultViewModelTest.kt diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 7c363b41..5ca4b844 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -68,3 +68,24 @@ jobs: with: name: android-lint-report path: composeApp/build/reports/ktlint/ + + common-tests: + name: Common Tests + runs-on: macos-latest + needs: [ build ] + + steps: + - uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Run common tests + run: ./gradlew :composeApp:iosSimulatorArm64Test + + - name: Uploads test reports + uses: actions/upload-artifact@v4 + if: failure() + with: + name: android-lint-report + path: composeApp/build/reports/tests/iosSimulatorArm64Test/ diff --git a/README.md b/README.md index f37c9728..afd64e12 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ besides platform-specific code that we can’t avoid, such as the loading our pr * `data` data layer code (database, preferences, network...) * `ui` UI layer code, organized into features/screens +<<<<<<< HEAD ### Build, Install, and Run @@ -59,7 +60,8 @@ To build, install, and run your application, use the following commands: ./gradlew runDebug -Porganization=dw ``` -There is a custom gradle task(`copyBrandingToCommonResources`) that is used to copy brand specific resources to the common resources folder. This task is called before the `preBuild` task. +There is a custom gradle task(`copyBrandingToCommonResources`) that is used to copy brand specific +resources to the common resources folder. This task is called before the `preBuild` task. ### Creating Run Configurations in Android Studio @@ -82,11 +84,25 @@ Configure run configurations for easy execution within Android Studio: #### OONI Probe iOS Configuration -The "Run/Debug Configurations" already has the proper configuration and you just need to select the XCode Project Scheme `OONIProbe` and run it. +The "Run/Debug Configurations" already has the proper configuration and you just need to select the +XCode Project Scheme `OONIProbe` and run it. #### News Media Scan iOS Configuration -The "Run/Debug Configurations" already has the proper configuration and you just need to select the XCode Project Scheme `NewsMediaScan` and run it. + +The "Run/Debug Configurations" already has the proper configuration and you just need to select the +XCode Project Scheme `NewsMediaScan` and run it. #### Switching between OONI Probe and News Media Scan + - Ensure you can run clean and build the project successfully. - Run `pod install` in the `iosApp` directory. + + +## Testing + +Common tests (tests inside `commonTest`) only run on the iOS Simulator. +Choosing the option `android (local)` won't work. This is a current +[issue](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-test.html#f03e048) with +the official testing library. + + diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index e77fd2a0..5c03ce11 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -1,3 +1,4 @@ +import org.jetbrains.compose.ExperimentalComposeLibrary import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.dsl.JvmTarget @@ -84,10 +85,16 @@ kotlin { kotlin.srcDir(config.srcRoot) } } + commonTest.dependencies { + implementation(kotlin("test")) + @OptIn(ExperimentalComposeLibrary::class) + implementation(compose.uiTest) + } all { languageSettings { optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") optIn("androidx.compose.material3.ExperimentalMaterial3Api") + optIn("androidx.compose.ui.test.ExperimentalTestApi") } } } diff --git a/composeApp/src/commonTest/kotlin/org/ooni/probe/ui/result/ResultScreenTest.kt b/composeApp/src/commonTest/kotlin/org/ooni/probe/ui/result/ResultScreenTest.kt new file mode 100644 index 00000000..71e6f6c0 --- /dev/null +++ b/composeApp/src/commonTest/kotlin/org/ooni/probe/ui/result/ResultScreenTest.kt @@ -0,0 +1,42 @@ +package org.ooni.probe.ui.result + +import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.runComposeUiTest +import org.ooni.probe.data.models.TestResult +import kotlin.test.Test +import kotlin.test.assertEquals + +class ResultScreenTest { + @Test + fun showResult() = + runComposeUiTest { + val result = TestResult(TestResult.Id("ABCDEF")) + setContent { + ResultScreen( + state = ResultViewModel.State(result), + onEvent = {}, + ) + } + + onNodeWithText(result.id.value).assertExists() + } + + @Test + fun pressBack() = + runComposeUiTest { + val events = mutableListOf() + val result = TestResult(TestResult.Id("ABCDEF")) + setContent { + ResultScreen( + state = ResultViewModel.State(result), + onEvent = events::add, + ) + } + + onNodeWithContentDescription("Back").performClick() + assertEquals(1, events.size) + assertEquals(ResultViewModel.Event.BackClicked, events.first()) + } +} diff --git a/composeApp/src/commonTest/kotlin/org/ooni/probe/ui/result/ResultViewModelTest.kt b/composeApp/src/commonTest/kotlin/org/ooni/probe/ui/result/ResultViewModelTest.kt new file mode 100644 index 00000000..e6c08302 --- /dev/null +++ b/composeApp/src/commonTest/kotlin/org/ooni/probe/ui/result/ResultViewModelTest.kt @@ -0,0 +1,21 @@ +package org.ooni.probe.ui.result + +import org.ooni.probe.data.models.TestResult +import kotlin.test.Test +import kotlin.test.assertTrue + +class ResultViewModelTest { + @Test + fun backClicked() { + var backPressed = false + + val viewModel = + ResultViewModel( + resultId = TestResult.Id("1234"), + onBack = { backPressed = true }, + ) + + viewModel.onEvent(ResultViewModel.Event.BackClicked) + assertTrue(backPressed) + } +} From 998e19be4781cba6334fcaabaeb3ec71a4024b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Santos?= Date: Wed, 31 Jul 2024 18:08:12 +0100 Subject: [PATCH 2/3] Copy resources before test --- .github/workflows/validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 5ca4b844..01ea1270 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -81,7 +81,7 @@ jobs: uses: ./.github/actions/setup - name: Run common tests - run: ./gradlew :composeApp:iosSimulatorArm64Test + run: ./gradlew copyBrandingToCommonResources :composeApp:iosSimulatorArm64Test - name: Uploads test reports uses: actions/upload-artifact@v4 From eee735804e8f8aaa126495ab565aed7ab62b188e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Santos?= Date: Wed, 31 Jul 2024 18:19:06 +0100 Subject: [PATCH 3/3] Fix README --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index afd64e12..63806833 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,6 @@ besides platform-specific code that we can’t avoid, such as the loading our pr * `data` data layer code (database, preferences, network...) * `ui` UI layer code, organized into features/screens -<<<<<<< HEAD - - ### Build, Install, and Run To build, install, and run your application, use the following commands: @@ -97,12 +94,9 @@ XCode Project Scheme `NewsMediaScan` and run it. - Ensure you can run clean and build the project successfully. - Run `pod install` in the `iosApp` directory. - ## Testing Common tests (tests inside `commonTest`) only run on the iOS Simulator. Choosing the option `android (local)` won't work. This is a current [issue](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-test.html#f03e048) with the official testing library. - -