After the implementation of a couple of projects for Android, it became clear that, despite their small size and apparent simplicity, we cannot do without automated builds and testing. The desire to get the following features was born:
- unit testing,
- integration testing
- interface testing,
- testing these types of tests on different versions of Android and device configurations,
- sending by email in case of a broken build;
- the automatic assembly of releases does not hurt either.
Almost immediately came
across the testdroid.com site, which offers almost everything the same, and even more (testing on real devices), but, of course, for denyuzhku.
In this regard, after two weeks of research, the choice was made on a bundle on Jenkins + build scripts on Ant (under Windows).
So, how to raise it all ?!
Prerequisites:
- Suppose we have already created, in some way, the project MyProject. And to it is a project for testing MyProjectTest (there is at least one test in the test project). And let there be a folder with projects in the directory d: \ projects \ MyProject \ trunk \. My project sources are stored under SVN.
- This manual is written using Android SDK version 16 (http://developer.android.com/sdk/index.html). If you have a different version, you may have to do something differently.
Step 1. Setting environment variables (optional, but easier).
Create the
ANDROID_HOME variable in the system environment (System variables) and specify in its value the path to the Android SDK folder. I have this way D: \ android \ android-sdk-windows.
We also add the value
;% ANDROID_HOME% \ platform-tools to the Path variable.
')
Step 2. Install Ant
Download the zip-archive from http://ant.apache.org/bindownload.cgi and unpack it into some folder (for example d: \ server \ android \ ant). The ant \ bin folder also needs to be added to the system environment variable Path.
Step 3. Preparing a build script for ant.
Google in the Android SDK has the ability to generate ant-scripts for building projects. To do this, you need to execute the following commands in the project's trunk folder:
- To create a build script for the main project:
android update project -p MyProject
- To create a build script for a test project:
- android update test-project -m .. \ MyProject -p MyProjectTest
Options for Android SDK <14 version can be viewed
here .
Step 4. Check the project build (optional again).
- Go to the trunk \ MyProject \ folder and run the command:
- ant clean debug
at the end of execution something should be written
- BUILD SUCCESSFUL
- Total time: 5 seconds
This means that the project was successfully assembled.
- Run the Android emulator and in the folder trunk \ MyProjectTest run
- ant all clean emma debug install test
The build will last a little longer, in my case it was 35 seconds. In the process, the debug builds of MyProject and MyProjectTest will be assembled, installed on the running emulator, and the tests run.
Step 5. Installing Jenkins.
Go to http://jenkins-ci.org/, there are links to distributions on the right, download and install. By default, it is installed and provides the web interface at http://127.0.0.1:8080/.
There is a small problem. By default, the Jenkins service starts from under the System user account, which makes it impossible for the plug-in driver to create emulators in the home folder of the account. The user needs to change either to your account, or create a special account for Jenkins.
If someone suddenly does not know, you need to go to Computer Management (the easiest way: Start> Computer (right click)> Manage), then select Services and Applications> Services, find the Jenkins> Properties> LogOn tab. After changing the account service must be restarted.
Step 6. Configure Jenkins.
So, zahoidm at http://127.0.0.1:8080/, choose
Manage Jenkins, then choose
Manage Plugins . Click on the
Available Plugins tab. If it's empty here, wait a while, Jenkins just hasn't loaded them yet.
We will need the following:
- Jenkins Emma plugin
- Android Emulator Plugin
- Hudson Port Allocator Plug-in
- ant
Perhaps some of them you have already been installed initially.
In my case, I also needed to install the Subversion Plugin, since my project was in SVN. If your project is under another SCM, do not forget to install a plugin for it.
Now, click the “
Install without restart ” button at the bottom, in the process you can put a checkmark
"Restart Jenkins when the machine is restarted and the plugins are working.
Next, go to
Manage Jenkins> Configure System . Here
- In the Android section, you need to register the Android SDK root (as already mentioned above, in our case it is D: \ android \ android-sdk-windows)
- To send an email if a build breaks, it is also worth completing the E-mail Notification section.
Now create a task for Jenkins. On the main page, click
New Job , enter the name, the type of the job, select
Build a free-style software project .
Here it is necessary to fill in the following sections:
- Source Code Management - choose the type of your version control system and enter the necessary parameters. Attention! It is necessary that only the trunk folder be pulled out of the repository, otherwise you will need to correct all the paths that will be further in the settings for the Jenkins task.
- Build Triggers - choose Poll SCM and write there * * * * *. This will mean that Jenkns will check the repository once a minute and, if there are new commits, run the build. For assembly every 5 minutes you can specify * / 5 * * * *.
- Build Environment - Better tick Assign unique TCP ports to avoid collisions.
- Run an Android emulator during build . Fill emulator parameters, for example
- Android OS Version: 2.1 (Make sure that this version is downloaded from your SDK)
- Screen density: 240
- Screen resolution: WVGA
- Device locale: en_US
- SD card size: 16M
- Build section, add Invoke Ant, in here
- Target: all clean emma debug install test
- Build File: QuickMeetingTest \ build.xml
- Properties: sdk.dir = D: \\ android \\ android-sdk-windows (exactly, with double slashes)
- Post-build Actions
- Archive the artifacts: ** / * test-TEST.xml
- Publish JUnit test result report: ** / * test-TEST.xml
- Record Emma coverage report: ** / coverage.xml
- Trackpoint files ** / * test-TEST.xml
- E-mail Notification - customize to your liking.
Actually, with the setting of Jenkins almost finished, but do not rush, yet everything is not ready.
There are two problems.
Problem 1.
Standard InstrumentationTestRunner does not generate xml with test results. Therefore, MyProjectTest need a little twist.
- Go to http://code.google.com/p/the-missing-android-xml-junit-test-runner/ Download polidea_test_runner_1.1.jar from there, put it in trunk \ MyProjectTest \ libs and add Java Build Path \ Libraries in the project properties.
- In AndroidManifest.xml, we change <instrumetation> so that it looks like this:
- <instrumentation
- android: name = "pl.polidea.instrumentation.PolideaInstrumentationTestRunner"
- android: targetPackage = "com.example.MyProject" />
- Add a line in the project.properties file
- test.runner = pl.polidea.instrumentation.PolideaInstrumentationTestRunner
- And in line
- <! - version-tag: 1 ->
change 1 to custom (it is necessary that your changes in this vayle are not overwritten during the next android update).
Problem 2.
The xml file with the results of the test run and the file with the results of the verification of coverage is generated on the device. They need to get out of there to Jenkins picked up.
The main ant script, which actually builds the project is in $ {sdk.dir} /tools/ant/build.xml and is imported into the project build script
- <import file = "$ {sdk.dir} /tools/ant/build.xml" />
- Go to $ {sdk.dir} /tools/ant/build.xml, take the whole <target name = "test" ../> section from there and paste it into our build.xml in the test project before the above import of the main script.
This overrides the challenge call test and, when we modify it, our changes will work.
- In <target name = "test" ../> in our build.xml we are looking
- <html outfile = "coverage / coverage.html" />
and add next
- <xml outfile = "coverage / coverage.xml" />
- And at the end, before </ target> we insert the code to pull the test results from the emulator:
- <mkdir dir = "$ {basedir} / junit-results" />
- <exec executable = "$ {adb}" failonerror = "true" dir = "$ {basedir} / junit-results" >
- <arg line = "$ {adb.device.arg}" />
- <arg value = "pull" />
- <arg value = "/data/data/${tested.manifest.package}/files/" />
- </ exec >
Step 7. Adding UI tests.
For this there is a handy tool
Robotium . You can
get here
code.google.com/p/robotium .
Setup:
- Download robotium-solo-3.1.jar (currently the latest version), put it in trunk \ MyProjectTest \ libs.
- Add in project properties in Java Build Path \ Libraries
- Create a test class and inherit it from ActivityInstrumentationTestCase2 <MyActivity>, in the constructor there should be a call of the form
- super ( "com.example.myproject" , MyActivity. class ) ;
where “com.example.myproject” is the package of the project under test, MyActivity is the Activity under test. - Add lines to class
- private solo solo ;
- @Override
- public void setUp ( ) throws Exception {
- solo = new Solo ( getInstrumentation ( ) , getActivity ( ) ) ;
- }
- @Override
- public void tearDown ( ) throws Exception {
- solo. finishOpenedActivities ( ) ;
- }
and then you can write tests like
- public void testPreferenceIsSaved ( ) throws Exception {
- solo. sendKey ( Solo. MENU ) ;
- solo. clickOnText ( "More" ) ;
- solo. clickOnText ( "Preferences" ) ;
- solo. clickOnText ( "Edit File Extensions" ) ;
- Assert . assertTrue ( solo. searchText ( "rtf" ) ) ;
- solo. clickOnText ( "txt" ) ;
- solo. clearEditText ( 2 ) ;
- solo. enterText ( 2 , "robotium" ) ;
- solo. clickOnButton ( "Save" ) ;
- solo. goBack ( ) ;
- solo. clickOnText ( "Edit File Extensions" ) ;
- Assert . assertTrue ( solo. searchText ( "application / robotium" ) ) ;
- }
Details can be found here
code.google.com/p/robotium/w/list .
Step 8. Test on multiple emulators.
- When creating a job for Jenkins, you can select the job type Build multi-configuration project.
- In the Configuration Matrix section, create axes for each changing parameter, for example, the resolution and version of the android, and substitute it into the Run emulator with properties settings in the form of $ {resolution}. Look at the pictures on the above link, everything will become clear.
- The remaining parameters are specified as in the usual task.
Details
here .
Step 9. Preparing the release assembly.
Release build is easier than running tests.
- Create a task in Jenkins MyProjectRelease (type Build a free-style software project).
- As in step 6, specify where to pull the source.
- Create an Invoke Ant Build Step with parameters:
- Targets:
- release
- Build File:
- MyProject \ build.xml
- Properties:
- sdk.dir = D: \\ android \\ android-sdk-windows
- key.store = .. \\ myproject.keystore (relative path to the key storage file, I put the key in the trunk \)
- key.alias = <alias>
- key.store.password = <pass>
- key.alias.password = <pass>
- You can also configure Archive the artifacts from Files to archive = ** \ * - release.apk (if you want to keep all releases carefully and be able to download them through the Jenkins web interface).
- To obfuscate a release using ProGuard, you only need to add the line proguard.config = proguard.cfg, where in the project.properties (or in the properties of the InvokeAnt step of the task in Jenkins)
- proguard.config - the name of the variable in which the name of the file with the settings for ProGuard should be located,
- and the proguard.cfg file is automatically created by Eclipse when the project is created.
Thank you for your attention, I hope this post will help make your programs a little better.
Also a special thank you for the support to the management of the
Artezio company, which supported my initiative and took the time to do this research.