diff --git a/docs/blog/posts/2017-03-01-hermetic-builds.md b/docs/blog/posts/2017-03-01-hermetic-builds.md index 859c8ec50..a8639dea9 100644 --- a/docs/blog/posts/2017-03-01-hermetic-builds.md +++ b/docs/blog/posts/2017-03-01-hermetic-builds.md @@ -11,7 +11,8 @@ slug: hermetic-builds Robolectric needs access to multiple Android SDK jars in order to perform its magic, which means it needs special configuration beyond just setting up dependencies in your build. By default, it tries to download Android SDK jars from Maven Central. -But what if you have a [hermetic build environment](https://blog.fahhem.com/2013/12/hermetic-build-systems/)? You just need to do a little more configuration. +But what if you have a [hermetic build environment][hermetic-build]? You just need to do a little +more configuration. Here's a Gradle build script that'll help: @@ -140,3 +141,5 @@ Add the `.jar` files listed in `build/output/README.txt` as compile-time depende Place the file called `build/output/robolectric-deps.properties` in your test `resources` directory. Change the paths as indicated in the comment in that file. You're all set! Robolectric will now load Android SDKs from the filesystem instead of attempting to download them from Maven Central. + +[hermetic-build]: https://blog.fahhem.com/2013/12/hermetic-build-systems diff --git a/docs/blog/posts/2017-03-02-robolectric-3-3-and-roadmap.md b/docs/blog/posts/2017-03-02-robolectric-3-3-and-roadmap.md index 6911f79f1..ddea6a71d 100644 --- a/docs/blog/posts/2017-03-02-robolectric-3-3-and-roadmap.md +++ b/docs/blog/posts/2017-03-02-robolectric-3-3-and-roadmap.md @@ -8,11 +8,15 @@ slug: robolectric-3-3-and-roadmap # Robolectric 3.3 and Roadmap -Your Robolectric maintainers are pleased to announce the release of [Robolectric 3.3](https://github.com/robolectric/robolectric/releases/tag/robolectric-3.3)! There's been a bunch of activity recently in Robolectric, and we wanted to give a quick update on our thinking about where the project is going. +Your Robolectric maintainers are pleased to announce the release of +[Robolectric 3.3][robolectric-3.3-release]! There's been a bunch of activity recently in +Robolectric, and we wanted to give a quick update on our thinking about where the project is going. ## Introduction -Robolectric started life in 2010 as a quick hack to allow Android tests to be run on a regular JVM rather than a device or emulator, allowing for fast [TDD cycles](https://en.wikipedia.org/wiki/Test-driven_development#Coding_cycle). It was mostly developed in brief spurts as needed for testing specific projects. +Robolectric started life in 2010 as a quick hack to allow Android tests to be run on a regular JVM +rather than a device or emulator, allowing for fast [TDD cycles][tdd-cycles]. It was mostly +developed in brief spurts as needed for testing specific projects. Since then, it's been cool to see Robolectric grow with the help of the community, and become quite widely used. It's become a critical part of the test infrastructure of lots of companies and projects. It's rather outgrown the scrappy side-project Robolectric was for much of its life and needs some full-time attention. @@ -44,10 +48,12 @@ As new SDKs and new features are released, we'll make sure Robolectric supports ## Community -We're going to do our best to stay on top of bug reports and pull requests. We'll be continuing to develop in the open on [GitHub](https://github.com/robolectric/robolectric), and we'd love your input on changes and designs. +We're going to do our best to stay on top of bug reports and pull requests. We'll be continuing to +develop in the open on [GitHub][robolectric-github], and we'd love your input on changes and +designs. As always, thanks for your pull requests, bug reports, ideas and questions! -_Your Robolectric maintainers,_ -
-[jongerrish@google.com](mailto:jongerrish@google.com) and [christianw@google.com](mailto:christianw@google.com) +[robolectric-3.3-release]: https://github.com/robolectric/robolectric/releases/tag/robolectric-3.3 +[robolectric-github]: https://github.com/robolectric/robolectric +[tdd-cycles]: https://en.wikipedia.org/wiki/Test-driven_development#Coding_cycle diff --git a/docs/blog/posts/2017-11-13-resources-for-real.md b/docs/blog/posts/2017-11-13-resources-for-real.md index c52077932..7fbe9ef39 100644 --- a/docs/blog/posts/2017-11-13-resources-for-real.md +++ b/docs/blog/posts/2017-11-13-resources-for-real.md @@ -19,7 +19,8 @@ We're doing this in three separate releases to give you a chance to fix your tes The releases will be: -- **3.6:** Resource selection based on transliterated framework code. Configuration properties set from [`@Config(qualifiers)`](../../device-configuration.md). +- **3.6:** Resource selection based on transliterated framework code. Configuration properties set + from [`@Config(qualifiers)`][config-annotation]. - **3.7:** Manifest parsing based on transliterated framework code. - **3.8:** Resource loading from `aapt`-processed binary resource files. @@ -29,6 +30,4 @@ Going forward, we're applying a higher standard for accuracy in Robolectric's im As always, thanks for your pull requests, bug reports, ideas and questions! 💯 -_Your Robolectric maintainers,_ -
-[jongerrish@google.com](mailto:jongerrish@google.com), [brettchabot@google.com](mailto:brettchabot@google.com), and [christianw@google.com](mailto:christianw@google.com). +[config-annotation]: ../../device-configuration.md diff --git a/docs/blog/posts/2018-05-09-robolectric-4-0-alpha.md b/docs/blog/posts/2018-05-09-robolectric-4-0-alpha.md index 9cce3f7df..3a53c9147 100644 --- a/docs/blog/posts/2018-05-09-robolectric-4-0-alpha.md +++ b/docs/blog/posts/2018-05-09-robolectric-4-0-alpha.md @@ -13,7 +13,11 @@ The Robolectric team is super excited to announce the first alpha release of Rob ## `androidx.test` -We’re collaborating closely with the Android Jetpack testing team to develop common APIs for writing Android tests that can run as both local (JVM-based) and on-device (instrumentation) tests. From 4.0 on, Robolectric will support Jetpack’s [`androidx.test`](https://developer.android.com/training/testing/) APIs, starting with support for the [`AndroidJUnit4` test runner](https://developer.android.com/training/testing/junit-runner), [`ActivityTestRule`](https://developer.android.com/training/testing/junit-rules), and [Espresso](https://developer.android.com/training/testing/espresso/) for interacting with UI components. +We’re collaborating closely with the Android Jetpack testing team to develop common APIs for writing +Android tests that can run as both local (JVM-based) and on-device (instrumentation) tests. From 4.0 +on, Robolectric will support Jetpack’s [`androidx.test`][androidx-test] APIs, starting with support +for the [`AndroidJUnit4` test runner][junit-runner], [`ActivityTestRule`][activity-test-rule], +and [Espresso][espresso] for interacting with UI components. ### A Robolectric 3.x style test @@ -49,7 +53,10 @@ As you can see, many of the idioms common in instrumentation tests are now suppo In conjunction with Android Studio 3.2, Robolectric can now use resources processed using the Android build toolchain, and loads and handles those resources using the same logic as on an actual Android device. Robolectric's old idiosyncratic resource handling mode is still available for projects not yet using the latest version of the build toolchain. -To enable the use of toolchain-processed resources in Robolectric tests, make sure you're using [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin#updating-plugin) version `com.android.tools.build:gradle:3.2.0-alpha14` or higher, and add the following to your `gradle.properties`: +To enable the use of toolchain-processed resources in Robolectric tests, make sure you're +using [Android Gradle Plugin][android-gradle-plugin] version +`com.android.tools.build:gradle:3.2.0-alpha14` or higher, and add the following to your +`gradle.properties`: ```properties android.enableUnitTestBinaryResources=true @@ -57,12 +64,17 @@ android.enableUnitTestBinaryResources=true ## Release Notes -Release notes are [available here](https://github.com/robolectric/robolectric/releases/tag/robolectric-4.0-alpha-1). Robolectric 4.0 is currently in alpha release, meaning that it is not yet feature-complete, and APIs are likely to change before the final release. Use with caution. +Release notes are [available here][robolectric-4.0-alpha-1-release]. Robolectric 4.0 is currently in +alpha release, meaning that it is not yet feature-complete, and APIs are likely to change before the +final release. Use with caution. --- As always, thanks for your pull requests, bug reports, ideas and questions! 💯 -_Your Robolectric maintainers,_ -
-[jongerrish@google.com](mailto:jongerrish@google.com), [brettchabot@google.com](mailto:brettchabot@google.com), and [christianw@google.com](mailto:christianw@google.com). +[activity-test-rule]: https://developer.android.com/training/testing/junit-rules +[android-gradle-plugin]: https://developer.android.com/studio/releases/gradle-plugin#updating-plugin +[androidx-test]: https://developer.android.com/training/testing +[espresso]: https://developer.android.com/training/testing/espresso +[junit-runner]: https://developer.android.com/training/testing/junit-runner +[robolectric-4.0-alpha-1-release]: https://github.com/robolectric/robolectric/releases/tag/robolectric-4.0-alpha-1 diff --git a/docs/blog/posts/2018-10-25-robolectric-4-0.md b/docs/blog/posts/2018-10-25-robolectric-4-0.md index 61ee5b0ee..2625e5a3c 100644 --- a/docs/blog/posts/2018-10-25-robolectric-4-0.md +++ b/docs/blog/posts/2018-10-25-robolectric-4-0.md @@ -13,7 +13,11 @@ Robolectric 4.0 is released! Here's what's new! ## `androidx.test` -The different idioms for testing using Robolectric and instrumentation tests have long been a headache. With today's release of Robolectric 4.0 and [`androidx.test`](https://developer.android.com/training/testing/) 1.0.0, both testing environments are converging on a set of common test APIs. Robolectric now supports the [`AndroidJUnit4` test runner](https://developer.android.com/training/testing/junit-runner), [`ActivityTestRule`](https://developer.android.com/training/testing/junit-rules), and [Espresso](https://developer.android.com/training/testing/espresso/) for interacting with UI components. +The different idioms for testing using Robolectric and instrumentation tests have long been a +headache. With today's release of Robolectric 4.0 and [`androidx.test`][androidx-test] 1.0.0, both +testing environments are converging on a set of common test APIs. Robolectric now supports the +[`AndroidJUnit4` test runner][junit-runner], [`ActivityTestRule`][activity-test-rule], and +[Espresso][espresso] for interacting with UI components. ### A Robolectric 3.x style test @@ -49,7 +53,9 @@ As you can see, many of the idioms common in instrumentation tests are now suppo In conjunction with Android Studio 3.2, Robolectric can now use resources processed using the Android build toolchain, and loads and handles those resources using the same logic as on an actual Android device. Robolectric's old idiosyncratic resource handling mode is still available for projects not yet using the latest version of the build toolchain, but is now deprecated and will be removed in a future release. -To enable the use of toolchain-processed resources in Robolectric tests, make sure you're using [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin#updating-plugin) version `com.android.tools.build:gradle:3.2.1` or higher, and add the following to your `gradle.properties`: +To enable the use of toolchain-processed resources in Robolectric tests, make sure you're using +[Android Gradle Plugin][android-gradle-plugin] version `com.android.tools.build:gradle:3.2.1` or +higher, and add the following to your `gradle.properties`: ```groovy android { @@ -73,16 +79,24 @@ android.enableUnitTestBinaryResources=true ## Migration Tool -Robolectric 4.0 contains a number of API changes that may require modifications to your test code. Check out the [migration notes](../../migrating.md#migrating-to-40) and use the new [automated migration tool](../../automated-migration.md) to help convert your existing tests to be compatible with Robolectric 4.0. +Robolectric 4.0 contains a number of API changes that may require modifications to your test code. +Check out the [migration notes][migration] and use the new +[automated migration tool][automated-migration-tool] to help convert your existing tests to be +compatible with Robolectric 4.0. ## Release Notes -Release notes are [available here](https://github.com/robolectric/robolectric/releases/tag/robolectric-4.0). +Release notes are [available here][robolectric-4.0-release]. --- As always, thanks for your pull requests, bug reports, ideas and questions! 💯 -_Your Robolectric maintainers,_ -
-[jongerrish@google.com](mailto:jongerrish@google.com), [brettchabot@google.com](mailto:brettchabot@google.com), and [christianw@google.com](mailto:christianw@google.com). +[activity-test-rule]: https://developer.android.com/training/testing/junit-rules +[android-gradle-plugin]: https://developer.android.com/studio/releases/gradle-plugin#updating-plugin +[androidx-test]: https://developer.android.com/training/testing +[automated-migration-tool]: ../../automated-migration.md +[espresso]: https://developer.android.com/training/testing/espresso +[junit-runner]: https://developer.android.com/training/testing/junit-runner +[migration]: ../../migrating.md#migrating-to-40 +[robolectric-4.0-release]: https://github.com/robolectric/robolectric/releases/tag/robolectric-4.0 diff --git a/docs/blog/posts/2019-06-04-paused-looper.md b/docs/blog/posts/2019-06-04-paused-looper.md index 8251f2aa8..da92147c8 100644 --- a/docs/blog/posts/2019-06-04-paused-looper.md +++ b/docs/blog/posts/2019-06-04-paused-looper.md @@ -8,11 +8,10 @@ slug: paused-looper # Improving Robolectric's Looper simulation -**TL;DR: We'd love your feedback on improvements we've made to make Robolectric's -[`Looper`](https://developer.android.com/reference/android/os/Looper.html) behavior more -realistic.** Try it out today by annotating your tests with -[`@LooperMode(PAUSED)`](../../javadoc/latest/org/robolectric/annotation/LooperMode.html) and let us -know your experience! +**TL;DR: We'd love your feedback on improvements we've made to make Robolectric's [`Looper`][looper] +behavior more realistic.** +Try it out today by annotating your tests with [`@LooperMode(PAUSED)`][looper-mode] and let us know +your experience! ## Background @@ -37,33 +36,28 @@ assertion fails with `[before, after, between]`, which is clearly incorrect. Robolectric’s current implementation is notoriously prone to deadlocks, infinite loops and other race conditions. Robolectric will duplicate each task posted to a `Looper` into a separate list -stored in [`Scheduler`](../../javadoc/latest/org/robolectric/util/Scheduler.html). The `Looper`’s -set of tasks and the `Scheduler`s can get out of sync, causing hard-to-diagnose errors. +stored in [`Scheduler`][scheduler]. The `Looper`’s set of tasks and the `Scheduler`s can get out of +sync, causing hard-to-diagnose errors. ## Solution We’ve re-written Robolectric’s threading model and `Looper` simulation in a way that we hope will -address the deficiencies of the current behavior. It’s available to try out now by applying a -`@LooperMode(PAUSED)` annotation to your test classes or methods. Some of the highlights of the -[`PAUSED`](../../javadoc/latest/org/robolectric/annotation/LooperMode.Mode.html#PAUSED) mode vs. the -existing [`LEGACY`](../../javadoc/latest/org/robolectric/annotation/LooperMode.Mode.html#LEGACY) -mode include: +address the deficiencies of the current behavior. It’s available to try out now by applying a +`@LooperMode(PAUSED)` annotation to your test classes or methods. Some of the highlights of the +[`PAUSED`][looper-mode-paused] mode vs. the existing [`LEGACY`][looper-mode-legacy] mode include: * Tasks posted to the main `Looper` are not automatically executed inline. Similar to the -[legacy `PAUSED` `IdleState`](../../javadoc/latest/org/robolectric/util/Scheduler.IdleState.html#PAUSED), -tasks posted to the main `Looper` must be explicitly executed via -[`ShadowLooper`](../../javadoc/latest/org/robolectric/shadows/ShadowLooper.html) APIs. However, -we’ve made a couple additional improvements in `PAUSED` mode that make this easier: -* Robolectric will warn users if a test fails with unexecuted tasks in the main `Looper` queue. -This is a hint that the unexecuted behavior is important for the test case. -* AndroidX Test APIs, like -[`ActivityScenario`](https://developer.android.com/reference/androidx/test/core/app/ActivityScenario), -[`FragmentScenario`](https://developer.android.com/reference/androidx/fragment/app/testing/FragmentScenario) -and [Espresso](https://developer.android.com/training/testing/espresso/) will automatically idle the -main `Looper`. -* Tasks posted to background `Looper`s are executed in real threads. This will hopefully -eliminate the need for hacks when trying to test code that asserts that it is running in a -background thread. + [legacy `PAUSED` `IdleState`][idle-state-paused], tasks posted to the main `Looper` must be + explicitly executed via [`ShadowLooper`][shadow-looper] APIs. However, we’ve made a couple + additional improvements in `PAUSED` mode that make this easier: +* Robolectric will warn users if a test fails with unexecuted tasks in the main `Looper` queue. + This is a hint that the unexecuted behavior is important for the test case. +* AndroidX Test APIs, like [`ActivityScenario`][activity-scenario], + [`FragmentScenario`][fragment-scenario] and [Espresso][espresso] will automatically idle the main + `Looper`. +* Tasks posted to background `Looper`s are executed in real threads. This will hopefully + eliminate the need for hacks when trying to test code that asserts that it is running in a + background thread. ## Using `PAUSED` `LooperMode` @@ -78,13 +72,13 @@ To switch to `PAUSED`: ``` * Apply the `@LooperMode(PAUSED)` annotation to your test package/class/method. -* Convert any background `Scheduler` calls for controlling `Looper`s to -[`shadowOf(looper)`](../../javadoc/latest/org/robolectric/Shadows.html#shadowOf(android.os.Looper)). +* Convert any background `Scheduler` calls for controlling `Looper`s to + [`shadowOf(looper)`][shadow-of-looper]. * Recommended, but not mandatory: Convert any foreground `Scheduler` calls to `shadowOf(getMainLooper())`. The `Scheduler` APIs will be deprecated and removed over time. -* Convert any [`RoboExecutorService`](../../javadoc/latest/org/robolectric/android/util/concurrent/RoboExecutorService.html) -usages to [`PausedExecutorService`](../../javadoc/latest/org/robolectric/android/util/concurrent/PausedExecutorService.html) -or [`InlineExecutorService`](../../javadoc/latest/org/robolectric/android/util/concurrent/InlineExecutorService.html). +* Convert any [`RoboExecutorService`][robo-executor-service] usages to + [`PausedExecutorService`][paused-executor-service] or + [`InlineExecutorService`][inline-executor-service]. * Run your tests. If you see test failures like `Main looper has queued unexecuted runnables`, you may need to insert `shadowOf(getMainLooper()).idle()` calls to your test to drain the main `Looper`. It's recommended to step through your test code with a watch set on @@ -120,16 +114,35 @@ public class MyTest { } ``` -Take a look at Robolectric’s [`ShadowPausedAsyncTaskTest`](https://github.com/robolectric/robolectric/blob/master/robolectric/src/test/java/org/robolectric/shadows/ShadowPausedAsyncTaskTest.java) for an example of using `PAUSED` `LooperMode` and background tasks. +Take a look at Robolectric’s [`ShadowPausedAsyncTaskTest`][shadow-paused-async-task-test] for an +example of using `PAUSED` `LooperMode` and background tasks. ## Troubleshooting -* Animations: Use of Animations can cause delayed tasks to be posted to the main `Looper` queue. -You can use the [`ShadowLooper.idleFor()`](../../javadoc/latest/org/robolectric/shadows/ShadowLooper.html#idleFor(long,java.util.concurrent.TimeUnit)) -or [`ShadowLooper.runToEndOfTasks()`](../../javadoc/latest/org/robolectric/shadows/ShadowLooper.html#runToEndOfTasks()) APIs to execute these tasks. +* Animations: Use of Animations can cause delayed tasks to be posted to the main `Looper` queue. You + can use the [`ShadowLooper.idleFor()`][shadow-looper-idle-for] or + [`ShadowLooper.runToEndOfTasks()`][shadow-looper-run-to-end-of-tasks] APIs to execute these tasks. ## Feedback Please let us know of any roadblocks to adopting `PAUSED` `LooperMode`. We’d like to make it the default mode for tests in the next release, and thus your feedback would be most welcome. + +[activity-scenario]: https://developer.android.com/reference/androidx/test/core/app/ActivityScenario +[espresso]: https://developer.android.com/training/testing/espresso +[fragment-scenario]: https://developer.android.com/reference/androidx/fragment/app/testing/FragmentScenario +[idle-state-paused]: ../../javadoc/latest/org/robolectric/util/Scheduler.IdleState.html#PAUSED +[inline-executor-service]: ../../javadoc/latest/org/robolectric/android/util/concurrent/InlineExecutorService.html +[looper]: https://developer.android.com/reference/android/os/Looper.html +[looper-mode]: ../../javadoc/latest/org/robolectric/annotation/LooperMode.html +[looper-mode-legacy]: ../../javadoc/latest/org/robolectric/annotation/LooperMode.Mode.html#LEGACY +[looper-mode-paused]: ../../javadoc/latest/org/robolectric/annotation/LooperMode.Mode.html#PAUSED +[paused-executor-service]: ../../javadoc/latest/org/robolectric/android/util/concurrent/PausedExecutorService.html +[robo-executor-service]: ../../javadoc/latest/org/robolectric/android/util/concurrent/RoboExecutorService.html +[scheduler]: ../../javadoc/latest/org/robolectric/util/Scheduler.html +[shadow-looper]: ../../javadoc/latest/org/robolectric/shadows/ShadowLooper.html +[shadow-looper-idle-for]: ../../javadoc/latest/org/robolectric/shadows/ShadowLooper.html#idleFor(long,java.util.concurrent.TimeUnit) +[shadow-looper-run-to-end-of-tasks]: ../../javadoc/latest/org/robolectric/shadows/ShadowLooper.html#runToEndOfTasks() +[shadow-of-looper]: ../../javadoc/latest/org/robolectric/Shadows.html#shadowOf(android.os.Looper) +[shadow-paused-async-task-test]: https://github.com/robolectric/robolectric/blob/master/robolectric/src/test/java/org/robolectric/shadows/ShadowPausedAsyncTaskTest.java diff --git a/docs/blog/posts/2021-09-13-a-memorial-tribute-for-jonathan-gerrish.md b/docs/blog/posts/2021-09-13-a-memorial-tribute-for-jonathan-gerrish.md index 8dd92bb1c..95c7ace38 100644 --- a/docs/blog/posts/2021-09-13-a-memorial-tribute-for-jonathan-gerrish.md +++ b/docs/blog/posts/2021-09-13-a-memorial-tribute-for-jonathan-gerrish.md @@ -19,13 +19,13 @@ tool that grew to be used by tens of thousands of Android developers. The breadth of the contributions that Jonathan made to the project are too wide to list in this post. He was involved in many high-profile projects such as -revamping [`PackageManager`](https://developer.android.com/reference/android/content/pm/PackageManager) -support and binary resources. He also worked extensively to get first-class support -for Robolectric in [Gradle](https://gradle.org/) and [Bazel](https://bazel.build). -Jonathan was passionate about continually improving the fidelity of Robolectric -to the point [where write-once, run-everywhere](https://medium.com/androiddevelopers/write-once-run-everywhere-tests-on-android-88adb2ba20c5) -was possible. This allowed the same test to either be run in Robolectric or any -physical or virtual Android device. +revamping [`PackageManager`][package-manager] support and binary resources. He +also worked extensively to get first-class support for Robolectric in +[Gradle][gradle] and [Bazel][bazel]. Jonathan was passionate about continually +improving the fidelity of Robolectric to the point +[where write-once, run-everywhere][write-once-run-everywhere] was possible. This +allowed the same test to either be run in Robolectric or any physical or virtual +Android device. More importantly, Jonathan had a great spirit and was beloved by friends and family. He was friendly, easy-going, and respectful. He settled near Mariposa, CA @@ -33,3 +33,8 @@ to be closer to nature and to enjoy the open space and fresh air. We miss you dearly, Jon. You will always be remembered by the Robolectric community. + +[bazel]: https://bazel.build +[gradle]: https://gradle.org +[package-manager]: https://developer.android.com/reference/android/content/pm/PackageManager +[write-once-run-everywhere]: https://medium.com/androiddevelopers/write-once-run-everywhere-tests-on-android-88adb2ba20c5 diff --git a/docs/blog/posts/2021-10-06-sharedTest.md b/docs/blog/posts/2021-10-06-sharedTest.md index 2d1c08945..9133a1072 100644 --- a/docs/blog/posts/2021-10-06-sharedTest.md +++ b/docs/blog/posts/2021-10-06-sharedTest.md @@ -98,7 +98,10 @@ If it finds current running environment has `RobolectricTestRunner`, it will del ## Not only sharing code, but also speeding up development -With `sharedTest` pattern, we can share test code as much as possible. Is it the only benefit to encourage you to use `sharedTest` pattern? Not yet. Actually, Robolectric is a simulated Android environment inside a JVM. It has better speed to establish and destroy tests environment, and developers can get test result more quickly. It can help developers to speed up [TDD cycles](https://developer.android.com/training/testing/fundamentals#create-test-iteratively): +With `sharedTest` pattern, we can share test code as much as possible. Is it the only benefit to +encourage you to use `sharedTest` pattern? Not yet. Actually, Robolectric is a simulated Android +environment inside a JVM. It has better speed to establish and destroy tests environment, and +developers can get test results more quickly. It can help developers to speed up [TDD cycles][18]: ![The two cycles associated with iterative, test-driven development](https://developer.android.com/images/training/testing/testing-workflow.png) @@ -135,3 +138,4 @@ There are some Google's projects have used `sharedTest` pattern to sharing test [15]: https://github.com/android/testing-samples/tree/main/ui/espresso/FragmentScenarioSample "FragmentScenarioSample of testing-samples" [16]: https://github.com/android/testing-samples/tree/main/ui/espresso/FragmentScenarioSample/app/src/sharedTest "sharedTest directory of FragmentScenarioSample" [17]: https://cs.android.com/androidx/android-test/+/master:ext/junit/java/androidx/test/ext/junit/runners/AndroidJUnit4.java "AndroidJUnit4 source code" +[18]: https://developer.android.com/training/testing/fundamentals#create-test-iteratively "TDD cycles" diff --git a/docs/blog/posts/2022-09-06-Umesh-GSoC-on-ConscryptMode.md b/docs/blog/posts/2022-09-06-Umesh-GSoC-on-ConscryptMode.md index 6b5196613..6edf6c10d 100644 --- a/docs/blog/posts/2022-09-06-Umesh-GSoC-on-ConscryptMode.md +++ b/docs/blog/posts/2022-09-06-Umesh-GSoC-on-ConscryptMode.md @@ -9,17 +9,35 @@ slug: Umesh-GSoC-on-ConscryptMode # GSoC 2022 - ConscryptMode -My name is [Umesh Singh](https://github.com/Umesh-01), and I was an open source contributor through Google Summer of Code this year. Google Summer of Code (GSoC) is a program where external participants can contribute to an open source project over a few months. We learn new computer science concepts, how to work on open source repositories, and create real code contributions to projects! +My name is [Umesh Singh][umesh-singh], and I was an open source contributor through Google Summer of +Code this year. Google Summer of Code (GSoC) is a program where external participants can contribute +to an open source project over a few months. We learn new computer science concepts, how to work on +open source repositories, and create real code contributions to projects! + +My project was +`Switching Robolectric from BouncyCastle to Conscrypt as the default security provider`. Robolectric +was using [BouncyCastle][bouncy-castle] as the Java Cryptography Extension (JCE) security provider. +After the introduction of Android P, Android switched to using [Google Conscrypt][conscrypt] as the +security provider. To be more consistent with Android, Robolectric needed to be updated to use +Conscrypt as the default security provider. -My project was `Switching Robolectric from BouncyCastle to Conscrypt as the default security provider`. Robolectric was using [BouncyCastle](https://www.bouncycastle.org/) as the Java Cryptography Extension (JCE) security provider. After the introduction of Android P, Android switched to using [Google Conscrypt](https://source.android.com/docs/core/architecture/modular-system/conscrypt) as the security provider. -To be more consistent with Android, Robolectric needed to be updated to use Conscrypt as the default security provider. - When I encountered Robolectric in the GSoC organization list, I know it would be a great fit. I had prior experience with Android development and was looking for growth opportunities in this area. Robolectric also offered a lot of learning opportunities in Java, security, and unit testing concepts. -The initial approach for this project was to drop BouncyCastle entirely and switch to Conscrypt. This seemed appealing due to the prior issues with BouncyCastle, such as [#5456](https://github.com/robolectric/robolectric/issues/5456). However, we discovered that we couldn't completely switch Robolectric to Conscrypt. Conscrypt only supports the security primitives provided by BoringSSL, and there were some legacy security primitives that were still being used in Android. Because of this, we realized that BouncyCastle was needed as the fallback security provider. We settled on having a [`@ConscryptMode`](../../javadoc/latest/org/robolectric/annotation/ConscryptMode.html) annotation that lets users choose whether Conscrypt will be installed or not. When Conscrypt is enabled, Robolectric will search for a requested security feature from Conscrypt first. If it does not support it, the other security providers will be queried. This is more consistent with how Android does it. - -- If [`ConscryptMode.Mode`](../../javadoc/latest/org/robolectric/annotation/ConscryptMode.Mode.html) is [`ON`](../../javadoc/latest/org/robolectric/annotation/ConscryptMode.Mode.html#ON), it will install Conscrypt and BouncyCastle. -- If [`ConscryptMode.Mode`](../../javadoc/latest/org/robolectric/annotation/ConscryptMode.Mode.html) is [`OFF`](../../javadoc/latest/org/robolectric/annotation/ConscryptMode.Mode.html#OFF), it will only install BouncyCastle. +The initial approach for this project was to drop BouncyCastle entirely and switch to Conscrypt. +This seemed appealing due to the prior issues with BouncyCastle, such as +[#5456][robolectric-issue-5456]. However, we discovered that we couldn't completely switch +Robolectric to Conscrypt. Conscrypt only supports the security primitives provided by BoringSSL, and +there were some legacy security primitives that were still being used in Android. Because of this, +we realized that BouncyCastle was needed as the fallback security provider. We settled on having a +[`@ConscryptMode`][conscrypt-mode] annotation that lets users choose whether Conscrypt will be +installed or not. When Conscrypt is enabled, Robolectric will search for a requested security +feature from Conscrypt first. If it does not support it, the other security providers will be +queried. This is more consistent with how Android does it. + +- If [`ConscryptMode.Mode`][conscrypt-mode-mode] is [`ON`][conscrypt-mode-mode-on], it will install + Conscrypt and BouncyCastle. +- If [`ConscryptMode.Mode`][conscrypt-mode-mode] is [`OFF`][conscrypt-mode-mode-off], it will only + install BouncyCastle. I have learned a lot about unit testing, such as how to test whether a piece of code is working according to the expected behavior, and about writing tests for specific scenarios. I have also learned about providing self-explanatory names to methods so that other developers can understand them easily in the future. @@ -27,4 +45,16 @@ I gained experience debugging a large, complex codebase like Robolectric, and ho I have also learned about the tradeoffs that sometimes arise in software projects. For example, Conscrypt does not currently support Mac M1, and to some extent this is out of our control. We were aware of this issue yet decided to move forward with making Conscrypt the default security provider on Linux, Windows, and Mac x86_64. The increased fidelity for these environments outweighs the lack of M1 support. We also have opportunities to collaborate with Conscrypt for Mac M1 support, or explore alternatives like repackaging Conscrypt for Robolectric until Conscrypt supports M1. -You can see my changes here in this [pull request](https://github.com/robolectric/robolectric/pull/7492) and here is a short [documentation](../../configuring.md#conscryptmode) about it. +You can see my changes here in this [pull request][robolectric-pr-7492] and here is a +short [documentation][conscrypt-mode-documentation] about it. + +[bouncy-castle]: https://www.bouncycastle.org +[conscrypt]: https://source.android.com/docs/core/architecture/modular-system/conscrypt +[conscrypt-mode]: ../../javadoc/latest/org/robolectric/annotation/ConscryptMode.html +[conscrypt-mode-documentation]: ../../configuring.md#conscryptmode +[conscrypt-mode-mode]: ../../javadoc/latest/org/robolectric/annotation/ConscryptMode.Mode.html +[conscrypt-mode-mode-off]: ../../javadoc/latest/org/robolectric/annotation/ConscryptMode.Mode.html#ON +[conscrypt-mode-mode-on]: ../../javadoc/latest/org/robolectric/annotation/ConscryptMode.Mode.html#ON +[robolectric-issue-5456]: https://github.com/robolectric/robolectric/issues/5456 +[robolectric-pr-7492]: https://github.com/robolectric/robolectric/pull/7492 +[umesh-singh]: https://github.com/Umesh-01 diff --git a/docs/blog/posts/2023-11-11-improving-android-all-downloading.md b/docs/blog/posts/2023-11-11-improving-android-all-downloading.md index 3181100d3..7a1249380 100644 --- a/docs/blog/posts/2023-11-11-improving-android-all-downloading.md +++ b/docs/blog/posts/2023-11-11-improving-android-all-downloading.md @@ -10,17 +10,15 @@ slug: improving-android-all-downloading In recent years, the team has received multiple issues regarding Robolectric's inability to download/resolve the necessary android-all jars when running Robolectric tests in a CI environment. Some examples include: -1. [android-all not downloaded as part of robolectric, or is it a separate dependency?](https://github.com/robolectric/robolectric/issues/7886) - -2. [Robolectric failing because not downloading dependencies in Jenkins when using Artifactory](https://github.com/robolectric/robolectric/issues/8158) - -3. [Flaky SHA mismatch on CI builds when retrieving Maven artifacts since upgrading to 4.10.x](https://github.com/robolectric/robolectric/issues/8205) - -Robolectric downloads the necessary android-all jars using its [MavenArtifactFetcher](https://github.com/robolectric/robolectric/blob/7fa0183c592974c3a84e948605f5278addae2731/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java#L37) when running Robolectric tests. -It does not use any proxies defined by the Gradle build system. -In a CI environment, especially in environments used by large companies internally, -there are often network restrictions that can cause the aforementioned issues. -This article provides some solutions to mitigate these issues as much as possible, +1. [android-all not downloaded as part of robolectric, or is it a separate dependency?][robolectric-issue-7886] +2. [Robolectric failing because not downloading dependencies in Jenkins when using Artifactory][robolectric-issue-8158] +3. [Flaky SHA mismatch on CI builds when retrieving Maven artifacts since upgrading to 4.10.x][robolectric-issue-8205] + +Robolectric downloads the necessary android-all jars using its +[MavenArtifactFetcher][maven-artifact-fetcher] when running Robolectric tests. It does not use any +proxies defined by the Gradle build system. In a CI environment, especially in environments used by +large companies internally, there are often network restrictions that can cause the aforementioned +issues. This article provides some solutions to mitigate these issues as much as possible, including setting a custom proxy for `MavenArtifactFetcher`, leveraging Robolectric's offline mode, and manually fetching the necessary android-all jars before running Robolectric tests. @@ -71,8 +69,8 @@ testOptions { } ``` -[Robolectric's configuration documentation](../../configuring.md#system-properties) contains a -detailed description of these special Robolectric properties, and you can read it for more details. +[Robolectric's configuration documentation][robolectric-system-properties] contains a detailed +description of these special Robolectric properties, and you can read it for more details. ## Leveraging Robolectric's offline mode @@ -101,7 +99,7 @@ To make it work, we need to download android-all jars into the `${rootDir}/robolectric-jars/preinstrumented` directory before running any Robolectric tests. I created a sample project to provide build scripts to download these android-all jars into this preinstrumented directory: -[robolectric-offline-sample](https://github.com/utzcoz/robolectric-offline-sample/). +[robolectric-offline-sample][robolectric-offline-sample]. ```kotlin plugins { @@ -164,12 +162,10 @@ might add a new android-all jar for a new Android version or modify internal log to update an existing android-all jar's version, these android-all jars might change across different Robolectric versions. If you store them in a Git repository, your Git repository might become bigger and bigger. If you like this approach, -you can store android-all jars in an external repository like -[AndroidX](https://android-review.googlesource.com/c/platform/prebuilts/androidx/external/+/2813314). +you can store android-all jars in an external repository like [AndroidX][androidx]. -[Robolectric's configuring documentation](../../configuring.md#system-properties) contains -a detailed description of these special Robolectric properties, and you can -read it for details. +[Robolectric's configuring documentation][robolectric-system-properties] contains a detailed +description of these special Robolectric properties, and you can read it for details. ## Fetching android-all jars manually before running Robolectric tests @@ -178,10 +174,10 @@ and you don't want to modify your system properties for Robolectric in your `build.gradle.kts`, you can try to download android-all jars in a script and download them manually before running any Gradle tasks. -For example, I created a project to do it for myself: -[robolectric-android-all-fetcher](https://github.com/utzcoz/robolectric-android-all-fetcher/). -You can change the Maven mirror to any one you like and run the script to download -all android-all jars for a specific Robolectric version. +For example, I created a project to do it for myself: +[robolectric-android-all-fetcher][robolectric-android-all-fetcher]. You can change the Maven mirror +to any one you like and run the script to download all android-all jars for a specific Robolectric +version. ## Conclusion @@ -189,3 +185,12 @@ Most of these issues are caused by a network issue when downloading necessary an and we can fix them or ease them by making android-all jars accessible before running Robolectric tests and letting `MavenArtifactFetcher` use them directly. The above potential solutions are some stable and recommended solutions for developers to try. Hope it can help you. + +[androidx]: https://android-review.googlesource.com/c/platform/prebuilts/androidx/external/+/2813314 +[maven-artifact-fetcher]: https://github.com/robolectric/robolectric/blob/7fa0183c592974c3a84e948605f5278addae2731/plugins/maven-dependency-resolver/src/main/java/org/robolectric/internal/dependency/MavenArtifactFetcher.java#L37 +[robolectric-android-all-fetcher]: https://github.com/utzcoz/robolectric-android-all-fetcher +[robolectric-issue-7886]: https://github.com/robolectric/robolectric/issues/7886 +[robolectric-issue-8158]: https://github.com/robolectric/robolectric/issues/8158 +[robolectric-issue-8205]: https://github.com/robolectric/robolectric/issues/8205 +[robolectric-offline-sample]: https://github.com/utzcoz/robolectric-offline-sample +[robolectric-system-properties]: ../../configuring.md#system-properties diff --git a/docs/blog/posts/2024-02-25-robolectric-2024-gsoc.md b/docs/blog/posts/2024-02-25-robolectric-2024-gsoc.md index 8ddff8159..12a81ce54 100644 --- a/docs/blog/posts/2024-02-25-robolectric-2024-gsoc.md +++ b/docs/blog/posts/2024-02-25-robolectric-2024-gsoc.md @@ -28,13 +28,12 @@ ecosystem as a whole. ## The Robolectric GSOC experience -This is the second time Robolectric has participated in GSOC ([the last time -being in 2022](2022-09-06-Umesh-GSoC-on-ConscryptMode.md)). Students who work -on Robolectric will gain a deeper understanding of the Android framework, JVM -internals, and testing methodologies. Students will also collaborate with the -Robolectric maintainers and other members of the Robolectric community, many -of whom are professional Android developers. Students participating in GSOC -will also receive a stipend from Google! +This is the second time Robolectric has participated in GSOC +([the last time being in 2022][robolectric-gsoc-2022]). Students who work on Robolectric will gain a +deeper understanding of the Android framework, JVM internals, and testing methodologies. Students +will also collaborate with the Robolectric maintainers and other members of the Robolectric +community, many of whom are professional Android developers. Students participating in GSOC will +also receive a stipend from Google! ## Ideal GSOC candidates @@ -54,14 +53,18 @@ mentor and host were in a compatible time zone. ## More information -The Robolectric profile for GSOC 2024 can be found [here](https://summerofcode.withgoogle.com/programs/2024/organizations/robolectric). +The Robolectric profile for GSOC 2024 can be found [here][robolectric-gsoc-profile]. -Review the [Robolectric GSOC 2024 project -list](https://docs.google.com/presentation/d/1Wyqkef0bK3c9EbZzTdFw7S9Hx5-fq9iRgNbVWozQ2q0/edit?usp=sharing) for a list of project ideas. +Review the [Robolectric GSOC 2024 project list][robolectric-gsoc-project-list] for a list of project +ideas. -If you have any questions, please start a discussion -[here](https://github.com/robolectric/robolectric/discussions) or email any of +If you have any questions, please start a discussion [here][robolectric-discussions] or email any of the Robolectric maintainers. We are very excited for the summer and hope that GSOC 2024 is an awesome experience for everyone involved! + +[robolectric-discussions]: https://github.com/robolectric/robolectric/discussions +[robolectric-gsoc-2022]: 2022-09-06-Umesh-GSoC-on-ConscryptMode.md +[robolectric-gsoc-profile]: https://summerofcode.withgoogle.com/programs/2024/organizations/robolectric +[robolectric-gsoc-project-list]: https://docs.google.com/presentation/d/1Wyqkef0bK3c9EbZzTdFw7S9Hx5-fq9iRgNbVWozQ2q0/edit?usp=sharing