Chapters

Hide chapters

Android App Distribution

First Edition · Android 12 · Kotlin 1.5 · Android Studio Bumblebee

11. Automation Tools for Your Local Environment
Written by Evana Margain Puig

In the previous chapter, you learned about build flavors and how you can combine them with build types to create build variants. You also reviewed the process of creating build certificates and signing your app for release.

Those processes are crucial to publishing your app to the Google Play Store. The not-so-great news is that repeating them every time can be a tedious and a time-consuming task.

This chapter will teach you all about automation. You’ll learn how to automate your release process, so you don’t waste time and avoid errors in every release you make.

What is automation?

Before diving deeper into the topic of automation, you need to learn what it is. Far from a mobile-only concept, automation refers to any system that reduces human intervention and executes processes by itself.

If you take a closer look at the Android world, automation is everything that happens once the developer finishes coding and the app is ready to go to the next steps, including:

  • App Signing
  • Testing
  • Uploading to the store
  • Validating code

Think of any process you repeat over and over every time your team finishes a feature.

Why automate my process?

Teams often choose not to automate processes because they think it’s challenging or the tools might make mistakes that humans could avoid. The truth is that automating an Android app is an easy and safe process.

Here are some of the benefits of automating your app:

  • Time savings
  • Avoiding human errors
  • Detecting bugs sooner
  • Re-running tests often

Building the app via command line

Before integrating any automation tools, it’s important to know how to build your app from the command line. Understanding this process will give you some insight into what automation tools do under the hood.

Note: We are showing you how to run your terminal from Android Studio, but if you are experienced with using the command line you can use your favorite terminal as well.

Gradle Wrapper

The Gradle Wrapper is a command-line tool available to all projects you create with Android Studio. Usually, the terminal is at the bottom of Android Studio, with other windows like Logcat and Run. Take a look at the image below for reference:

If you can’t find it there, you can also navigate in the top bar to View ▸ Tool Windows ▸ Terminal or tap F12 on your keyboard.

All the commands you’ll use in the terminal start with ’gradlew’, which stands for Gradle Wrapper. It varies a little from one OS to another. In Windows, you use:

gradlew instruction-to-execute

While in Mac or Linux, it’s:

./gradlew instruction-to-execute

For your terminal test, you’ll build a debug apk. In the terminal, write:

gradlew assembleDebug

Press enter and then wait for the terminal to complete the process. It may take a couple of minutes, but you’ll see the progress in percentage at the top of the terminal. Once it finishes, use your file explorer app to navigate to PodPlay ▸ app ▸ build ▸ outputs ▸ apk. You’ll see three folders, one for each of the possible debug apps outputs:

Navigate to any of those folders. Inside the subfolder debug, you’ll see an apk. Now say you want to install the freeGoogleDebug version in your emulator. Make sure an emulator is running and type the following command in the terminal:

gradlew installfreeGoogleDebug

The app won’t automatically run as it does when you run it from the Run button on Android Studio, but you’ll see it available in the emulator.

You can do much more in the terminal. In fact, you can do almost everything Android Studio enables through the UI.

For more information on the topic of terminal commands, take a look at the Where to go from here? section at the end of the chapter.

Introduction to Fastlane

In this section, you’ll learn about Fastlane, one of the most popular automation tools out there. Fastlane is an open-source platform aimed at Android and iOS deployment. Although developers use it more on iOS than on Android, it’s still the most powerful tool out there.

Some of the most notable features of Fastlane are:

  1. Taking automated screenshots for the Play Store.
  2. Distribution to beta testers via Firebase App Distribution.
  3. Deployment to the Play Store.

Installing Fastlane

Before using Fastlane, you need to download and install it. The installation will vary depending on your OS.

MacOS or Linux

The most common way is to install it in macOS is through homebrew. Open a terminal and type the following command:

brew install fastlane

Windows

For this OS, there are several options. I’ll guide you through the easiest one:

  1. Navigate to rubyinstaller.org and download an installer for Ruby 2.5 or newer.

  2. Once you install it, confirm which Ruby version you have by running the following in a terminal:

