Best practices for testing multi module android app - android

I have an application with 4 different modules. Network layer is separated in different module and I created a fake repository for unit testing in it.
The problem is that I cannot access that fake repository in my main module test classes (for creating test classes for viewmodels). I tried different solutions from google and none of them are working.
If I use something like this in gradle
testImplementation(project(":data"))
Test classes are still not visible.
My question is what are the best practices when writing tests for multi module android application? Is good practice to create one module for test and put everything related to testing from every module in that one? Or is there a way to make test classes from other modules visible in my main module?

Related

A way to share code between multiple android test modules

I want to achieve something like this:
[ComponentTestsModule] com.android.test
[FunctionalTestsModule] com.android.test
both depends on
-> [TestLibraryModule] ?
which depends on
-> [AppModule] com.android.application
Is there any way to do it with android Gradle plugin 3.0+?
Why I need multiple test modules?
I want different test runners for different types of tests, also target different variants.
It is working right now with single codebase under androidTest, but with ugly switches in the custom test runner.
Why I need a test library module?
I want to share the same page-objects between different types of tests, and maybe some utility code.
Problem is: that page objects must have access to R class of app (locators: R.id.*)
None of the module types I'm aware of can depend on APK-producing module, expect from com.android.test, but i cannot depend from com.android.test with another com.android.test.
I have recently faced this problem and just want to share my solution in case some body needs it.
What I have done so far (not a perfect solution - I guess, but at least it works).
Create a new module named testing_base or some thing like that
In testing_base module only put things related to testing (Like the code you want it to be shared between modules) in to normal packages, NOT in the test packages/folders.
From others module, try to import things from testing_base module
ex: testImplementation project(":testing_base")
Hope it can helps someone, happy testing!
I want different test runners for different types of tests
To run a test class with a specific test runner, use the #RunWith annotation.
also target different variants
To target a specific variant, create your tests in app/src/androidTestVariantName for instrumented tests or in app/src/testVariantName for unit tests.

In clean architecture, How to do acceptance testing?

In Android, I'm using clean architecture and putting my code packaged by layer. So I've 4 layers (modules) :
app
data
device
domain
I know, correct me if I'm wrong, that acceptance testing (Using FitNesse) should replace UI in better words, it should mimic UI and test core functions of the system from customer's point of view.
My Question is :
Should I create another module for FitNesse fixtures and stuff, with dependencies on each module in the system?
This is what I usually see done, yes. The builder system (maven, gradle, etc.) is tweaked so that it does not include the module containing the fixtures in the production artifact. The module containing the fitnesse fixtures is aware of / has dependencies to all of the modules it directly tests, which tends to be the domain layer.

(Dis-) Advantage of having multiple modules in an Android Studio Project?

Is it advantageously to have multiple modules in an Android Studio Project over having only a single large app-module?
I know about Android Modules in general and the advantages of SOLID so my focus is especially considering build performance. As gradle can do incremental builds, and if only one module changes, those other modules don't need to be processed?
Is this noticeable or is there even a considerable amount of overhead?
It is of great advantage to have multiple modules rather than to create a single large app-module. Following are the key points:
If you find the compile time is taking longer then you can disable the module from gradle you are not working upon temporarily and compile it faster.
A module helps us to divide project into discrete units of functionality also. You can create one data module which contains all pure java beans and can be used by multiple app if you are in same domain. Eg. Finance domain can have two applications one for viewing policies for customer and other can be for an insurance agent for viewing the same data. But the data module can be shared across all apps and even the data module can be borrowed from server or API team. Data module can be tested individually without any android dependencies and any one knows about java can write test cases.
Each module can be independently build, tested, and debugged.
Additional modules are often useful when creating code libraries within your own project or when you want to create different sets of code and resources for different device types, such as phones and wearables, but keep all the files scoped within the same project and share some code.
Also Android app module and Library module are different.
You can keep two different versions of module based on the API releases as from ASOP.
You can have a look for more on android developer resource
How modularization can speed up your Android app’s built time
App modularization and module lazy loading at Instagram and beyond
Modularizing Android Applications by Mauin
Survey on how Android developers were modularising their apps
There was an article on Medium yesterday, which exactly adresses my question:
https://medium.com/#nikita.kozlov/how-modularisation-affects-build-time-of-an-android-application-43a984ce9968#.at4n9imbe
tl;dr:
First and most important, the hypothesis was correct, modularising project can significantly speed up build process, but not for all configurations.
Second, if splitting is done in a wrong way, then build time will be drastically increased, because Gradle build both, release and debug version of library modules.
Third, working in test-driven way is much easier for a project with multiple modules, because building a small library module is way faster then the whole project.
Forth, doing many things in parallel slows down the build. So having more powerful hardware is a good idea.
Below you can find results of all experiments described in this article
Update
Addressed at Google I/O '17: https://youtu.be/Hx_rwS1NTiI?t=23m17s

