Building Android Apps with Agility: Continuous Integration

http://www.androidcentral.com

In this post, I’m going to share my experience integrating an Android App I worked on with CircleCI. However it’s important to first establish what continuous integration is all about, and why it is important.

At the heart of the agile methodology is continuous software delivery. A typical iteration in the agile process comprises some planning, analysis, design, testing(TDD), implementation, some more tests, and of course, deployment. Usually we work on chunk of features known as the User Story. We follow through this process, from planning that feature to deploying it. This is one of the beauties of the agile process — we can deliver value fast, frequently, and at the early stages of development.

Automating the process of integrating changes to projects, as we work on features is gaining widespread acceptance especially with web-based projects. But, what about mobile apps? We do not view native mobile apps via browsers? right? Usually, we use emulators or our mobile phones to test our apps. Can we then achieve continuous integration with mobile apps development? The answer is Yes!

There are super useful tools for automating integration, and deployment. We need our Git project (hosted on Github, Bitbucket and the likes), and we need a CI server, such as Jenkins, Travis CI or Circle CI.

Here, we cover git updates with CircleCI.

Getting Started

Now that we’ve established the importance of continuous integration, let’s get started:

Let’s build a simple Android app named “Resume Manager” with the following very simple user story:

  • As a user, I want to click on “create resume” button to create a resume.

We should add some other stories or chores usually known as Technical User Stories. Here are some important ones that should be prioritised above the functional user stories.

  • Set up the app structure
  • Set up the testing framework and structure
  • Run a few mock tests to see if testing works well
  • Set up CircleCI

Setting up CircleCI

Since our focus for this article is on CircleCI, I will assume that you have set up the app and test structure. We will go ahead to set up our project on CircleCI and run our first Integration (which sometimes fail). Note that each Integration test you run is called a build. Each build has a number associated with it, which helps identify every progress made in the history of your app, and for every feature delivered, what success at that stage looked like.

Here’s how you set up your CircleCI

  • Visit circleci.com
  • Authorise CircleCI with your Github account
  • When you sign in, you see a list of your Github accounts or organisations your account is mapped with.
  • Choose an account in order to choose the repository you want to build. In this case the resume-manager repo. Then click on the “Build Project” button.
  • This is what the build screen looks like. Here, my first build was successful.

Is that all there is to it? Nope! When you take a look at the tabs below the success check. These tabs:

You will notice that there’s the Artifacts tab and the circle.yml. What does this even mean? Usually, you could configure a typical CircleCI to generate some APKs for you such as the debug APK for testing an integration that has just been made before merging pull requests to your master/clean branch. How do you configure this? Create a circle.yml file at the root of your project.

circle.yml — what’s that?

You would notice that CircleCI ran our first build for us. It did so by automatically inferring settings from our code, this time around Android. However, we really want CircleCI to see more than just our code, we want to reflect the same tests we run on our local systems. When contributors or co-programmers, push code, we want their integration to pass through the same test. We are taking our dependencies into consideration, the version of tools we use, among others. The circle.yml is how we tell CircleCI all of these.

Sections of the circle.yml

The circle.yml file has different sections fully explained here by the CircleCI team. I will examine just a few sections that we need here.

The general section: contains general information about the app, this is where we configure artifacts which are outputs to be collected for every build such as the APK files.

general:
artifacts:
- /home/ubuntu/resume-manager/app/build/outputs/apk/

Direct the outputs to your project name as configured on your circleci. In this case, the project’s name is resume-manager.

The machine section: is where we specify which virtual machine builds our tests.

machine:
environment:
ANDROID_HOME:
/usr/local/android-sdk-linux

Next, we specify the dependencies for the Android app in the dependencies section.

dependencies:
override:
- echo y | android update sdk --no-ui --all --filter tools,platform-tools,build-tools-23.1.1,android-23,extra-google-m2repository,extra-google-google_play_services,extra-android-m2repository

Ensure that the dependencies you specify match with the dependencies in your build.gradle file. Here’s an entire dependencies list compiled by JeroenMols

Check your dependencies with ./gradlew

- ANDROID_HOME=/usr/local/android-sdk-linux ./gradlew dependencies

Finally, let’s add one of the most vital sections, the test section.

test:
override:
- (./gradlew assemble):
timeout:
360

Your circle.yml should look like this:

general:
artifacts:
- /home/ubuntu/resume-manager/app/build/outputs/apk/

machine:
environment:
ANDROID_HOME:
/usr/local/android-sdk-linux

dependencies:
override:
- echo y | android update sdk --no-ui --all --filter tools,platform-tools,build-tools-23.1.1,android-23,extra-google-m2repository,extra-google-google_play_services,extra-android-m2repository
- ANDROID_HOME=/usr/local/android-sdk-linux ./gradlew dependencies

test:
override:
- (./gradlew assemble):
timeout:
360

Build Every feature Completed with CircleCI

Now that we’ve added circle.yml to the root of our project, we will proceed to create the user feature, write a unit and instrumentation test.

Next, we commit this feature and push to the remote branch. Watch CircleCI run this build. We can also check if the build passes directly from Github.

CircleCI is configured by default to only send notifications for failed builds. However, you may choose to change this.

For every build successfully completed, we can collect artifacts by clicking on the Artifacts tab as shown below:

Conclusion

Although CI is really popular with web apps, we can continuously integrate and test changes made as well, when building native mobile apps. This article has shown how this is done with Android using CircleCI. It’s easy to test if new features integrate easily into an existing app.

For example, when someone contributes to your open sourced Android project and raises a new pull request, you see the build for this new feature on CircleCI, collect the APKs right there, see the test results, before proceeding to accept or provide feedback on the pull request raised.

So now, congratulations! You have just created a pipeline for continuously integrating every piece of code pushed or pull requests raised for your android project.

If you liked this, click the💚 below so other people will see this here on Medium. Also, if you have any question or observation, use the comment section to share your thoughts/questions.