How to create parametrized test cases in JUnit 4 and Kotlin for Android?
Following this amazing tutorial, we can implement it in Kotlin language in this way:
First of all convert the EmailIdUtility
class into Kotlin:
object EmailIdUtility {
fun isValid(email: String): Boolean {
val regex =
"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$"
val pattern = Pattern.compile(regex)
val m = pattern.matcher(email)
return m.matches()
}
}
Then convert the EmailIdValidatorTest
into Kotlin
@RunWith(value = Parameterized::class)
class EmailIdValidatorTest(
private val email: String,
private val expected: Boolean)
{
@Test
fun testIsValidEmailId() {
val actual = EmailIdUtility.isValid(email)
assertEquals(expected, actual)
}
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{index}: isValid({0})={1}")
fun data(): Iterable<Array<Any>> {
return arrayListOf(
arrayOf("[email protected]", true),
arrayOf("[email protected]", true),
arrayOf("[email protected]", true),
arrayOf("mary@testdomaindotcom", false),
arrayOf("mary-smith@testdomain", false),
arrayOf("testdomain.com", false)
).toList()
}
}
}
Remember to add
@JvmStatic
in thedata()
method, otherwise you will get the error: java.lang.Exception: No public static parameters method on class com.example.testapp.dev.EmailIdValidatorTest
EASIER WAY
If you can use another library (working in Android too) I suggest you to add JUnitParams to your test dependencies, in Android it could be:
testImplementation "pl.pragmatists:JUnitParams:1.1.1"
Then you could convert the above class in this way:
@RunWith(JUnitParamsRunner::class)
class EmailIdValidatorTest {
@Test
@Parameters(value = [
"[email protected], true",
"[email protected], true",
"[email protected], true",
"mary@testdomaindotcom, false",
"mary-smith@testdomain, false",
"testdomain.com, false"
])
fun testIsValidEmailId(email: String, expected: Boolean) {
val actual = EmailIdUtility.isValid(email)
assertEquals(expected, actual)
}
}
which for me is a lot easier than the JUnit
way.
For more examples on how to use JUnitParams you can check the link.
With JUnit 5 this is a lot easier but currently JUnit 5 is not supported for Android tests if you don't use Android-JUnit 5 too.
I know you're using JUnit 4, but if you consider to update to JUnit 5, you can use @TestFactory
annotation to execute parametrized unit test.
In your case that would result in a test class like this:
import org.junit.jupiter.api.DynamicTest
import org.junit.jupiter.api.TestFactory
internal class EmailIdValidatorTest {
@TestFactory
fun `test email id validity`() =
listOf(
"[email protected]" to true,
"[email protected]" to true,
"[email protected]" to true,
"mary@testdomaindotcom" to false,
"mary-smith@testdomain" to false,
"testdomain.com" to false
).map {
dynamicTest("email ${it.first} should be ${if (it.second) "valid" else "not valid" }") {
val actual = EmailIdUtility.isValid(it.first)
assertEquals(expected, actual)
}
}
}