How to write less code in tests

cenci7
Mercadona Tech
Published in
3 min readOct 24, 2023

One year ago we started trying Maestro. It’s a game changer for the UI tests!

As our UI tests were a mess, we got encouraged to try it. The results for the first use case were impressive: we reduced from more than 260 lines to just 21, almost 92% less!

It’s well known that the fewer lines of code, the fewer the errors.

Photo by ahmad elsafty on Unsplash

To add more context to the article, I will focus on this use case: Our drivers have to input the center, their driver ID, the route and the expedition lane, and also the plate of the vehicle to log in to our Delivery App.

What we had before

We had some layers in our testing framework:

  • Espresso: Google’s framework for UI testing. Allows to write things like this:
onView(withId(R.id.etDriver)).perform(typeText("1007"))
  • Barista: Built on top of Espresso, it provides a simple API, removing most of the boilerplate of common Espresso tasks.
BaristaEditTextInteractions.writeTo(R.id.etDriver, "1007")
  • Custom functions: a bunch of Barista actions grouped to give them more semantics.
fun doLoginWithRouteAndPlate() {
selectCenter()
enterWithDriver(DRIVER_ID)
allowPermissionsIfNeeded(Manifest.permission.READ_PHONE_STATE)
enterWithRouteAndLane(ROUTE_WITH_NO_PLATE_ID, LANE_ID)
enterWithPlate(VEHICLE_PLATE)
}
  • A custom class to allow us write things like this and improve the readability. Big clap for my mate Edgar Miró, this was a huge achievement!
@E2eTest
class LoginE2eTest : BaseE2eTest() {

@Test
fun login() {
AppLaunched
.then(LoginScreen) {
doLoginWithRouteAndPlate()
}
.then(OrderListScreen) {
assertHasNavigatedToIt()
}
}
}

What we have now

appId: es.mercadona.our.delivery.app
---
- clearState
- launchApp

- assertVisible: "Buscar por número de centro"
- inputText: "4447"
- tapOn: "Colmena Valencia"

- inputText: "1007"
- tapOn: "Siguiente"

- inputText: "74476"
- tapOn: "Calle de expedición"
- inputText: "1"
- tapOn: "Siguiente"

- tapOn: "Matrícula"
- inputText: "4321BUM"

- assertVisible: "Ruta 74476 / Calle 1"

Comparison

Before:

  • Need some libraries.
  • A lot of lines of code.
  • Only we (the android engineers) had the knowledge of how to write tests.
  • Poor readability (remember that we have to create our custom class to make it more readable).

Now:

  • No libraries needed.
  • Very few lines of code.
  • The whole team is able to write a test.
  • Best readability by far.
  • Big Slack community where ask for help when needed and request new features.
  • It’s open source , and they make releases quite often.
  • We could share the same tests between Android and iOS if the UI is the same.

Conclusion

Even so, if I had to say one bad thing, it would be that they deprecated the mocking network feature. It allowed us to make our tests faster and more independent. Now, we must wait until our backend app is up locally and start our tests suite.
Although on the other hand, we found a workaround:

  • Launching our UI tests with the server response mocked with Mocks Server (and not via Maestro).
  • Keep the coverage between server and client implementing contract tests, but this is another article 😉

As always in life, we learn by doing, and we have our own tricks right now and you? Have you tried Maestro? Share your thoughts in the comments!

--

--