From 1fd280b73553d06dcce13d259111c80252c1dbaf Mon Sep 17 00:00:00 2001 From: Abhijit Naik Date: Wed, 21 Aug 2024 01:32:23 +0530 Subject: [PATCH] Integrate setup for Unit Testing - along with enabling unit testing in CI/CD pipeline Signed-off-by: Abhijit Naik --- .github/workflows/{blank.yml => android.yml} | 4 + app/build.gradle.kts | 6 + .../utils/GenericExtensionsTest.kt | 46 ++++++ .../utils/WeatherTypeExtensionsTest.kt | 153 ++++++++++++++++++ gradle/libs.versions.toml | 14 +- 5 files changed, 220 insertions(+), 3 deletions(-) rename .github/workflows/{blank.yml => android.yml} (93%) create mode 100644 app/src/test/java/com/compose/weatherapplite/utils/GenericExtensionsTest.kt create mode 100644 app/src/test/java/com/compose/weatherapplite/utils/WeatherTypeExtensionsTest.kt diff --git a/.github/workflows/blank.yml b/.github/workflows/android.yml similarity index 93% rename from .github/workflows/blank.yml rename to .github/workflows/android.yml index 43a8c38..6b50d94 100644 --- a/.github/workflows/blank.yml +++ b/.github/workflows/android.yml @@ -35,6 +35,10 @@ jobs: - name: Build with Gradle run: ./gradlew build + # Runs the entire unit test suite + - name: Run Unit Tests + run: ./gradlew test + # # Runs a set of commands using the runners shell # - name: Upload a Build Artifact # uses: actions/upload-artifact@v3.1.3 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 49efe6c..bdb1335 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -78,6 +78,12 @@ dependencies { implementation(composeBom) androidTestImplementation(composeBom) + // Unit Testing + testImplementation(libs.test.junit) + testImplementation(libs.test.junit.core) + testImplementation(libs.test.roboelectric) + testImplementation(libs.test.mockk) + // Tooling - Preview debugImplementation(libs.androidx.compose.ui.tooling) implementation(libs.androidx.compose.ui.tooling.preview) diff --git a/app/src/test/java/com/compose/weatherapplite/utils/GenericExtensionsTest.kt b/app/src/test/java/com/compose/weatherapplite/utils/GenericExtensionsTest.kt new file mode 100644 index 0000000..0f7fa27 --- /dev/null +++ b/app/src/test/java/com/compose/weatherapplite/utils/GenericExtensionsTest.kt @@ -0,0 +1,46 @@ +package com.compose.weatherapplite.utils + +import io.mockk.impl.annotations.RelaxedMockK +import java.time.LocalDate +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals +import org.junit.Test + +class GenericExtensionsTest { + + @RelaxedMockK + private val date = LocalDate.now() + + @RelaxedMockK + private val mockedPastDate = LocalDate.now().minusDays(1) + + @RelaxedMockK + private val mockedFutureDate = LocalDate.now().plusDays(1) + + @Test + fun `toDayOfWeek returns Today for current date`() { + // Action + val result = date.toDayOfWeek() + + // Assert + assertEquals("Today", result) + } + + @Test + fun `toDayOfWeek returns correct day name for past date`() { + // Action + val result = mockedPastDate.toDayOfWeek() + + // Assert + assertNotEquals("Today", result) + } + + @Test + fun `toDayOfWeek returns correct day name for future date`() { + // Action + val result = mockedFutureDate.toDayOfWeek() + + // Assert + assertNotEquals("Today", result) + } +} diff --git a/app/src/test/java/com/compose/weatherapplite/utils/WeatherTypeExtensionsTest.kt b/app/src/test/java/com/compose/weatherapplite/utils/WeatherTypeExtensionsTest.kt new file mode 100644 index 0000000..234bcba --- /dev/null +++ b/app/src/test/java/com/compose/weatherapplite/utils/WeatherTypeExtensionsTest.kt @@ -0,0 +1,153 @@ +package com.compose.weatherapplite.utils + +import com.compose.weatherapplite.R +import com.compose.weatherapplite.presentation.model.WeatherType +import org.junit.Assert.assertEquals +import org.junit.Test + +class WeatherTypeExtensionsTest { + + @Test + fun `toDrawable returns correct drawable for ClearSky`() { + // Action + val result = WeatherType.ClearSky.toDrawable() + + // Assert + assertEquals(R.drawable.vd_clear_sky, result) + } + + @Test + fun `toDrawable returns correct drawable for Overcast`() { + // Action + val result = WeatherType.Overcast.toDrawable() + + // Assert + assertEquals(R.drawable.vd_overcast, result) + } + + @Test + fun `toDrawable returns correct drawable for Foggy`() { + // Action + val result = WeatherType.Foggy.toDrawable() + + // Assert + assertEquals(R.drawable.vd_foggy, result) + } + + @Test + fun `toDrawable returns correct drawable for Drizzle`() { + // Action + val result = WeatherType.Drizzle.toDrawable() + + // Assert + assertEquals(R.drawable.vd_drizzle, result) + } + + @Test + fun `toDrawable returns correct drawable for Rain`() { + // Action + val result = WeatherType.Rain.toDrawable() + + // Assert + assertEquals(R.drawable.vd_rain, result) + } + + @Test + fun `toDrawable returns correct drawable for HeavyRain`() { + // Action + val result = WeatherType.HeavyRain.toDrawable() + + // Assert + assertEquals(R.drawable.vd_heavy_rain, result) + } + + @Test + fun `toDrawable returns correct drawable for SnowFall`() { + // Action + val result = WeatherType.SnowFall.toDrawable() + + // Assert + assertEquals(R.drawable.vd_snowfall, result) + } + + @Test + fun `toDrawable returns correct drawable for Thunderstorm`() { + // Action + val result = WeatherType.Thunderstorm.toDrawable() + + // Assert + assertEquals(R.drawable.vd_thunderstorm, result) + } + + @Test + fun `toAnimatedVectorDrawable returns correct drawable for ClearSky`() { + // Action + val result = WeatherType.ClearSky.toAnimatedVectorDrawable() + + // Assert + assertEquals(R.drawable.avd_clear_sky, result) + } + + @Test + fun `toAnimatedVectorDrawable returns correct drawable for Overcast`() { + // Action + val result = WeatherType.Overcast.toAnimatedVectorDrawable() + + // Assert + assertEquals(R.drawable.avd_overcast, result) + } + + @Test + fun `toAnimatedVectorDrawable returns correct drawable for Foggy`() { + // Action + val result = WeatherType.Foggy.toAnimatedVectorDrawable() + + // Assert + assertEquals(R.drawable.avd_foggy, result) + } + + @Test + fun `toAnimatedVectorDrawable returns correct drawable for Drizzle`() { + // Action + val result = WeatherType.Drizzle.toAnimatedVectorDrawable() + + // Assert + assertEquals(R.drawable.avd_drizzle, result) + } + + @Test + fun `toAnimatedVectorDrawable returns correct drawable for Rain`() { + // Action + val result = WeatherType.Rain.toAnimatedVectorDrawable() + + // Assert + assertEquals(R.drawable.avd_rain, result) + } + + @Test + fun `toAnimatedVectorDrawable returns correct drawable for HeavyRain`() { + // Action + val result = WeatherType.HeavyRain.toAnimatedVectorDrawable() + + // Assert + assertEquals(R.drawable.avd_heavy_rain, result) + } + + @Test + fun `toAnimatedVectorDrawable returns correct drawable for SnowFall`() { + // Action + val result = WeatherType.SnowFall.toAnimatedVectorDrawable() + + // Assert + assertEquals(R.drawable.avd_snowfall, result) + } + + @Test + fun `toAnimatedVectorDrawable returns correct drawable for Thunderstorm`() { + // Action + val result = WeatherType.Thunderstorm.toAnimatedVectorDrawable() + + // Assert + assertEquals(R.drawable.avd_thunderstorm, result) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d2c4571..fa93b4c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -18,6 +18,10 @@ lifecycle = "2.7.0-beta01" material3 = "1.1.2" okhttp = "4.11.0" playservicesLocation = "21.0.1" +test-junit = "4.13.2" +test-junit-core = "1.6.1" +test-robolectric = "4.3" +test-mockk = "1.13.7" retrofit = "2.9.0" versionCatalogUpdate = "0.8.1" @@ -48,13 +52,17 @@ converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref compose-map = { module = "com.google.maps.android:maps-compose", version.ref = "composeMap" } destinations-core = { module = "io.github.raamcosta.compose-destinations:core", version.ref = "destinations" } destinations-ksp = { module = "io.github.raamcosta.compose-destinations:ksp", version.ref = "destinations" } -okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" } -okhttp3 = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" } +ksp = { module = "com.google.devtools.ksp:symbol-processing", version.ref = "ksp" } +okhttp-logging = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" } +okhttp3 = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" } playservices-location = { module = "com.google.android.gms:play-services-location", version.ref = "playservicesLocation" } retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" } -ksp = { module = "com.google.devtools.ksp:symbol-processing", version.ref = "ksp" } +test-junit = { module = "junit:junit", version.ref = "test-junit" } +test-junit-core = { module = "androidx.test:core", version.ref = "test-junit-core" } +test-roboelectric = { module = "org.robolectric:robolectric", version.ref = "test-robolectric" } +test-mockk = { module = "io.mockk:mockk", version.ref = "test-mockk" } [plugins]