diff --git a/.gitea/workflows/common_coverage.yml b/.gitea/workflows/common_coverage.yml
new file mode 100644
index 0000000..adace78
--- /dev/null
+++ b/.gitea/workflows/common_coverage.yml
@@ -0,0 +1,43 @@
+name: Build
+on:
+  workflow_call:
+
+jobs:
+  BuildAndTestAndCoverage:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Check out repository code
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+      - name: Fetch tags
+        run: git fetch --tags -p
+      - uses: actions/setup-java@v4
+        with:
+          distribution: 'temurin'
+          java-version: '17'
+          cache: gradle
+      - uses: gradle/actions/setup-gradle@v3
+      - uses: android-actions/setup-android@v3
+      - name: Configure gradle...
+        run: mkdir -p ~/.gradle && echo "org.gradle.daemon=false\nignoreGitVersion=true" >> ~/.gradle/gradle.properties
+      - uses: KengoTODA/actions-setup-docker-compose@v1
+        with:
+          version: "2.23.3"
+      - name: run selfoss
+        run: |
+          docker compose -f .gitea/workflows/assets/docker-compose.yml up -d
+      - name: coverage
+        run: |
+          ./gradlew androidApp:connectedAndroidTest
+      - uses: actions/upload-artifact@v3
+        with:
+          name: coverage-espresso
+          path: build/reports/coverage/androidTest/githubConfig/debug/connected
+          retention-days: 1
+          overwrite: true
+          include-hidden-files: true
+      - name: Clean
+        if: always()
+        run: |
+          docker compose -f .gitea/workflows/assets/docker-compose.yml stop
diff --git a/.gitea/workflows/on_pr.yml b/.gitea/workflows/on_pr.yml
index d0d265b..8be2206 100644
--- a/.gitea/workflows/on_pr.yml
+++ b/.gitea/workflows/on_pr.yml
@@ -3,9 +3,13 @@ on:
   pull_request:
     branches:
       - master
-      - chore-crowdin-ci
 
 jobs:
+  EspressoReports:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Espresso Coverage
+        run: ./gradlew createDebugCoverageReport
   Lint:
     runs-on: ubuntu-latest
     steps:
diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts
index 4e65d85..0a36018 100644
--- a/androidApp/build.gradle.kts
+++ b/androidApp/build.gradle.kts
@@ -96,6 +96,7 @@ android {
         // tests
         testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
         testInstrumentationRunnerArguments["clearPackageData"] = "true"
+        testInstrumentationRunnerArguments["useTestStorageService"] = "true"
     }
     packaging {
         resources {
@@ -109,6 +110,8 @@ android {
             proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
         }
         getByName("debug") {
+            isTestCoverageEnabled = true
+            enableAndroidTestCoverage = true
         }
     }
     flavorDimensions.add("build")
@@ -197,14 +200,15 @@ dependencies {
     testImplementation("io.mockk:mockk:1.13.14")
     testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1")
     implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1")
-    androidTestImplementation("androidx.test:runner:1.6.2")
-    androidTestImplementation("androidx.test:rules:1.6.1")
+    androidTestImplementation("androidx.test:runner:1.7.0-alpha01")
+    androidTestImplementation("androidx.test:rules:1.7.0-alpha01")
     androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
     implementation("androidx.test.espresso:espresso-idling-resource:3.6.1")
     androidTestImplementation("androidx.test.ext:junit-ktx:1.2.1")
-    androidTestUtil("androidx.test:orchestrator:1.5.1")
+    androidTestUtil("androidx.test:orchestrator:1.6.0-alpha02")
+    androidTestUtil("androidx.test.services:test-services:1.6.0-alpha02")
     testImplementation("org.robolectric:robolectric:4.14.1")
-    testImplementation("androidx.test:core-ktx:1.6.1")
+    testImplementation("androidx.test:core-ktx:1.7.0-alpha01")
 
     implementation("ch.acra:acra-http:$acraVersion")
     implementation("ch.acra:acra-toast:$acraVersion")