Unit Testing for Android
Unit Testing for Android
Presented By
Yasmeen Hosny
About Course
• Duration (18 hours)
- 2 Lectures (6 hours)
- 2 Labs (6 hours)
• Evaluation
40% on Labs
60% on Project
Agenda
JUnit Espresso
Testing Scopes
Unit Testing
• Low fidelity
Integration Test
● Both test source sets doesn’t know anything about each other
● When you upload your application to the store none of your test
cases will be added.
TO-DO Notes Application
The app allows you to:
1. Add tasks to complete and displays
them in a list.
2. Mark tasks as completed or not.
3. Filter tasks.
4. Delete tasks.
Great! Test
passed.
Make your test readable
1. Naming
2. Code Structure (Given/When/Then)
3. Assertion framework
Naming
General Form:
subjectUnderTest_actionOrInput_resultState
Ex:
getActiveAndCompleteStates_noCompleted_returnZeroCompleteHundredActive
Given – When – Then
Sometimes called as Arrange Act Assert (AAA)
It is a strategy to structure the code inside the testing function
• Given: sets up the objects and the state of the app that you need for
the test
• When: make the actual actions and changes to the subject under test
• Then: checks what happen when you do the action how your changes
affect (often done using assertion framework)
Assertion framework
We can use different assertion framework to make our tests more readable.
For example:
• Hamcrest
• Truth
testImplementation “org.hamcrest:hamcrest:2.2”
testImplementation “org.hamcrest:hamcrest-library:2.2”
assertEquals(0f, result.completedTasksPercent)
assertThat(result.completedTasksPercent, `is`(0f))
JVM
Testing
(Logic)
• If there are two completed tasks and three active tasks (the completed
percentage should be 40f and the active percentage should be 60f.)
• If there are empty list (that the percentage of active tests is 0%,and the
percentage of completed tasks is 0%.)
4. Select the test directory (not androidTest) because we'll be writing local tests.
Testing ViewModel
App Architecture Application
Repository
The test you'll write will check that when you call the addNewTask
method, the Event for opening the new task window is fired. Here's the
app code you'll be testing
TasksViewModel
When we want to run a test as a local test but it requires a class from
android we can use AndroidX
AndroidX test
Collection of libraries for testing. It includes classes and methods that give
you test versions of components like applications and activities.
They are built to work both for local tests and instrumented tests. So:
• You can run the same test as a local test or an instrumented test.
• You don't need to learn different testing APIs for local vs. instrumented
tests.
When you write your code using AndroidX Test libraries, you can move it
from the test folder to the androidTest folder and the tests will still run.
Robolectric
Robolectric is a library that creates a simulated Android environment
for tests and runs faster than booting up an emulator or running on a
device.
The simulated Android environment that AndroidX Test uses for local
tests is provided by Robolectric.
Test Runner
• A test runner is a JUnit component that runs tests. Without a test
runner, your tests would not run. There's a default test runner provided
by JUnit that you get automatically. @RunWith swaps out that default
test runner.
4
Testing LiveData
Observing LiveData in local test
We used to observe liveData. Without observation the value will be
null but to observe it we need a LifecycleOwner like activity or
fragment
which is not available here in local test.
How to solve this ??
the magic keyword is observeForever
which ensures the LiveData is constantly observed,
without needing a LifecycleOwner
Observing LiveData in local test Con.
Observation steps
1. Create observer
2. Observe livedata
3. Add new task
4. Assert livedata
5. Remove the observer Remember !!
Observing LiveData in local test Con.
1
2
5
Observing LiveData in local test Con.
• The previous solution works well. But every time we test the liveData
we will be creating the same dummy observer, handle it and finally
remove it. It seems like a Boilerplate code!