Part2: Testing in Android
Here we will write our first test and dive into testing basics.
better to check part 1 before you start
First of all, start a new empty project in the Android studio
and navigate to build.gradle
app-level
we need to add a new dependency 📲testImplementation “com.google.truth:truth:1.1.3”
and will come to that later.
sync your project and grab your coffee ☕️.
Take a look at Java folder inside our root package
There are 3 folders
com
This is where our actual code (forget about it now)
com(androidTest)
This folder contains the tests that rely on Android components and that means they can run only on the android emulator in other words instrumental test
com(test)
This folder contains the tests that don’t rely on Android components they can run without an emulator in other words Unit Test
All of these folders are called source sets.
In build.gradle
app-level there are testImplementation
and androidTestImplementation
you might wonder what is the difference between them ?!
testImplementation
: Including library to only that specific source set com(test)
androidTestImplementation
: Including library only to that specific source set com(androidTest)
so when we added the truth library we used testImplementation
that make truth library accessible only in com(test)
source set.
because we need to access the library also in com(androidTest)
we will add another dependency using androidTestImplementation
this time.
androidTestImplementation “com.google.truth:truth:1.1.3”
Let’s try to test this registration form
we need to register the user to our database only if he entered all the above details in the correct way.
Do you remember TDD? check here if you don’t.
1st step in TDD
function signature.
we will start by creating a new RegistrationUtil
object in our com
source set to declare the function signature
object RegistrationUtil {
private val existingUsers = listOf<String>(
"Kazimi",
"Jone",
"Adam"
)
fun validateRegistrationInput(
userName: String,
password: String,
confirmedPassword: String
): Boolean {
return true
}
}
I declared another variable called existingUsers
to simulate our already registered users
2nd step in TDD
Creating the test
right-click inside the object block and choose generate
or ctrl + n for windows command + n for mac users
by default selection for the testing library is Junit5 we need to change it to Junit4
Click OK
Choose the package inside unitTest
folder, Click OK
You will find the android studio creating a new Kotlin class for you called RegistrationUtilTest
inside this class, our test cases will be placed.
Let’s think of how we going to validate our user input.
The input is not valid if
->The user name or password is empty.
->The user name is already taken.
->The confirmed password it’s not the same as the real password.
->The password contains less than 2 digits.
The input is valid if
->The user name not empty and not already exist and password not empty and confirmed password repeated correctly and password contained more than or equal 2 digit.
@Test
fun `if user name is empty return false`() {
}
if you find it a weird function don’t worry this function it’s working exactly like a normal function but the name of the function is quite interesting cause we should have a readable and meaningful function name. and Kotlin provide us with this amazing ability to naming test function as we want
just use `` and you can name it anything.
class RegistrationUtilTest {
@Test
fun `if user name is empty return false`() {
val result = RegistrationUtil.validateRegistrationInput(
"",
password = "1234",
confirmedPassword = "1234"
)
assertThat(result).isFalse()
}
}
assertThat()
is checking if the result
variable is equal false by calling .isFalse()
easy !! right
the variable result
will be True because in validateRegistrationInput
we return True no matter what. just for now because we didn’t implement the real code yet.
if you run the test it will fail
make sure to import
assertThat()
from truth library
Here’s all test cases we talked about.
valid user name and correctly repeated password return true
@Test
fun `valid user name and correctly repeated password retrun true`() {
val result = RegistrationUtil.validateRegistrationInput(
"Ahmad",
password = "1234",
confirmedPassword = "1234"
)
assertThat(result).isTrue()
}
User name already exist return false
@Test
fun `user name already exist return false`() {
val result = RegistrationUtil.validateRegistrationInput(
"Kazimi",
password = "1234",
confirmedPassword = "1234"
)
assertThat(result).isFalse()
}
Password is empty return false
@Test
fun `password is empty return false`() {
val result = RegistrationUtil.validateRegistrationInput(
"Ahmad",
password = "",
confirmedPassword = ""
)
assertThat(result).isFalse()
}
Password was repeated incorrectly return false
@Test
fun `password was repeated incorrectly return false`() {
val result = RegistrationUtil.validateRegistrationInput(
"Ahmad",
password = "Abcabc",
confirmedPassword = "123123"
)
assertThat(result).isFalse()
}
Password Contains less than 2 digit return false
@Test
fun `password contain less than 2 digit return false`() {
val result = RegistrationUtil.validateRegistrationInput(
"Ahmad",
password = "Abcabc1",
confirmedPassword = "Abcabc1"
)
assertThat(result).isFalse()
}
You can run all test once just by clicking on green run arrow right next to our test class name.
3nd step in TDD
implement code to make the test pass
fun validateRegistrationInput(
userName: String,
password: String,
confirmedPassword: String
): Boolean {
if (userName.isEmpty() || password.isEmpty())
return false
if (userName in existingUsers)
return false
if (password != confirmedPassword)
return false
if (password.count { it.isDigit() } < 2)
return false
return true
}
here’s validateRegistrationInput()
function after implementing or actual code.
Now just hit that run button and enjoy.
You will see that beautiful green check everywhere telling you your test are passed ✅
You can find the full source code here.
See you soon in part 3
Happy coding :)
Kazimi