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

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

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.

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.

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:

gradlew instruction-to-execute
./gradlew instruction-to-execute
gradlew assembleDebug

gradlew installfreeGoogleDebug

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.

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:

$ ruby --version
gem install bundler
source "https://rubygems.org"

gem "fastlane"
bundle update

Creating a Fastfile

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

fastlane init

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.

Executing a lane

In the command line where you installed Fastlane, type:

bundle exec fastlane test

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.

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

<!-- 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"/>
<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.

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")
  }
}
bundle exec fastlane screengrab init
# 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)
desc "Screen Grab tests"
lane :screenshot_main_screen do
  gradle(task: "clean assembleDebug assembleAndroidTest")
  screengrab
end  
# 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"
bundle exec fastlane screenshot_main_screen

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.

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.

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
firebase login

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

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.

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
bundle exec fastlane beta

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.

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.

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.

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')

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

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.

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.

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.

bundle exec fastlane deploy

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?

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.
© 2024 Kodeco Inc.

You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a Kodeco Personal Plan.

Unlock now