$ ruby --version

Your output will be something like: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]

  1. Install Bundler by running the following command in the terminal:
gem install bundler
  1. In the root directory of your Android project, create a file named Gemfile. Add the following lines to it:
source "https://rubygems.org"

gem "fastlane"
  1. Save the file and go back to your terminal. Then run:
bundle update
  1. Add ./Gemfile and ./Gemfile.lock to your version control repository if you’re using it.

Note: This process may vary a lot depending on your OS. If you have any problems, refer to the Fastlane Documentation at https://docs.fastlane.tools/getting-started/android/setup/ for a more comprehensive explanation of the install process.

Creating a Fastfile

By now, hopefully, you’ve installed Fastlane without further trouble.

In your terminal, navigate to the root of the PodPlay project and run:

fastlane init

The terminal will display a lot of text and stop at certain points to ask you for information. Add the information as shown below:

  1. The package name: com.raywenderlich.podplay.
  2. A JSON secret file: Leave empty. Press enter.
  3. Download existing metadata and setup metadata management: y, indicating you do want to download that information. The metadata is the information you enter when uploading the app, such as the app name, version code and description. You can manually manage those, but as the purpose of this chapter is automation, you want Fastlane to do it for you.

Here are two screenshots of the terminal output in case you need to reference any of the information:

Once this finishes, in your file system, navigate to the root of the PodPlay project. You’ll see this command created a fastlane folder. If you navigate inside that folder, you’ll notice two files: Appfile and Fastfile.

Open Appfile from the project view of Android Studio. You’ll see it has two lines pre-filled with the information you added in the terminal above.

  1. json_key_file: Contains two open quotes because you just pressed enter to skip it.
  2. package_name: com.raywenderlich.podplay, the same as you added in the terminal.

Now open Fastfile. You’ll notice it’s a longer file than the previous one. This file contains the automation instructions. It may look a bit weird, but you’ll understand what each line is trying to do if you follow the information.

  • Lines 1-14: These are comments providing you with sources of information to edit the file.
  • Lines 16 and 18: Both of these lines specify that your platform is Android and signal the start of the automation instructions.

After that, you’ll see three blocks of instructions which start with desc, standing for description, and end with end. You’ll learn about each of these commands, using an example, in the next section.

Running tests

As mentioned throughout the book, tests are a fundamental part of delivering robust and successful apps. Running tests is an essential part of an automation pipeline.

The first block, shown in the Fastfile, runs tests. Take a look at the image below to see which block it is.

Take a closer look at each line of code:

  • 19: desc explains that this lane runs all the tests in the app and is purely for documentation.

  • 20: Now pay attention to the second line, named lane. The name of this lane is test followed by a keyword do.

  • 21: Then the body, which has only one line, instructs to run a gradle task named test, which of course runs the app tests. The body can contain more than one instruction.

  • 22: The end keyword signals the end of the lane’s instructions.

Executing a lane

In the command line where you installed Fastlane, type:

bundle exec fastlane test

The terminal will now show instructions related to testing your app, which will take up to a couple of minutes. Be aware that this is dependent on your app size. In the end, you’ll get a summary of the tests.

In the above case, the terminal executed tests successfully.

Using Screengrab

Another great feature of Fastlane is automatically taking screenshots using a tool named Screengrab. This is useful both for UI tests and for the screenshots required for the store listing.

Setting up Screengrab

Screengrab is a tool that doesn’t come bundled in the base Fastlane package, so you need to install it to use it.

In the same terminal where you ran your tests, run the following command to install Screengrab:

sudo gem install screengrab

It may take a while to run. Be patient because, in the long run, your automation pipeline will make your life way easier.

Unlike previous steps in this chapter, you need to add a line of code to your Android Studio project to take the screenshots. Go to the app level build.gradle. Locate a TODO for adding the screengrab dependency and replace it with:

androidTestImplementation "tools.fastlane:screengrab:2.0.0"
androidTestImplementation 'com.jraska:falcon:2.2.0'

