Open source: CI / CD and Avito test infrastructure for Android

We moved Avito for Android open source infrastructure: Gradle plugins, emulators and test libraries. Our code will be useful in automating CI / CD, and will also facilitate the writing and support of autotests.

In this review article, we will explain why we decided to make our work open, about the most significant libraries of the project and will orient where to go with emerging issues. We will analyze in detail individual libraries, Gradle plugins, and our development approaches in the following materials.



Who we are and what we do


We are working on the Android industry in the Speed ​​platform team. There are four of us:
Seryozha Boishtyan
Senior engineer
Twitter account


Dima Voronin
Lead engineer
Twitter account


Zhenya Krivobokov
Senior engineer
Twitter account


Daniil Popov
Senior engineer
Twitter account


We are responsible for delivering changes in all Avito Android applications to users faster. Our area of ​​responsibility includes:

  • Local work with the project: so that everything is quickly assembled and the IDE does not slow down.
  • CI pipeline: tests, all possible checks.
  • CD: tools for release engineers.

Why do we need open source


We wanted not just to mirror the code in an open repository on Github, but to do it for the benefit of ourselves and the engineering community. The main reasons to take the project to open source are five:

  • Get feedback.
  • Influencing industry standards.
  • Learn new things.
  • Affect third-party libraries.
  • Boost your personal brand.

Let's go over them briefly.

Get feedback and make code easier to reuse


We make tuning for Avito engineers, and our users need all solutions to just work. We lack the view from the developers who solve similar problems. It will be cool if they point out problems in the internal implementation and the convenience of connecting to our project.

We have already seen how porting code to Github highlighted the problems of reuse. When you understand that other companies can use this, you look at architecture differently. Reusing code is not an end in itself. But this external criterion says a lot about the quality of architecture and its flexibility.

Influencing industry standards


We have been developing infrastructure for mobile applications since 2017 and regularly talk about it at conferences and meetings:


In addition to the stories, we always wanted to share the code and give the opportunity to reuse it. Indeed, many Android developers face similar challenges:

  • How to write autotests so that they benefit.
  • How to run them in pull requests.
  • How to cheaper to maintain infrastructure.

There are no generally accepted and established solutions for these tasks - each company operates in its own way. We share our best practices so that in new projects developers do not have to collect bit by bit information on testing mobile applications and building CI / CD. I would like to have ready-made solutions for routine problems instead of writing my bike. And, even if no one uses the project code in its original form, developers will be able to spy on our approaches and improve their own libraries.

Learn by explaining to others


Just putting the code in open source is not enough. Practices, approaches, ways of finding problems and making decisions are important. Showing them, we check how our ideas and ready-made proposals work outside of Avito.

Affect third-party libraries and fix their problems faster


Imagine you are facing a problem in an Android or library and cannot find a workaround. You need help from the community or code authors. You asked a question on Stack Overflow, created a bug in Google IssueTracker, described everything in detail, but the problem does not reproduce. You are asked for a test case. All this takes extra time.

Open source helps you create a reproducible example faster. We have a test application that uses part of the infrastructure. His main task is dogfooding, that is, as early as possible to verify with a simple and isolated example that everything works. But this same application makes it easier to show bugs. When we give a reproducible example in a foreign library, its author is easier to understand what is the matter. This increases the chances that he will undertake improvements.

The popularity of an open source project also increases the likelihood that they will pay attention to you. Pointing out a problem in a library with a bunch of stars and users increases the pressure, it's harder to ignore. Obtaining such a result without open source is more difficult - your application must be super popular or you should know it personally.

PR and personal motivation


Last, but not least, is personal gain. Everybody benefits from the publicity of daily work. The company attracts attention due to a useful product, and we pump a personal brand as engineers and get additional motivation for work. You no longer need to look for time in the evenings for your own projects or commits in third-party open source libraries.

What was brought to open source


We put almost all of our Android and CI / CD testing infrastructure into the Github repository . To make it easier for other developers to navigate the project, all modules are grouped by purpose:




I’ll note a couple of the most significant libraries.

Test runner


This is a gradle plugin to run instrumentation tests. The closest analogue is Marathon , but ours is written only for Android.

Test runner:

  • Describes which tests to run. There is filtering by annotations, by packages, by the results of the last launch.
  • Describes which emulators to run tests on. Backs them up to Kubernetes or connects to local emulators.
  • Sets the conditions for restarting the tests.
  • Sends a final report with the results of the test run.

Results are stored in custom TMS (test management system), it is not in open source. We are working on the possibility of connecting another implementation.



Impact analysis


We have about 1600 instrumentation tests and 10K unit tests. We would like to run all the tests for any code change, but this is not possible - the run will take too much time.

A simple solution is to manually divide the tests into different sets, for example, smoke tests, fast, slow, and run only a part. But with this approach, there is always a chance to miss an error, because it is not clear which set of tests is optimal. The ideal solution is to understand which minimum set of tests will verify all changes. This is called test impact analysis .

We wrote a Gradle plugin that looks for changes in modules, parses tests and determines which ones to run.



The main modules and approaches are described in more detail in the project documentation .
Now she is not very good, and even not all is translated. We want to make the documentation easier to understand, and we need your help. Tell us what to finalize and correct in the text in our telegram chat .



How our libraries can be useful


Since the project has many components, its use depends on your needs. If you are solving a similar problem or just want to understand the technology - feel free to write to us in a telegram chat in Russian or in English . We will tell you what we know, try to help and show relevant examples.

You can ask anything:

  • How do you work with unstable tests?
  • Why so much code? He is useless.
  • Why is all the code in Gradle plugins, not Python scripts?

If you want to use a specific module, you can try it in a test application . Now it shows an example of using test runner.

Unfortunately, we still have few examples of reuse in other projects, so integration still may reveal unknown restrictions. Write to us if this happens, and we will see what needs to be finalized.

Conclusion


In the following articles we plan to talk about:

  • Our test runner.
  • Anatomy of the test - what happens from pressing the “Run” button in the IDE to get the result.
  • How we struggle with instability of tests and infrastructure.
  • Our approaches to writing infrastructure.
  • How we reduced the release time from month to week.

There are ideas on more general topics:

  • How to start writing tests.
  • Fundamentals of testing for beginners - about common approaches and technologies.

Tell us in the comments what you will be interested to know. So we will understand which text to write first.

All Articles