Sharing Android instrumentation tests between modules - android

Our Android app code is setup is like below:
Project
----Module1
----Module2
----Common UI library module
----Common SDK module
Module 1 and Module 2 are built into separate apks and published separately. They however share/extend a great deal of UI that are in the library module. Currently we have instrumentation tests inside each module, which means we have to duplicate tests for the same screens (defined in the UI module) under both Module 1 and Module 2. Is there a way to strip out the instrumentation tests from the specific modules and have a separate test module? I would ideally like to have shared tests where I can specify through command line something along the lines of: "Run test suite T against the test apk for Module 1" or "Run test suite T against the test apk for Module 2.
Any suggestions on how to do this is appreciated.

Related

Run androidTest from app module including androidTest from submodules without own activities

I have a project with a single module app and then lots of other modules like search and detail. app has MainActivity and almost nothing else. The other modules have lots of #Composable functions that make up the actual completed application. The individual modules also have tests in androidTest for automated testing.
How can I run the tests declared in each submodule but against the app build apk?
Directory structures may make this clearer:
/project/app/src/main/.../MainActivity.kt
/project/search/src/main/.../SearchComposable.kt
/project/search/src/androidTest/.../SearchTests.kt
/project/detail/src/main/.../DetailComposable.kt
/project/detail/src/androidTest/.../DetailTests.kt
If I run
./gradlew :search:connectedDebugAndroidTest
it will try to run those tests but they don't have an Activity, they only really run from app. Unit tests of course work fine, but automated tests do not.
If I run
./gradlew :app:connectedDebugAndroidTest
Then it will only run those declared within app. I haven't figured out a way to add a dependency from app's androidTest configuration to search/detail's androidTest output (lots of searching, nothing promising yet).
If I run
./gradlew connectedDebugAndroidTest
It will try to run all and fail to run search and detail since they don't have an activity.

How can I share a Module's androidTest "Robots" with another module?

I am a big fan of the Robot pattern for keeping UI tests clean. But how can I reuse Robot classes across multiple modules?
:lib-with-ui . // has Robot classes in `src/androidTest`
:app
I fully test my lib-with-ui with the Robot classes, however I want to reuse those same Robot classes in the :app module for some quick smoke testing.
For why the smoke testing is useful, it's because we want to test the integration of all our components as well as catch any possible proguarding issue that may occur (we have a special flavor of our sample app that utilizes proguarded AARs of our libraries).
We've tried a variety of approaches to get this to work, but it has all lead to weird resource issues.
Robot classes are defined in module 'lib-with-ui' and you want to use this in module 'app'?
Add lib-with-ui android library module as dependency to app module. Any code and resources in the Android library is now accessible to your app module, and the library AAR file is bundled into your APK at build time.
https://developer.android.com/studio/projects/android-library.html#AddDependency

Why there is no task generateXXXSource in instant app module?

For a project include installable, instant, and other modules, I can see there are gradle tasks of :installable:generateGoogleReleaseSources, :<module_name>:generateReleaseSources but I only see :instant:dummyGoogleRelease and there is no :instant:generateGoogleReleseSources (or any variant of it)
You can see it in action inside Android studio (this one is debug variant):
Executing tasks: [:instant:dummyDebug, :main:generateDebugSources, :detail:generateDebugSources, :base:generateDebugSources, :installed:generateDebugSources]
Is that supported? Cause I want to generate BuildConfig for instant app. The app module and the base module has it, instant module doesn't has it.
I tried put java sources, manifest, etc and same result.
(My android project has installable, instant, core (base feature), and many other library modules, as suggested by Google.)

How to run unit test on a android module?

I have a android project that has multiple library modules and I am trying to test a specific package that contains all modules.
I tried this command:
./gradlew -Dtest.single=com.moduleone* testProductionDebug
And it does not work: it doesn't execute the tests inside this module, but instead executes all the unit tests in the main project package class.
How do I test just the one module?
You can use test suits: https://developer.android.com/reference/junit/framework/TestSuite.html . Definition of a suit contains classes of tests you need
Assuming you're trying to execute a gradle task against a single module rather than the entire project, you can supply the name of the module in front of the task separated by a colon (module_name:task)
Per your question, this would look something like
./gradlew -Dtest.single=com.moduleone* your_library_module:testProductionDebug
This is a simple example, assuming you have a simple project setup. You can also find further reading on this in the gradle docs for executing a multi-project build

Multi module test code reuse

I have a multi module Android Studio project composed of 3 modules:
app (regular and unit-test configs) - contains main app code and tests
common (regular and unit-test configs) - contains common code and tests that are shared with another app
common-testing (regular config only) - contains common testing utility code used in the tests of the other 2 modules
Now common-testing (regular) depends on common (regular) for certain classes. This gets dicey in the common (unit-test) configuration, where a circular dependency develops. The dependencies for that case are mapped below:
common (unit-test) depends on common (regular)
common (unit-test) depends on common-testing (regular) depends on common (regular)
Unfortunately the last line is a circular dependency (common depends on common), and the project fails to evaluate.
Is there a way to instruct Gradle to break out of a circular dependency? Some sort of include guard like in C/C++?
If not, are there alternate ways of organizing the project to successfully share test code (like runners) between modules?

Categories

Resources