Make a gradle sync as the IDE requests in the banner at the top. Then wait for the project to integrate screengrab.

Now navigate to the debug version of AndroidManifest.xml. Both manifests are the same, but you only want to enable permissions for screengrab on the debug version. Otherwise, someone may misuse the permissions in your production app.

At the bottom of the manifest file, you’ll find a TODO showing you where to put the following permissions:

<!-- Allows unlocking your device and activating its screen so UI tests can succeed -->
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>

<!-- Allows for storing and retrieving screenshots -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!-- Allows changing locales -->
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"
  tools:ignore="ProtectedPermissions"/>

You may notice the bottom permission has a tools:ignore directive. This is because you’re sure it’s safe since you’re only using it in a debug version of your app. You may need to add the tools to your top manifest tag like this:

<manifest
  ...
  xmlns:tools="http://schemas.android.com/tools"
  ...>

Using Screengrab for screenshot tests

Now that you have everything ready for Screengrab to work, you’ll create screenshot tests. If you’re new to the term, screenshot test refers to a test when the testing tools take screenshots and then compares them with older ones to ensure no unintended UI change occured.

Create a new Kotlin file in: PodPlay ▸ app ▸ java ▸ com.raywenderlich.podplay (androidTest) and name it AutomatedUITests.

Replace the boilerplate code with:

package com.raywenderlich.podplay

// 1
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.raywenderlich.podplay.ui.PodcastActivity
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import tools.fastlane.screengrab.Screengrab
import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy

// 2
@RunWith(AndroidJUnit4::class)
class AutomatedUITests {
  // 3
  @Before
  fun setUp() {
    ActivityScenario.launch(PodcastActivity::class.java)
    Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy())
  }
  // 4
  @Test
  fun captureScreen() {
    Thread.sleep(500)
    Screengrab.screenshot("podcast_activity")
  }
}

Inspect the code above to see what it’s doing in each part:

  1. Imports needed for the code to work.
  2. You add this annotation to tell the compiler this is a JUnit test class.
  3. A function that executes before the test. First, you tell it which Activity to launch and then which strategy to use.
  4. Finally, the test itself. You add a sleep of 500 milliseconds to wait for the screen to launch and then take the screenshot. The screenshot will save with the name podcast_activity.

That’s about it for the test.

Now initialize Screengrab in Fastlane. Go to your terminal and run:

bundle exec fastlane screengrab init

When this finishes running, you’ll notice a new file named Screengrabfile in the fastlane folder.

As you did with the other files, open this one with a text editor. Replace the contents with:

# 1
android_home('$PATH')

# 2
use_adb_root(true)

# 3
app_package_name('com.raywenderlich.podplay')

# 4
app_apk_path('app/build/outputs/apk/freeGoogle/debug/app-free-google-debug.apk')
tests_apk_path('app/build/outputs/apk/androidTest/freeGoogle/debug/app-free-google-debug-androidTest.apk')

# 5
locales(['en-US'])

# 6
clear_previous_screenshots(true)

In the code above, you:

  1. Use the environment variable PATH to set the directory for the Android SDK.
  2. Grant root privilege to ADB. This lets Screengrab store screenshots on the Android device.
  3. Set the app’s package name.
  4. Set the directories to find the app APK and the instrumentation test APK.
  5. Set the locale to en-US. This function takes an array of locales you can use to take screenshots of the app in different locations.
  6. Clear screenshots from previous executions of Screengrab.

Now you want Fastlane to run this test automatically. So, add a new block of code containing a lane to the fastfile.

Open your Fastfile located in Podplay ▸ Fastlane. Then, below the first test lane, create another lane with:

desc "Screen Grab tests"
lane :screenshot_main_screen do
  gradle(task: "clean assembleDebug assembleAndroidTest")
  screengrab
end  

Save your Fastfile and close it. Launch an emulator since the tests require a virtual device to use root privileges.

Also, make sure you have environment variables for Android tools set up correctly. You generally set them when installing Android Studio, but just in case, you can run the following in the terminal.