What are the benefits of a multi-project build in Android?

I'm reading the source code of Android : Clean Architecture, mostly to learn how to properly organize an application into layers, and for the MVP pattern, and also to match it with what I've been reading on MVP here.
However, as pretty as I find the structure, I don't really understand the benefit of order a single application into multiple sub-projects or modules. Considering they (data, presentation, domain) depend on one another, and eventually will be part of the same executable, it looks more like configuration hell.
dependencies {
...
compile project(':domain')
compile project(':data')
What are the benefits of compartmentalizing an Android application into multiple subprojects (modules), rather than keep them in one project but separate them merely by packages?
Actually this question is not Android-specific but more software architecture related as it applies to almost any software you develop (e.g. why does any app consists of several modules and not all in one package).
Splitting the code into modules would provide you at least the following benefits (these are the first 3 that comes to my mind):
Clear isolation between the modules. The whole goal of the MVP pattern is to make sure your business logic and presentations layer are not tightly coupled together. By defining these in different modules it makes this separation more clear and encourages you to stick to this pattern.
Code reuse - consider the case where you have one application that you'd to sell for several customers, but each of these customers would like to get a different look and feel. If you'll have all of your code in one monolithic project you'll have to either have many forks of your project, one for each customer or otherwise bloat the provided app code with the customization options. Now, if on the other hand you had separated your modules, then you could just prepare a different presentation layer for each customer and bundle it with the other common modules.
Splitting your project into sub-project allows more efficient build and testing as you can rebuild and test only the modules that changed rather than recompiling the whole project whenever there's a change in one of the files.
I hope that this makes sense to you.
The main benefit of using multi-module projects, instead of just packages, is that the code usage between modules goes in one direction only.
Any code inside the module can have a back-and-forth relationship:
A -> uses classes from -> B
and
B -> uses classes from -> A
If A and B are in separate modules, this only goes one-way:
A -> (uses classes from) -> B...
But B can't see anything in A.
This splits up your thinking into smaller, bite-sized chunks. If you need to understand how a class in module B works, you only need to look at the other classes in B.
But in the first scenario, you have to look at the all the classes in both A and B.
As an added bonus, if you do want to reuse any code, you can copy that module right over to the next project.
I usually put the bulk of my code in modules, with a thin app layer connecting them all together. I recommend using dependency inversion to make any connections between modules.
Another Android specific advantage of splitting into modules apart from faster build time is that the update size of your app will be less.

How can I have unit and functional tests for my android independent calsses without needing a device?

I am developing an android app and I want to be able to test the android independent classes (which basically contain my logic) using junit without needing a device. The question is that is it possible? and if yes, what would be the correct package hierarchy. I've been searching and doing some trial and error (I am using eclipse) but couldn't come to a solution.
You can use regular unit tests and run them with Eclipse. I used this blog to learn how to write unit tests for android:
http://www.vogella.com/tutorials/JUnit/article.html
In my apps im using package hierarchy similar to this:
abc.core - contains all core classes, interfaces and skeleton of infrastructure
abc.data - contains all data access logic
abc.logic - contains all business logic and services
and then
abc.android - contains android project, where your views use mostly abc.logic package
tests:
abc.core.tests - contains unit tests od core
abc.data.tests - constains all data tests
abc.logic.tests - constains all logic tests
I know than the package count is quite high, but I came from .Net world :)

Categories

Resources