Android TDD Part 10— Robolectric

Evan Chen
2 min readAug 8, 2020

--

We already know running UI and Instrumented tests on devices are slow. There is another way to verify interaction with Android Framework. Robolectric is a framework that brings fast and reliable unit tests to Android. This means you can run your tests on JVM.

Using the previous register sample. This time, we use Robolectric to test it’s interacting with View.

  1. When register fail, should alert “Error”
  2. When register success, should open ResultActivity.

The production code of the register sample.

if (!isLoginIdOK) {
// Register fail
val builder = AlertDialog.Builder(this)
builder.setMessage(
"loginId at least 8 words and first letter should be alphabetized.")
.setTitle("Error")
builder.show()
}
else if (!isPwdOK) {
val builder = AlertDialog.Builder(this)
builder.setMessage(
"Password at least 8 words and first letter should be alphabetized.")
.setTitle("Error")
builder.show()
} else {
val intent = Intent(this, ResultActivity::class.java)
intent.putExtra("ID", loginId)
startActivity(intent)
}

Create tests to verify:

  1. Register fail ⇒ alert
  2. Register success ⇒ open StartActivity

Creating a Robolectric Test

Add the following to your build.gradle:

android{
testOptions.unitTests.includeAndroidResources = true
}
dependencies {
testImplementation "org.robolectric:robolectric:4.3"
}

Create MainActivityTest on your src/test folder. Add an annotation Robolectric test runner on MainActivityTest.

@RunWith(RobolectricTestRunner::class)
class MainActivityTest {
}

Initial MainActivity on setupActivity method.

private lateinit var activity: MainActivity@Before
fun setupActivity() {
MockitoAnnotations.initMocks(this)

activity = Robolectric.buildActivity(MainActivity::class.java).setup().get()
}

Use shadowActivity to test StartActivity

To verify startActivity, follow these steps:

Step 1. Create a shadowActivity.

Step 2. Type UserId and Password, then click the send button.

Step 3. Verify intent.

@Test
fun registerSuccessShouldDirectToResult() {
//Step 1. Create shadowActivity
val shadowActivity = Shadows.shadowOf(activity)
//Step 2. Type UserId and Password, then click send button.
val userId = "A123456789"
val userPassword = "a123456789"
activity.loginId.setText(userId)
activity.password.setText(userPassword)
activity.send.performClick()
//Step 3. Verify intent
val nextIntent = shadowActivity.nextStartedActivity
//To assert nextIntent's class should be ResultActivity
assertEquals(
nextIntent.component!!.className
,ResultActivity::class.java.name)
//To assert nextIntent's size is 1
assertEquals(1, nextIntent.extras!!.size())
//To assert nextIntent's extra include ID
assertEquals(userId, nextIntent.extras!!.getString("ID"))
}

Use ShadowAlertDialog.getLatestDialog() to verify is Dialog shown.

@Test
fun registerFailShouldAlert() {

//arrange
val userId = "A1234"
val userPassword = "a123456789"
activity.loginId.setText(userId)
activity.password.setText(userPassword)
//act
activity.send.performClick()
//assert
val dialog = ShadowAlertDialog.getLatestDialog()
assertNotNull(dialog)
assertTrue(dialog.isShowing)
}

Github:
https://github.com/evanchen76/AndroidTDD_RobolectricSample

Reference:
http://robolectric.org/

Next: Android TDD Part 11 — Use custom view to improve testability

--

--