# Path to Android SDK
export ANDROID_HOME=$HOME/Library/Android/sdk

# Path to Android platform tools (adb, fastboot, etc)
export ANDROID_PLATFORM_TOOLS="$ANDROID_HOME/platform-tools"

# Path to Android tools (aapt, apksigner, zipalign, etc)
export ANDROID_TOOLS="$ANDROID_HOME/build-tools/29.0.3/"

# Add all to the path
export PATH="$PATH:$ANDROID_PLATFORM_TOOLS:$ANDROID_TOOLS"

Test the setup with:

bundle exec fastlane screenshot_main_screen

After the test executes, the screenshots appear in an HTML file and most likely open in your browser as shown below:

Congratulations! You’ve created screenshots for PodPlay with Screengrab and created a lane to execute them in one step! This is the beginning of your automation journey.

Deploying beta builds

Fastlane isn’t only about testing and building your app. It also lets you upload your app to the store. Once you have this setup, you can release as many versions of your app as you want with minimal intervention.

Once you finish an app release, the first thing you usually want to do is release it as a “Beta”. This is a common practice, and there are lots of users willing to participate in beta testing.

Fastlane supports many services that upload Beta versions of Android apps. But in this chapter, you’ll focus on uploading to Firebase. For an extended list of other providers, check the Fastlane documentation at https://docs.fastlane.tools/actions/#beta on beta testing actions.

Firebase App Distribution

You may have noticed when you opened your Fastfile, the provided code had an action to upload to Crashlytics. Android has replaced that tool with Firebase App Distribution.

Go to the Firebase Console at https://console.firebase.google.com/. It may ask you for credentials to your Google Account. Provide them, and you’ll log into the console. Click the first tile with the text Add project.

Then add the name of the project PodPlay and click Continue, like in the image below:

Don’t enable Google Analytics since you won’t need it for this project. Click Create Project. Wait until it finishes, and then click Continue again.

Now you’ll find yourself in the project dashboard.

Installing Firebase CLI

After creating the project in the Firebase Console, you’ll need to install Firebase CLI in your local environment. The instructions vary depending on your computer’s OS. You can read them at the Firebase CLI docs https://firebase.google.com/docs/cli. There are instructions that work for both cases. If you are on a MacOS of Linux machine you can install them in your project base path by runnning:

curl -sL https://firebase.tools | bash

The code above downloads a script from the given URL and runs it using bash.

After the installation is complete, log in to the Firebase console through your terminal by entering:

firebase login

It’ll open a browser window asking you to select your google account and then show you a success message like in the image below.

Installing the Fastlane plugin for Firebase Distribution

With that configured, you’re ready to install the Firebase Distribution plugin in Fastlane. Go back to your terminal and run:

bundle exec fastlane add_plugin firebase_app_distribution

The code above adds the plugin named firebase_app_distribution to Fastlane.

It’ll take a while to run and then ask you a question regarding modifying the GemFile. Type y and press Enter to continue.

Once you get a success message, go back to the Firebase console. Select PodPlay. On the main screen, select the little Android logo shown in the image below.

On the next screen, add PodPlay’s package by entering “com.raywenderlich.podplay” and PodPlay as the name. Click Register App.

After a couple of seconds, the screen will show step two and give you instructions to add a JSON file to the project in Android Studio. Follow those instructions and put the file in the project as shown in the image below:

Click Next to go to step three in the Firebase console, and you’ll see instructions to add the Firebase SDK to the project. Follow the steps there and run Gradle sync. Ensure the app is still working and unchanged after those steps.

Click Continue to console. Then you’ll land on the project page in the Firebase Console. On the menu to the left, click the settings button at the top and then choose Project Settings. Scroll to the bottom, and you’ll see an App ID. Save it somewhere handy because you’ll need it soon.

Distributing your beta build

In the menu at the left of the Firebase console, you’ll see an option named App Distribution. Click it. You’ll see the title App Distribution and a small dropdown with the name of the app you just added in the top banner.

Click Get Started, and you’ll see where your builds will appear after you upload them through Fastlane.

