One of the integral phases of application development life cycle is testing but the question is why?
The answer is to eliminate the occurrence of ANR dialog or unexpected behavior in application logic. For Android, all UI updation is handled by the main thread and if the main thread is unable to respond to user events within 5 seconds then it causes the application to crash and gives the user an option to close the application instead of keeping the user in an infinite waiting state, resulting in poor user experience.
Application Not Responding dialog is the least expected event that can occur when the main thread (aka UI thread) is blocked for too long. Some instances that may cause this are:
Rendering a larger image
Performing REST calls on main thread
Other reasons are Exceptions, infinite recursive method calls, missing class definitions, deadlocks ,or implementation of unsupported features on older versions like vector drawable etc.
TDD is a recursive cycle of writing code, testing, and refactoring the code to resolve bugs the moment they appear. TDD lays out the approach to test the working of the application after every modification in code base. The objectives of TDD are:
To meet the requirements that guided the application design and development
To determine the performance of an application under different environments considering
Network connectivity
User input
Server stability
To validate the application security against SQL injections and data security vulnerabilities
"Testing leads to failure and failure leads to understanding :- Burt Rutan"
Unit Testing : Unit tests run on the local machine, i.e. Java Virtual Machine (JVM), which means it requires no device or emulator. Unit tests tend to be fast because units test don't test any Android specific dependency (Activity,SharedPreferenc) or mock objects are used to mimic the behavior of android framework dependencies.
Unit tests are located under
package-name/src/test/java/
Instrumentation Testing : Instrumentation tests are specifically designed to test the UI of an application and requires an emulator or physical device to perform tests. Android UI components depend upon Context to access the resources in an application like xml, images, string, and other resources. Context is provided by the Android operating system, so for instrumentation testing the context is provided by the Instrumentation API to track the interaction between android OS and to application i.e. to give commands to activity life cycle, environment details etc.
Instrumentation tests are located under
package-name/src/androidTest/java/
AndroidJUnitRunner
is a JUnit test runner that lets you run JUnit tests on Android devices while providing annotations to ease-up the testing procedure. For instrumentation tests, the test class must be prefixed with @RunWith(AndroidJUnit4.class).@Test
Annotation is used to mark a method for testing and methods with @Before
annotation are executed first to setup the environment for testing and methods with the @After
annotation executed at the end. @LargeTest
annotation is used to indicate that the test duration can be greater than 1 second.mockito
is often used for unit testing to create dummy objects to mimic the behavior of objects.Espresso is a testing framework by Google for UI (user-interface) testing which includes every View
component like buttons, List, Fragments etc. Espresso is collection of testing APIs, specifically designed for instrumentation/UI testing. UI tests ensure that users don’t have poor interactions or encounter unexpected behaviors.
Espresso has various options to find 'View' on screen, perform actions, and verify visibility and state/content of 'View'.
1onView(withId(R.id.my_view)) // onView() is a ViewMatcher</strong>
2 .perform(click()) // click() is a ViewAction</strong>
3 .check(matches(isDisplayed()));// matches(isDisplayed()) is a ViewAssertion
ViewMatcher : used to locate the view in the UI hierarchy(tree structure of xml layout components) using withId(R.id.id_of_view)
, withText("find by text on view")
.
ViewActions : used to perform a specific action or group of actions in the UI views using ViewInteraction.perform(click(),doubleClick())
or click()
, longClick()
, doubleClick()
, swipeDown()
, swipeLeft()
, swipeRight()
, swipeUp()
, typeText()
, pressKey()
, clearText()
, etc.
ViewInteraction.check(assertion method)
where assertion methods can be isDisplayed()
, isEnabled()
, isRoot()
.build.gradle
app module:1dependencies {
2 implementation fileTree(dir: 'libs', include: ['*.jar'])
3
4 // AndroidJUnitRunner and JUnit Rules
5 androidTestCompile 'com.android.support.test:runner:1.0.1'
6 androidTestCompile 'com.android.support.test:rules:1.0.1'
7
8 // espresso support
9 androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
10 exclude group: 'com.android.support', module: 'support-annotations'
11 })
12 androidTestCompile 'com.android.support.test.espresso:espresso-contrib:3.0.1'
13
14 // for intent mocking
15 androidTestCompile 'com.android.support.test.espresso:espresso-intents:3.0.1'
16
17 // for network testing to track idle state
18 androidTestCompile 'com.android.support.test.espresso.idling:idling-concurrent:3.0.1'
19 androidTestCompile 'com.android.support.test.espresso:espresso-idling-resource:3.0.1'
20
21 // other dependencies
22}
1testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
Complete build.gradle
(app) file:
1apply plugin: 'com.android.application'
2
3android {
4 compileSdkVersion 26
5 buildToolsVersion "26.0.1"
6
7 defaultConfig {
8 applicationId "com.pavneet_singh.espressotestingdemo"
9 minSdkVersion 15
10 targetSdkVersion 26
11 versionCode 1
12 versionName "1.0"
13 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 }
15
16 buildTypes {
17 release {
18 minifyEnabled false
19 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 }
21 }
22}
23dependencies {
24 //as mentioned above
25}
The values for library version can differ in your project due to future updates and the rest of the configuration values are project dependent.
The default animations can cause issues during the Espresso testing process, so it is recommended to turn-off the animation on the device and emulator before testing.
Open Settings
Select Developer Options (if not activated, then click several times on build version/number in About Device Settings)
Disable:
Window animation scale
Transition animation scale
I hope that testing will now help you to be a stellar programmer, you can share your love by giving this guide a thumbs up.