Skip to content

Commit

Permalink
Merge pull request #28 from ooni/testing
Browse files Browse the repository at this point in the history
Add UI and ViewModel tests
  • Loading branch information
sdsantos authored Jul 31, 2024
2 parents efae06c + eee7358 commit abdedaa
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 5 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 copyBrandingToCommonResources :composeApp:iosSimulatorArm64Test

- name: Uploads test reports
uses: actions/upload-artifact@v4
if: failure()
with:
name: android-lint-report
path: composeApp/build/reports/tests/iosSimulatorArm64Test/
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +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



### Build, Install, and Run

To build, install, and run your application, use the following commands:
Expand All @@ -59,7 +57,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

Expand All @@ -82,11 +81,22 @@ 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.
7 changes: 7 additions & 0 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import org.jetbrains.compose.ExperimentalComposeLibrary
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

Expand Down Expand Up @@ -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")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<ResultViewModel.Event>()
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())
}
}
Original file line number Diff line number Diff line change
@@ -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)
}
}

0 comments on commit abdedaa

Please sign in to comment.