Before configuring Fastlane, you need to create a tester group that will receive the beta builds. There are three tabs on the screen. Currently, you’re in the one called Releases. Open Testers & Groups and click + Add group.

Add the group name PodPlay Beta Testers and click Save. Look at the image below for guidance.

Then add your email to the testers group so you can verify betas are being sent.

Go back to the PodPlay project in Android Studio and open Fastfile by opening the project view of the file explorer and navigating to PodPlay ▸ fastlane.

Previously in this chapter, you explored this file and noticed a lane for beta builds. Google originally intended it for Crashlytics but later deprecated it and replaced it with Firebase Distribution. So, change that lane in lines 30-37 of the Fastfile with:

desc "Submit a new Beta Build to Firebase App Distribution"
lane :beta do
  gradle(task: "clean assembleFreeGoogleDebug")

  firebase_app_distribution(
      app: "1:167913591674:android:6b252800fedbd5f7cbfcc3",
      groups: "podplay-beta-testers",
      release_notes: "First Podplay Beta!"
  )
end

In the code above, you generate a build using the assembleFreeGoogleDebug Gradle task and upload the same build with the release notes specified in release_notes.

Replace the app id with the one you copied previously from the console. Now execute this lane as you did with the others by running the following command in the terminal:

bundle exec fastlane beta

The console will output a lot of text. To verify that you successfully generated and uploaded your build, look at the following part:

Go back to the Firebase console, and you’ll see the apk appears there as in the image below:

That’s all you need to know about distributing betas. At this point, anyone added to the selected group will get an email and can download and test your app.

Deploying to production

Once you’re sure your app is mostly bug-free and has been beta-tested enough, you’ll want to get your app into production so everyone can enjoy it. To do this, once again, you’ll get help from Fastlane.

Before anything else, you’ll need an API key, which comes from a service account. A service account is like an identifier for your app to communicate with Google Cloud Services.

Note: If you haven’t done so already, you may need to create a developer account in the Google Play Console and pay the required $25 fee.

Go to the Google Play Console at https://play.google.com/console. In the left menu, scroll to the bottom. Under Setup, click API Access. You may see a screen prompting you to select a Google Cloud Project or create a new one. Select the option to create a new project and click the button at the bottom to continue. Once you see the screen below click Create new service account.

Creating a service account

Google Cloud Platform now manages a service account. This process will take place in that admin console. The Google Play Console will prompt you to go to Google Cloud and create the Service Account. Click the hyperlink to access the Google Cloud Platform, and your screen will look like the image below. Click + Create Service Account at the top.

On the form that appears, add only the Service account name by writing fastlane-podplay and clicking Create and continue. Then in the role, search for Service account and Service account user.

Click Continue. Leave the next section empty and click Done.

At this point, you’ve created a Service account but still need the API Key. Notice there’s a Key ID column, and the newly created service account has no keys. To the right of that row, you’ll see a menu called Actions with three vertical dots that you can click for more options. Click Manage Keys from the menu shown.

This redirects you to the keys screen, where you’ll add your key. Click ADD KEY. Then select Create New Key. In the options, select JSON and click Create. Then, it’ll prompt you to download the file to your computer.

Note: Please create your own keys. The one in the example project isn’t valid because of Google’s security policies.

Adding your service account to the Google Play Console

Go back to the Google Play Console, where the last thing you saw was the popup requiring the service account. Click Refresh service accounts as shown below.

Once you see your service account in the list, click Grant Access. Be careful when granting these kinds of permissions, as someone with unauthorized access who may get control of a service account could make harmful changes to your app. For testing, grant the Admin permission but remember you won’t do that in a production app.

Then click Invite user and confirm by clicking Send invite in the alert shown to finish the process.

Good job! With that set, Fastlane can now release the project for you.

Uploading your app to the Play Console

Finally, with all those validations, you can upload to the store. There are a few more points to take into consideration. Take a moment to go through each of them.

Which Build Variant do you want to upload to the store?

