I found this useful video on Android Testing and I thought to talk about it here. Suppose you want to create a fully mocked version of your application, despite the one you are doing for production. This is where productFlavors come in.

You can have different Hosts, Icons or Package Names deppending on different versions of the same app. Open your app/build.gradle file and insert the following:

android {
    ...

    productFlavors {
        mock {
            applicationIdSuffix ".mock"
            versionNameSuffix "-mock"
        }
        prod {
            applicationIdSuffix ".prod"
            versionNameSuffix "-prod"
        }
    }
}

We are creating two different flavors mock and prod, once you sync your gradle file you will see the following in your Build Variants

Build Variants




Now, let's try to use them!

I have created a simple code, just to give an idea how things will look like. We have a field were we write a name, and give this name to an API that will give you back a list of emails that matches the name you inserted. So the structure of your code looks like the following:

app/src
└── main
      ├── AndroidManifest.xml
      └── java
            └── it.linnal.androidflavor
                  ├── EmailApi.java
                  └── MainActivity.java

What EmailApi class does, is a POST request to a give URL (the url you'll use in production).
Now that we introduced the concept of productFlavor, let's make the modifications to use them.


Create mock and prod folders under src

app/src
├── main
├── mock
└── prod


Now copy the class EmailApi.java inside both of them and remove it from main. Things will still work as before.

app/src
└── main
│      ├── AndroidManifest.xml
│      └── java
│            └── it.linnal.androidflavor
│                 └── MainActivity.java
├── mock
│       └── java
│            └── it.linnal.androidflavor
│                 └── EmailApi.java
└── prod
     └── java
          └── it.linnal.androidflavor
                └── EmailApi.java


Now you can modify EmailApi.java under mock to return an hardcoded result. For example, return always the same email for whatever input you insert, so you do not need to call the real API anymore.


Depending on which environment you want your app to run, choose it under Build Variants.
* If you choose mock you will see that whatever you insert you will get back the same email.
* If you choose prod you will be calling the API.


Different Global Variables per Flavor

android {
    ...

    productFlavors {
        mock {
            applicationIdSuffix ".mock"
            versionNameSuffix "-mock"
            buildConfigField "String", "api_host", "http://localhost:3000"
        }
        prod {
            applicationIdSuffix ".prod"
            versionNameSuffix "-prod"
            buildConfigField "String", "api_host", "http://some_other_url"
        }
    }
}

You can access to api_host as following:

BuildConfig.api_host



Different Res Content per Flavor

If you want to reuse the same application, but with different colors and images, create the res folder under your flavors with the wanted modifications. Just the ones you want to change.

app/src
├── main
├── mock
│       └── res
│            └── values
│                 └── colors.xml
└── prod
     └── res
          └── values
                └── colors.xml