How MVVM helped us run A/B tests quicker

Dhruv Taneja
Practo Engineering
Published in
5 min readOct 9, 2018

One of the quickest ways to test your app designs with the least amount of conclusive data is by running A/B tests. At the time when people want to be prudent and factually correct at the same, these tests can turn out to be the go-to thing. For those it is new, A/B test is a test where you put out two(or more) variants of your product, and analyse over time which variant is the winner.

The main idea for these tests is to build fast and fail fast. With our Practo mobile apps, we always aim to thrive with a data driven approach to optimise user solutions and these tests are the core of this approach now. We use Firebase for our A/B tests for both Android and iOS.

What did we need an A/B test for?

Before starting the experiment, the Practo app had four tabs —

  1. Home tab — The home for all the transactions
  2. Todo tab — List of all actionables and “todos” for the user
  3. Read tab — A place to read about health queries and health articles
  4. Profile tab — Everything about the user

Since the launch of Todo cards, we have a lot of faith in the product and the data has been equally corroborating. So we wanted to offer it to the users right on the first screen, like this —

Home without todo cards(left) and Home with todo cards(right)

We had an assumption that putting todo cards on home can give over the top success for the product, and equally happy users. So we decided to run an A/B test to concretise the decision.

How MVVM actually helped

As mentioned above, the main idea of A/B tests is to build fast and fail fast. Which means put the code there fast, fix the bugs fast, and make sure the features don’t break in any of the variants. For a fair test, you would not want any disparity of your feature support between your release and patch cycles.

For the brevity of this post, I will not try to explain some of the best practices that should be followed for writing MVVM, but I will advocate how it can accelerate both business and development.

For one of the variants, todo cards is a separate tab on our home screen. So we have a fragment, and a viewmodel for the todo tab on home, i.e., TodoHomeViewModel. The fragment is nothing but a container for a recycler view sugar coated with some cool UI. And the responsibility of the view model is to create a list of todo cards that the fragment can display. The viewmodel has a bunch of observables and livedata for databinding, and recycler adapter’s data. But the main sorcery happens within these functions -

The fragment subscribes to the Maybe returned by the viewmodel, and gets the todo cards from the server. The viewmodel then creates different viewmodels for different cards. The observable list is updated with these viewmodels. And the list is observed to spit the cards in the recyclerview. Everything is working. Unit tests are running. Life is good!

For convenience, the AppHomeViewModel(the viewmodel for home) is also structured in a similar way. There’s an observable list being observed by the app home fragment, and functions that put data into that list.

Now comes the second variant, where the todo cards are on the home tab and the todo fragment does not exist. So how can MVVM help here? With this implementation that we have here with a bunch of observables and a list being observed, putting the results at one place hardly appears to be a puzzle now. All we have to do now is to instantiate the TodoHomeViewModel in the AppHomeViewModel, make it fetch the cards from the server just the way todo fragment does, observe the response and append the cards to the list.

And the updated tests —

Everything is working. Unit tests are running. Life is good!

Most importantly, time taken to get the A/B experiment out on production = Time taken to instantiate the todo home viewmodel in the app home viewmodel + Time taken to observe the cards sent by the server + Time taken to append those cards to the list of segments. A big time saver for the business. A win-win for all.

And to put this all in picture —

Why MVVM

Well you can still live with copying and pasting the same code for two different variants of the app (I would like to argue against that though). Or put everything in huge methods and wrap everything in a lot of if’s and else’s and things would still work. But things can get, and will get complicated when you have more than 2 variants, or multiple tests running at the same time. The business logic will get lost in the bulk of control flow logic and code maintenance, scalability and debugging will go for a toss. And you will find yourself praying to stop any more variants or tests coming in your code. After adding a few more variants on top of that, it will start looking like jenga blocks about to fall.

MVVM framework helps in maintaining single responsibility principle and helps in writing easy communications between different components via observer objects, mediator objects or some other behaviour that suits the case.

To wrap things up, investing in MVVM gives us some cogent advantages:

  1. Zero code duplication — No need to rewrite blocks of business logic again and again.
  2. Separation of concern — Individual features, or view models have the responsibility of (only) their own experiments.
  3. Maintainability and scalability — The code will look a lot less daunting and more breathable. Adding more experiments will not take much time. (Remember: build fast, fail fast)
  4. Maintains testability — This is by far the favourite gains we have had from writing in MVVM involving multiple experiments. There are little to no changes in the unit test cases for each individual view models. Since, a lot of our experiments were UI-centric, our unit test suite remained almost the same. So along with building fast and failing fast, we could also maintain the sanctity of our code.

Writing or rewriting your code in MVVM might feel like a needless or a redundant task at first, but it really pays you in the future. It does not take much time getting used to, and the gains are surely worth it, to — Build fast, fail fast.

If you liked this article, please hit the 👏 button to support it. This will help other Medium users find it. Share this on Twitter to help out reach as many readers as possible.

--

--