If you’ve followed the book, you may know that at this point, you have several Build Variants, and each generates a separate APK. To tell Fastlane which one you want to upload, navigate to your fastfile in the Project View of Android Studio under Podplay ▸ fastlane. In the last lane, change the code between do and end to:

gradle(task: "clean assembleFreeGoogleRelease")
upload_to_play_store(release_status: 'draft')

With the lines above, you tell Fastlane the app you want to upload is the ’Free Google Release’ build variant. You also indicate this is a draft app, so it doesn’t go live right away.

Validating the JSON key with Fastlane

As with many other services, you need to authenticate your Fastlane setup with the Google Play Console. You already generated the key in the previous step. All you need to do now is authenticate with it by running the following command at the root of your project through the terminal:

bundle exec fastlane run validate_play_store_json_key json_key:/path_where_you_downloaded_the_json_key

If you followed the steps in the previous section correctly, you’ll see a success message in the terminal, as follows:

Then you need to add the JSON file path to your project and Appfile. Rename the file you downloaded to podplay-playstore-key.json and copy it to the root of the Android project structure. Then open the Appfile, located in the project view of the Android Studio PodPlay project, under Podplay ▸ fastlane. Add the following line:

json_key_file("./podplay-playstore-key.json")

The Application ID has to be unique

At this point, if you tried to upload the app with the release lane in Fastlane by running bundle exec fastlane deploy, you would get an error saying you don’t have permissions. That’s because in the Google Play Store every app has to have a unique identifier.

The Application ID located in the app-level build.gradle file is currently defined as com.raywenderlich.podplay. Since there’s already an app with that same app id in the Google Play Store, you get a permission error. To fix this, change that identifier to something unique.

In my case, I changed it to com.raywenderlich.podplay.evana. So, change it in the second line of the Appfile and the app level build.gradle, by changing the applicationId.

Having the app listed in the Play Store

Before you can upload your app, you need to have it listed in the Play Store. That topic is too long to cover in this chapter. If you still haven’t done that, go back to Chapter 2 and look at the Creating your first app section.

In summary, go to the Google Play Console at https://play.google.com/console and click the top right button, Create app, and fill in the information with the requested data like in the images below.

Then the console will drop you on the app’s Dashboard page.

You need to upload the first version of your app manually, so the Google Play Store recognizes the app identifier, thus enabling Fastlane to do releases later.

In Android Studio, create a signed apk in the top menu Build ▸ Generate signed Bundle/APK…. You can find it by clicking the locate hyperlink at the bottom right.

Back in the Dashboard, click in the menu to the right in the option and click Create new release. Then, let google make the signing for you and drag the APK you just created into the square for it, as in the image above.

Finally, click Save, and you’re ready to go. There’s a button in the top left of the page to go back to All apps. Click it, and you’ll see a list of apps that includes PodPlay with its App ID at the bottom.

Now, Fastlane knows where to upload the app! Awesome job!

Running the lane

Open the Android Studio Project once again and go to the app module build.gradle. In the version code, increment it to 2 since you uploaded 1 manually.

If you correctly set up everything above, you can now run the lane in the terminal. Run the deploy command again:

bundle exec fastlane deploy

It’ll take a couple of minutes for the whole process to execute, but you’ll eventually see a success message in your terminal like the one below. You did it!

Go back to the Google Play Console and verify the apk you uploaded is there by clicking Releases Overview in the left menu. The upload will be there with the version number 2.

Great job! You now have an automated release pipeline! That’s quite an achievement. Many senior devs out there have never done this process.

Key points

  • Automation reduces the number of manual tasks you need to do after developing your app, and Fastlane is a great tool to help with mobile automation.
  • Automation tools use commands you can run by yourself in the Terminal.
  • Fastlane’s most important files are the Fastfile and the Appfile.
  • A Lane is a group of instructions that execute together in an automated command.
  • You can create lanes for testing, taking screenshots, releasing your betas and uploading to production.

Where to go from here?

In the next chapter, you’ll learn about Continuous Integration and Build Servers to go beyond your local environment.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.