{"id":35858662,"url":"https://github.com/mannodermaus/android-junit-framework","last_synced_at":"2026-01-16T13:50:03.489Z","repository":{"id":38814499,"uuid":"69637233","full_name":"mannodermaus/android-junit-framework","owner":"mannodermaus","description":"Modern testing with JUnit for Android.","archived":false,"fork":false,"pushed_at":"2026-01-14T14:27:32.000Z","size":2955,"stargazers_count":920,"open_issues_count":16,"forks_count":57,"subscribers_count":16,"default_branch":"main","last_synced_at":"2026-01-14T18:10:23.626Z","etag":null,"topics":["android","gradle-plugin","junit","junit5","unittesting"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mannodermaus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-09-30T05:40:48.000Z","updated_at":"2026-01-14T14:27:32.000Z","dependencies_parsed_at":"2023-02-10T17:30:19.317Z","dependency_job_id":"fdabc68e-d3d8-4514-b937-6f92ab012369","html_url":"https://github.com/mannodermaus/android-junit-framework","commit_stats":null,"previous_names":[],"tags_count":83,"template":false,"template_full_name":null,"purl":"pkg:github/mannodermaus/android-junit-framework","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mannodermaus%2Fandroid-junit-framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mannodermaus%2Fandroid-junit-framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mannodermaus%2Fandroid-junit-framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mannodermaus%2Fandroid-junit-framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mannodermaus","download_url":"https://codeload.github.com/mannodermaus/android-junit-framework/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mannodermaus%2Fandroid-junit-framework/sbom","scorecard":{"id":113167,"data":{"date":"2025-08-04","repo":{"name":"github.com/mannodermaus/android-junit5","commit":"bf38a6bdd9c16b1672936f8d6334866d5f18ecca"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":4.8,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"18 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/gradle-wrapper-validation.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle-wrapper-validation.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/mannodermaus/android-junit5/gradle-wrapper-validation.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/gradle-wrapper-validation.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/mannodermaus/android-junit5/gradle-wrapper-validation.yml/main?enable=pin","Info:   0 out of   1 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 9 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-15T16:30:52.814Z","repository_id":38814499,"created_at":"2025-08-15T16:30:52.814Z","updated_at":"2025-08-15T16:30:52.814Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479034,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","gradle-plugin","junit","junit5","unittesting"],"created_at":"2026-01-08T11:00:26.714Z","updated_at":"2026-01-16T13:50:03.437Z","avatar_url":"https://github.com/mannodermaus.png","language":"Kotlin","readme":"\u003c!--\n  This file was automatically generated by Gradle. Do not modify.\n  To update the content of this README, please apply modifications\n  to `README.md.template` instead, and run the `generateReadme` task from Gradle.\n--\u003e\n\u003ch1\u003e\n  \u003cpicture width=\"400\"\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\".images/logo-inverted.svg\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\".images/logo.svg\"\u003e\n    \u003cimg alt=\"Android JUnit\" src=\".images/logo.svg\" width=\"400\"\u003e\n  \u003c/picture\u003e\n\u003c/h1\u003e\n\n[![CircleCI](https://circleci.com/gh/mannodermaus/android-junit-framework/tree/main.svg?style=svg)][circleci]\n\nA Gradle plugin that allows for the execution of [JUnit][junit-github] 5+ tests in Android environments using **Android Gradle Plugin 8.2 or later.**\n\n## How?\n\nThis plugin configures the unit test tasks for each build variant of a project to run on the JUnit Platform.\nFurthermore, it provides additional configuration options for these tests [through a DSL][wiki-dsl]\nand facilitates the usage JUnit for instrumentation tests.\n\nInstructions on how to write tests with modern JUnit can be found [in their User Guide][junit-guide].\nTo get a first look at its features, a small showcase project can be found [here][sampletests].\n\n## Setup\n\nTo get started, declare the plugin in your `app` module's build script alongside the latest version.\nSnapshots of the development version are available through [Sonatype's `snapshots` repository][sonatyperepo].\n\n```kotlin\nplugins {\n    // 1. Apply the plugin\n    id(\"de.mannodermaus.android-junit\") version \"2.0.0\"\n}\n\ndependencies {\n    // 2. Add JUnit BOM and the required dependencies\n    testImplementation(platform(\"org.junit:junit-bom:5.14.1\"))\n    testImplementation(\"org.junit.jupiter:junit-jupiter-api\")\n    testImplementation(\"org.junit.jupiter:junit-jupiter-params\")\n    testRuntimeOnly(\"org.junit.jupiter:junit-jupiter-engine\")\n\n    // 3. Add JUnit Vintage if you also have JUnit 4 tests (e.g. for Robolectric)\n    testImplementation(\"junit:junit:4.13.2\")\n    testRuntimeOnly(\"org.junit.vintage:junit-vintage-engine\")\n}\n```\n\nMore information on Getting Started can be found [on the wiki][wiki-gettingstarted].\n\n## Requirements\n\nThe latest version of this plugin requires at least:\n* Android Gradle Plugin `8.2`\n* Gradle `8.2`\n\n## Instrumentation Test Support\n\nYou can also write instrumentation tests with new JUnit APIs and execute them on emulators and physical devices.\nDepending on the Java requirements of the JUnit version, these instrumentation tests will only run on devices\nthat meet these requirements, however. On older devices, an exception will be raised at runtime.\n\n- JUnit 5 requires Java 8; devices require at least Android 8.0 (API 26)\n- JUnit 6 requires Java 17; devices require at least Android 15 (API 35)\n\nBefore you can write instrumentation tests with JUnit Jupiter,\nmake sure that your module is using the `androidx.test.runner.AndroidJUnitRunner`\n(or a subclass of it) as its `testInstrumentationRunner`. Then, simply add a dependency on JUnit Jupiter API\nto the `androidTestImplementation` configuration in your build script and the plugin will\nautomatically configure JUnit 5 tests for you:\n\n```kotlin\ndependencies {\n    androidTestImplementation(platform(\"org.junit:junit-bom:5.14.1\"))\n    androidTestImplementation(\"org.junit.jupiter:junit-jupiter-api\")\n}\n```\n\nBy enabling JUnit for instrumentation tests, you will gain access to `ActivityScenarioExtension` among other things,\nwhich helps with the orchestration of `Activity` classes. Check [the wiki][wiki-home] for more info.\n\n### Ignoring older devices\n\nHistorically, tests were ignored if the Android device running them did not meet the requirements of JUnit.\nThis was changed in the 2.0.0 of the plugin \u0026 library, but if you want to restore the previous behavior,\nyou can do so via the `junitPlatform` DSL.\n\n```kotlin\njunitPlatform {\n    instrumentationTests.behaviorForUnsupportedDevices = UnsupportedDeviceBehavior.Skip\n}\n```\n\n### Extensions\n\nAn optional artifact with `extensions` is available for specific use cases. It contains the following APIs:\n\n- `GrantPermissionExtension` for granting permissions before each test\n\nCan you think of more? Let's discuss in the issues section!\n\n```kotlin\njunitPlatform {\n    instrumentationTests.includeExtensions = true\n}\n```\n\n### Jetpack Compose\n\nTo test `@Composable` functions on devices compatible with modern JUnit,\nenable support for instrumentation tests as described above. Then add the Compose test dependency\nto your `androidTestImplementation` configuration and the plugin will autoconfigure JUnit 5 Compose support for you.\n\n```kotlin\ndependencies {\n    // Setup from the previous section for enabling instrumentation tests...\n\n    // Compose test framework\n    androidTestImplementation(\"androidx.compose.ui:ui-test-android:$compose_version\")\n\n    // Needed for createComposeExtension() and createAndroidComposeExtension()\n    debugImplementation(\"androidx.compose.ui:ui-test-manifest:$compose_version\")\n}\n```\n\n[The wiki][wiki-home] includes a section on how to test your Composables.\n\n### Override the version of instrumentation test libraries\n\nBy default, the plugin will make sure to use a compatible version of the instrumentation test libraries\nwhen it sets up the artifacts automatically. However, it is possible to choose a custom version instead via its DSL:\n\n```kotlin\njunitPlatform {\n    instrumentationTests.version = \"2.0.0\"\n}\n```\n\n## Official Support\n\nAt this time, Google hasn't shared any immediate plans to bring first-party support for anything beyond JUnit 4 to Android.\nThe following list is an aggregation of pending feature requests:\n\n- [InstantTaskExecutorRule uses @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -- why? (issuetracker.google.com)](https://issuetracker.google.com/u/0/issues/79189568)\n- [Add support for JUnit 5 (issuetracker.google.com)](https://issuetracker.google.com/issues/127100532)\n- [JUnit 5 support (github.com/android/android-test)](https://github.com/android/android-test/issues/224)\n\n## Support for @Rules\n\nSince JUnit has replaced the `@Rule` mechanism with the concept of an `Extension` in version 5,\nthe following artifacts help bridge the gap until Android officially transitions, if ever.\n\n### InstantExecutorExtension\n\nReplaces `InstantTaskExecutorRule` in JUnit 5.\n\n```kotlin\ndependencies {\n    testImplementation(\"io.github.neboskreb:instant-task-executor-extension:1.0.0\")\n}\n```\n\nFor more details see [instant-task-executor-extension](https://github.com/neboskreb/instant-task-executor-extension) on GitHub.\n\n## Building Locally\n\nThis repository contains multiple modules, divided into two sub-projects.\nThe repository's root directory contains build logic shared across the sub-projects,\nwhich in turn use symlinks to connect to the common build scripts in their parent folder.\n\n- `instrumentation`: The root folder for the instrumentation libraries \u0026 a sample. Open this folder in Android Studio.\n- `plugin`: The root folder for the Gradle plugin. Open this folder in IntelliJ IDEA.\n\n## Plugin Compatibility Map\n\nFor users that cannot match the current minimum version requirement of the Android Gradle Plugin requested by this plugin,\nrefer to the table below to find a suitable alternative version. Note that **no active development will go into legacy versions**,\nso please consider upgrading to at least AGP 8.2 before filing an issue with the latest one.\n\n|Your AGP Version|Suggested Plugin Version|\n|---|---|\n|`\u003e= 8.2.0`|`2.0.0`|\n|`8.0.0` - `8.1.4`|`1.12.2.0`|\n|`7.0.0` - `7.4.2`|`1.10.0.0`|\n|`4.0.0` - `4.2.2`|`1.8.2.1`|\n|`3.5.0` - `3.6.4`|`1.7.1.1`|\n|`\u003c 3.5.0`|none; you should **really** update your build env, bro|\n\n## License\n\n```\nCopyright 2017-2026 Marcel Schnelle\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n  http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\nSee also the [full License text](LICENSE).\n\n [junit-github]: https://github.com/junit-team/junit-framework\n [junit-guide]: https://docs.junit.org\n [circleci]: https://circleci.com/gh/mannodermaus/android-junit-framework\n [sonatyperepo]: https://central.sonatype.com/repository/maven-snapshots\n [sampletests]: instrumentation/sample\n [wiki-home]: https://github.com/mannodermaus/android-junit-framework/wiki\n [wiki-dsl]: https://github.com/mannodermaus/android-junit-framework/wiki/Configuration\n [wiki-gettingstarted]: https://github.com/mannodermaus/android-junit-framework/wiki/Getting-Started\n","funding_links":[],"categories":["Kotlin"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmannodermaus%2Fandroid-junit-framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmannodermaus%2Fandroid-junit-framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmannodermaus%2Fandroid-junit-framework/lists"}