Getting started with Android testing — Part 2

Getting Started With Android Testing — Part 2

Saurabh Vashisht
The Startup
4 min readSep 6, 2020

--

In the previous article, we discussed how to set up instrumented tests for our Android app. In this tutorial we will add some new functionality to our app and write unit tests to test that behavior.

You can check out the previous post here

You can check out the beginning code for this article here

In our app we have a simple TextView which shows a string present in app reources.
We will now add a new TextView that will show the number of words shown in the above mentioned simple TextView.

Lets add another TextView to our MainActivity’s layout file.

<TextView
android:id="@+id/text_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/string_to_be_tested"
/>
<!--Add new textView here-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/word_count"
/>

Now we will add some code to count the number of words in text_container.

Create a new class StringUtil that will contain the logic of our word counting algorithm.

package com.sample.androidtesting

class StringUtil {
companion object {
fun countNoOfWords(text: CharSequence?): Int {
val pattern = "\\s".toPattern()
//If text is null or empty/contains only white space characters, //return 0
if (text == null || text.trim().isEmpty())
return 0
var noOfWords = 0
//Split text using split() function and count the segments that //are not empty.
for (word in text.split(pattern.toRegex())) {
if (word.isNotEmpty()) {
noOfWords += 1
}
}
return noOfWords
}
}
}

You can find the code for this class here.

Now we need to call this function from our MainActivity with text shown in text_container as a parameter.

Our MainActivity will look like this

package com.sample.androidtesting

import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
private val textContent by lazy<TextView> { findViewById(R.id.text_container) }
private val wordCount by lazy<TextView> { findViewById(R.id.word_count) }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val text = textContent.text
wordCount.text = StringUtil.countNoOfWords(text).toString()
}


}

Code for MainActivity can be found here.

Now we want to add unit tests to test countNoOfWords() function. Think of all the possible inputs that this function might receive from MainActivity. We need to make sure that the result returned by this function in all these test cases is as per the defined behavior i.e. “Return the number of words in text supplied as function parameter”.

Unit tests can be run locally and do not require physical device or emulators so you can write as much test cases as you need to.

To add unit tests we need to create a new class in the test folder. In android studio find the test folder here

Create new class in test folder.

Since we are testing StringUtil class lets name our class StringutilUnitTest.

Now we need to add our testing code.

class StringUtilUnitTest{//Test function with null input
@Test
fun checkCountOfWordsForNullString(){

}
//Test function with empty string input
@Test
fun checkCountOfWordsForEmptyString(){

}
//Test function with string which contains only white space
@Test
fun checkCountOfWordsForStringWithWhiteSpaces(){

}
//Test function with a single word and lots of white spaces
@Test
fun checkCountOfWordsForStringWithWhiteSpacesAndSingleWord(){

}
//Test function with string that contains 4 words
@Test
fun checkCountOfWordsForString_with4words(){

}
}

Note: I have added test cases for all the use cases I could think of. But this is not an exhaustive list. There can be other use cases too.

Let’s examine each test function separately and add code that will perform testing.

//Test function with null input
@Test
fun checkCountOfWordsForNullString(){
val stringTobeTested: String? = null
assertThat(StringUtil.countNoOfWords(stringTobeTested), `is`(0))
}

In this method we will call countNoOfWords() with null input. assertThat Asserts that code (StringUtil.countNoOfWords(stringTobeTested)) satisfies the condition specified by matcher code (`is`(0)).

//Test function with empty string input
@Test
fun checkCountOfWordsForEmptyString(){
val stringTobeTested = ""
assertThat(StringUtil.countNoOfWords(stringTobeTested), `is`(0))
}

In this test case, we have called countNoOfWords() with and empty stirng and we expect it to return 0 as result.

//Test function with string which contains only white space
@Test
fun checkCountOfWordsForStringWithWhiteSpaces(){
val stringTobeTested = " "
assertThat(StringUtil.countNoOfWords(stringTobeTested), `is`(0))
}

In this case we have called countNoOfWords() a string that only contains a white space and we expect our function to return 0 as result.

//Test function with a single word and lots of white spaces
@Test
fun checkCountOfWordsForStringWithWhiteSpacesAndSingleWord(){
val stringTobeTested = " Buyakasha "
assertThat(StringUtil.countNoOfWords(stringTobeTested), `is`(1))
}

In this case we have countNoOfWords() with a String that contains a single word and white spaces. We expect our function to return 1 as result.

//Test function with string that contains 4 words
@Test
fun checkCountOfWordsForString_with4words(){
val stringTobeTested = " Buyakasha wazza my amigos"
assertThat(StringUtil.countNoOfWords(stringTobeTested), `is`(4))
}

In this case we have called countNoOfWords() with a string and expect it to return 4 as result.

That’s it. We can now run our tests and all tests should pass.
As an exercise you can add test cases with input strings that contain punctuation marks. (They will fail).

For completion, I have also added instrumented test for our new TextView. You can check out the new instrumented test here.

You can find the complete code for this article here

--

--