Why must Jetpack Compose tests be Instrumentation tests? - android

In this code lab, it says that “Compose tests are instrumented tests. This means they require a device (physical device or emulator) to run on.” This implies they must be in the androidTest package.
Can anyone explain why this is? I am able to run my compose tests as unit tests using Robolectric (test package) so not sure why the documentation explicitly calls this out.

Related

Gradle ConnectedAndroidTest - Attach Test Listener

I'm working on an SDK that uploads real-time Android test results to a backend. I'd like to be able to attach a test listener to the instrumented tests that run when the connectedAndroidTest gradle command is invoked.
I can annotate the tests with #RunWith and have them use a custom runner with its own listener, but this solution is not ideal, as users implementing this SDK will have to annotate each and every test. We're looking for something that works at a global level.
For unit tests, we can hook into the gradle test API and listen for test results. But, instrumented tests use different gradle APIs, provided by the Android Gradle Plugin (this is where the connectedAndroidTest task comes from). There doesn't seem to be an equivalent gradle-based test listener.
I can set a JUnit test listener via the testInstrumentationRunner in build.gradle - but this listener runs on the Android device under test - I'm looking for something that can listen to test results on the local machine, rather than the Android device.
Android Studio seems to have this capability - when running Instrumented Tests via a run configuration, the IDE can report on instrumented test results in real-time. I've had a dig around in the source code, but it's not clear to me how this works.
Any help would be greatly appreciated!

Run JVM unit test as an Android instrumented test

I added unit tests (that run on bare JVM) to a Kotlin library, and I'd like to also run the code in ART (Android Runtime) and Dalvik VM against the Android API, reusing the defined tests in the test sourceSet, and running them with tests in the androidTest sourceSet, on a real device or in an emulator.
Is this possible, and if so, how?
The reason why I want to do this is that I run some code on the main thread when on a real device, falling back to a custom thread if an error/exception is thrown because not running on a real device, but I also want to test the code when it doesn't fallback because it is running on a real device which has access to the main thread.
Yes, move the JVM tests from 'test' directory to androidTest target. It runs the JVM tests along with instrumentation tests.

Unit test for AOSP code?

Are unit test cases provided for any app in AOSP(Android Open Source Project)in android? Suppose take Gallery App, which is a system app. If I download the AOSP, Is complete test suite available for Gallery App. I meant to say both unit tests and Instrumentation test suites?
From my experience in working with AOSP, there is a python script called runtest.py in platform development/testrunner/runtest.py to run every available unit tests on each module in AOSP. It is a good starting point to look for what you want, but beware some unit tests are outdated and obsoleted.
You can add tests and then be include into runtest.py to form a test suite. runtest.py will help you compile, deploy then run the unit test suite on the target device.

Integrating uiautomator test cases with Instrumentation test cases

We have already written test cases in Android Instrumentation with InstrumentationTestRunner now as this does not support app switching so we have planned to create some UIAutomation based test cases but we are struggling in merging this test cases. We want to create a single suite from where we can run Instrumentation as well as UiAutomator test cases.
As far as I know for running UiAutomator requires AndroidJUnitRunner but this does not support Instrumentation test cases.
UiAutomator does not require AndroidJUnitRunner, you can use InstrumentationTestRunner if you like.
AndroidJUnitRunner can also run regular Android instrumentation tests, so you could use AndroidJUnitRunner for both types of tests instead.
In general, I'd recommend using AndroidJUnitRunner since it is updated more frequently and supports JUnit4.

Best way to run Robolectric tests on Android device

I have a Robolectric test project setup, but I'd like to also run these tests on my device to check that I don't get bit by JVM vs Dalvik implementation differences.
Unlike robolectric tests, I won't run these tests frequently. My concern is that there's little effort to maintain the test suite and that they verify actual device functionality.
What's the best way to do that?
What I've currently got:
My robolectric test project as a test case TestPackage. I created an Android Test project with a test case TestRoboOnAndroid. It creates a TestPackage and has a test for each test in TestPackage.
Right now, every time I add a test to my robolectric suite, I need to manually add it to my device suite. Is there some way to do that automatically with reflection?
Also, Robolectric uses JUnit 4 (by default) and Android uses JUnit 3. So I have to write all of my Robolectric tests using JUnit 3 style (importing from junit.framework instead of org.junit).
The whole point of Robolectric is NOT to run it on the device and the design is based on that. If you want to run something on the device look at the default instrumentation tests from the SDK or Robotium.
It is totally feasible to run your Robolectric tests on the JVM and in addition create Robotium tests that rely on device specific interaction (e.g. creating screenshots, hardware differences...) and run on devices and emulators all combined into one build.
The easiest way to do that is to use the Android Maven Plugin.
I use a tiered system, where I prefer earlier tiers where possible:
Pure unit tests. I try to make as much code as possible fully independent of Android APIs, and then use "pure" unit tests which can run on any JVM. These tests are the fastest, and it helps keep code that has no need to be Android-specific portable.
Robolectric-supported unit tests. Where my code has only small dependencies on Android APIs, that can be satisfied by Robolectric shadows, I test it with Robolectric. There is a little more setup time for Robolectric compared to pure tests, but it's still faster than starting/running on an emulator.
Android framework tests. Where Robolectric doesn't cut it - either because the shadows don't exist, or because I'm heavily using Android APIs (and therefore want to test against the Real Thing) - I write test that run on the emulator/device with the default framework.
The point of the tiers is to keep things as simple as possible, which keeps the full suite faster and helps promote cleaner code.
We use Robolectric for unit testing against the JVM and Calabash-Android for system testing against Dalvik. Both can be integrated into our Jenkins CI build and between the two tools I feel that we cover all the bases.

Categories

Resources