Testing Strategy and it's Theory in Android

Writing Tests for different components that go in production is really important specially when the app has a large user base.

How we can define a good testing strategy?

One should consider 3 aspects

  1. Scope - How much Code does the test covers?

Unit Tests cover a single method or Class, Instrumented Tests can cover Interaction between different classes and E2e Tests can cover a complete functionality. Unit Tests < Integration Tests < E2e Tests

2. Speed - How much time your tests take to run?

E2e Tests < Integration Tests < Unit Tests

3. Fidelity - How reliable are your tests?

If your tests are able to mimic the real world use case such as a user's interaction with the app or starting up the app along with testing some functionality then it is highly reliable. Unit Tests < Integration Tests < E2e Tests

Trade off between these 3 aspects helps a team to decide the best testing strategy for their project.

Note - All the observations written here are based on using JUnit’s framework for testing, it’s dependencies are included by default in any new Android

Library for making assertions?

Assertion is what you expect from the test? Results of a Test should be exhaustive, It should either FAIL or PASS.

If we generate any Test Class by right clicking on the unit we want to test such as a Class, method etc. Android Studio adds an import statement import org.junit.Assert.*

The syntax for asserting results is this

assertEquals(actual value, expected result)

this statement is not very understandable as per google, Hamcrest assertion library provides a better asserting statement

Hamcrest’s version of asserting results

assertThat(actual value, `is`(expected value))

Dependency

testImplementation "org.hamcrest:hamcrest-all:$hamcrestVersion"

Why are there back quotes in the is?

In Kotlin, is is a reserved keyword, so to differentiate this as the Hamcrest is, you use back ticks.

Google also recommends another library called Truth , which I personally use, Truth’s version of asserting results

assertThat(actual value).isEqualTo(expected value)

Dependency

testImplementation "com.google.truth:truth:1.0.1"

I personally use Truth.

Where to write tests in the project?

A new Android Project by default have 3 source sets main, test and androidTest. Our tests are located in the test and androidTest source tests.

image.png

Suppose there is a file which we want to test is located inside the package com.testingdemo.utils then it's corresponding test class will be located at the same package inside test or the androidTest.

Difference between test and androidTest source sets

For the components which can be run on JVM, you will place your test cases for those components inside the test source set. Eg. include simple utility classes which perform logical operations.

If you want to write tests about a component in your app which needs Android Runtime Components such as context then you will place your tests inside the androidTest directory. One example of such a component is Room Database because it requires the context of application.

With AndroidX Testing library it's possible to write the test cases for components which uses context inside both test source set and androidTest source set but that's not in the scope of this blog.