{"id":3397,"date":"2018-03-28T13:02:59","date_gmt":"2018-03-28T11:02:59","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=3397"},"modified":"2023-06-08T17:45:27","modified_gmt":"2023-06-08T15:45:27","slug":"automated-unit-and-gui-testing-for-android-in-jenkins","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/automated-unit-and-gui-testing-for-android-in-jenkins\/","title":{"rendered":"Automated Unit- and GUI-Testing for Android in Jenkins"},"content":{"rendered":"<p style=\"text-align: left; margin-bottom: 10px;\"><em>Related articles:&nbsp;\u25ba<a href=\"https:\/\/wp.me\/p71Rzi-Tb\">Take Me Home &#8211; Project Overview<\/a>&nbsp; \u25ba<a href=\"https:\/\/wp.me\/p71Rzi-RU\">CI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image&nbsp;<\/a>\u25ba<a href=\"https:\/\/wp.me\/p71Rzi-RH\">Android SDK and emulator in Docker for testing<\/a>&nbsp; &nbsp;\u25ba<a href=\"https:\/\/wp.me\/p71Rzi-SQ\">Testing a MongoDB with NodeJS, Mocha and Mongoose<\/a><\/em><\/p>\n<hr style=\"padding-top: 1px;\">\n<p>In this article we would like to describe, how to write unit- and gui-tests for an Android-Application in Android Studio and how-to automat these tests on Jenkins.<\/p>\n<h2>Tools and frameworks<\/h2>\n<p>We used the following tools and frameworks to write and automate our tests:<\/p>\n<ul>\n<li>Android Studio<\/li>\n<li>JUnit<\/li>\n<li>Espresso<\/li>\n<li>Jenkins<\/li>\n<\/ul>\n<h2>Unit-Tests<\/h2>\n<p>To test the basic functionality of your app, the best way is to run a unit-test.<!--more--><\/p>\n<h3>Writing unit-tests with JUnit<\/h3>\n<p>We used JUnit to write unit-tests for our application. Tests with JUnit work in Android the same way as in all other Java-applications. In this article, we won\u00b4t go to deep into in the details of writing a unit-test in Junit, there are a lot of sources in the internet to consult.<\/p>\n<p>It is very important to place all the test-code in the \u201ctest\u201d-folder of your Android Studio-Project, <strong>not<\/strong> in the \u201candroidTest\u201d-folder (this folder is later required).<\/p>\n<h3>Executing unit-tests in Android Studio<\/h3>\n<p>You can start your Unit-Test in Android Studio by selecting the file with the test-code and clicking on the \u201cRun\u201d-button in the menu-bar. As an alternative you can also start all your tests or just one test by clicking on the little triangle next to the beginning of your test(s).<\/p>\n<h3>Automating unit-tests in Jenkins<\/h3>\n<p>After a successful local test, you can add your tests to your Jenkins-build to run them automatically with every build. To add it to a Jenkins-job you have to add the command \u201cgulp test\u201d to the pipeline-script, which defines your Jenkins job. Further information to automate your tests in Android you can find in the following block-article: <em><a href=\"https:\/\/wp.me\/p71Rzi-RH\">Android SDK and emulator in Docker for testing<\/a><\/em><\/p>\n<p>From now on, the tests will always be executed, when starting the Jenkins-job. You can see the result of the tests in the \u201ctestresults\u201d-tab in the job-overview in the Jenkins-AdminUI. Be aware of that the build will fail, if the tests aren\u00b4t executed successfully.<\/p>\n<h2>GUI-Tests<\/h2>\n<p>Gui-test are a bit more complicated than unit-tests. They test the functionality of the graphical-user interface of an Android-application, but not the exact design of the interface. So, if you want to test for example the exact position of a single element like a button, gui-tests are not the right way to do it. For our test we used the test-framework espresso, which especially build to write gui-tests in Android.<\/p>\n<h3>Writing gui-tests with Espresso<\/h3>\n<p>To use espresso in your application you first have to add the following imports to your \u201cbuild.gradle\u201d-file in the \u201cdependencies\u201d-tab:<\/p>\n<pre class=\"prettyprint lang-groovy\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'\nandroidTestCompile 'com.android.support.test:runner:1.0.1'<\/pre>\n<p>Then you have to add the next line to the \u201candroid.defaultConfig\u201d-tab:<\/p>\n<pre class=\"prettyprint lang-groovy\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"<\/pre>\n<p>Then you can start writing a gui-test. In this block, we don\u2019t want to go into detail, how to write such a test. Place your tests in the \u201candroidTest\u201d-folder of your project.<\/p>\n<p>So here are the basics:<\/p>\n<h4>Defining a test-rule<\/h4>\n<p>First you need to instance a @Rule to interact with the Android-activity you want to test. In this example we define a rule for the \u201cMainActivity\u201d:<\/p>\n<pre class=\"prettyprint lang-java\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">@Rule\npublic ActivityTestRule&lt;MainActivity&gt; activityRule = new ActivityTestRule&lt;&gt;(MainActivity.class);<\/pre>\n<p>To write a gui-test in espresso you can always follow the same way:<\/p>\n<h4>Select a gui-element<\/h4>\n<p>There are two ways to select an gui-element: <em>onView()<\/em> or <em>onData()<\/em>.<\/p>\n<h5>onView<\/h5>\n<p>This function uses ViewMatchers to select a gui-element. Examples for a <em>withId()<\/em> or <em>withText()<\/em>. But there is also the possibility to create more complex expressions with <em>allOf()<\/em> and <em>not()<\/em>.<\/p>\n<pre class=\"prettyprint lang-java\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">\/\/ element with specific id, here \u201cbuttonLogin\u201d\nonView(withId(R.id.buttonLogin));\n\n\/\/ element with specific text, in this case \u201clogout\u201d\nonView(withText(\"logout\"));\n\n\/\/ all views with a specific id (\u201cbuttonLogin\u201d), but without a specific text (logout)\nonView(allOf(withId(R.id. buttonLogin), not(withText(\"logout\"))))<\/pre>\n<h5>onData<\/h5>\n<p>This function you can use to get data from an gui-element like a ListView.<\/p>\n<pre class=\"prettyprint lang-java\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">\/\/ Looking for a specific string (\u201creading\u201d) in a ListView\nonData(allOf(is(instanceOf(String.class)), is(\"reading\")));<\/pre>\n<h5>Perform gui-action<\/h5>\n<p>After selecting an gui-element you can use the function <em>perform()<\/em> to do something on the selected gui-element. There several actions, you can do like <em>click()<\/em>, <em>doubleClick()<\/em>, <em>longClick()<\/em>. But also interactions like <em>scrollTo()<\/em> or <em>swipeLeft()<\/em> are possible. It is also possible to string several commands together, only separated by a \u201c,\u201d.<\/p>\n<pre class=\"prettyprint lang-java\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">\/\/ Click on an element with a specific id (\u201cbuttonLogin\u201d) several times\nonView(withId(R.id.buttonLogin)).perform(click(), doubleClick(), longClick());<\/pre>\n<p>You can also define complete-text input with <em>typeText(\u201cString\u201d)<\/em> and clear this text later <em>clearText()<\/em>.<\/p>\n<pre class=\"prettyprint lang-java\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">\/\/ enter text into an element with a specific id (\u201ctext_view\u201d)\nonView(withId(R.id.text_view)).perform(typeText(\"Hello World\"));<\/pre>\n<h4>Check the results<\/h4>\n<p>To verify if your activity works like expected, you can use the function <em>check()<\/em>.For this check you can use classic JUnit-Assertions, or you can use special ViewAssertions like matches or <em>isAbove()<\/em>.<\/p>\n<pre class=\"prettyprint lang-java\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"\">\/\/ checks if the element with the specific id (\u201cerrorMessage\u201d) is visible\nonView(withId(R.id.errorMessage)).check((matches(isDisplayed()));<\/pre>\n<p>All this information is just a small overview over gui-tests with espresso. You can find more information under the following link: <a href=\"https:\/\/developer.android.com\/training\/testing\/espresso\/index.html\">https:\/\/developer.android.com\/training\/testing\/espresso\/index.html<\/a><\/p>\n<h3>Executing gui-tests in Android Studio<\/h3>\n<p>In contrast to unit-tests with junit, it is a little bit more complicated to execute gui-test for android with espresso. Because gui-tests needs a gui you also need a running gui, on which you can execute your tests. There are two possibilities to achieve this: First you can use your smartphone to run the test. Or you can start an emulator in Android Studio to run the tests. To run a gui-test, you just have to start it by clicking on the \u201cRun\u201d-button in Android Studio. In the next window you could select a device (smartphone or emulator) to run your tests on it.<\/p>\n<h3>Automated gui-test in Jenkins<\/h3>\n<p>To run the gui-tests in the Jenkins-server automatically you have to ensure, that there is an emulator running a (virtual) gui, which you can test. To get this emulator running, we have a hole blog-post, because it is not that easy. Link to the block-post: <em><a href=\"https:\/\/wp.me\/p71Rzi-RH\">Android SDK and emulator in Docker for testing<\/a><\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Related articles:&nbsp;\u25baTake Me Home &#8211; Project Overview&nbsp; \u25baCI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image&nbsp;\u25baAndroid SDK and emulator in Docker for testing&nbsp; &nbsp;\u25baTesting a MongoDB with NodeJS, Mocha and Mongoose In this article we would like to describe, how to write unit- and gui-tests for an Android-Application in Android Studio [&hellip;]<\/p>\n","protected":false},"author":870,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[653,651,2],"tags":[147,148,78,149],"ppma_author":[744],"class_list":["post-3397","post","type-post","status-publish","format-standard","hentry","category-mobile-apps","category-system-designs","category-system-engineering","tag-android","tag-espresso","tag-jenkins","tag-testing"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":3329,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/android-sdk-and-emulator-in-docker-for-testing\/","url_meta":{"origin":3397,"position":0},"title":"Android SDK and emulator in Docker for testing","author":"Michael Laemmle","date":"28. March 2018","format":false,"excerpt":"Related articles:\u00a0\u25baTake Me Home - Project Overview\u00a0 \u25baCI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image\u00a0 \u25baAutomated Unit- and GUI-Testing for Android in Jenkins\u00a0 \u25baTesting a MongoDB with NodeJS, Mocha and Mongoose During our Android development project, we had to cope with several technological and organizational\u2026","rel":"","context":"In &quot;Mobile Apps&quot;","block_context":{"text":"Mobile Apps","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/interactive-media\/mobile-apps\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/Pipeline.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":3421,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/take-me-home-project-overview\/","url_meta":{"origin":3397,"position":1},"title":"Take Me Home &#8211; Project Overview","author":"cp054","date":"28. March 2018","format":false,"excerpt":"Related articles:\u00a0\u25baCI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image\u00a0\u25baDockerizing Android SDK and Emulator for testing\u00a0 \u25baAutomated Unit- and GUI-Testing for Android in Jenkins\u00a0 \u25baTesting a MongoDB with NodeJS, Mocha and Mongoose During the winter term 2017\/2018, we created an app called Take Me Home. The\u2026","rel":"","context":"In &quot;Mobile Apps&quot;","block_context":{"text":"Mobile Apps","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/interactive-media\/mobile-apps\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/tmh_admin_usermanagement_bearbeitet.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":9816,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2020\/02\/24\/using-gitlab-to-set-up-a-ci-cd-workflow-for-an-android-app-from-scratch\/","url_meta":{"origin":3397,"position":2},"title":"Using Gitlab to set up a CI\/CD workflow for an Android App from scratch","author":"Johannes Mauthe","date":"24. February 2020","format":false,"excerpt":"Tim Landenberger (tl061) Johannes Mauthe (jm130) Maximilian Narr (mn066) This blog post aims to provide an overview about how to setup a decent CI\/CD workflow for an android app with the capabilities of Gitlab. The blog post has been written for Gitlab Ultimate. Nevertheless, most features are also available in\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/lh3.googleusercontent.com\/TILM-T31y5pbvWRvoZbA53hR9mLaqMjANXKq7iGX_j-c19K_uiVnmKVDZV9DHBnGdPMgFogHmaNvLSy9gguK5rkMVLlosa4YuvYQQy-d090w90UjqUX_MbwizDt6_zQ1BlT6TrJ5","width":350,"height":200},"classes":[]},{"id":3400,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/testing-a-mongodb-with-nodejs-mocha-and-mongoose\/","url_meta":{"origin":3397,"position":3},"title":"Testing a MongoDB with NodeJS, Mocha and Mongoose","author":"Domenik Jockers","date":"28. March 2018","format":false,"excerpt":"Related articles:\u00a0\u25baTake Me Home - Project Overview\u00a0 \u25baCI\/CD infrastructure: Choosing and setting up a server with Jenkins as Docker image\u00a0\u25baAndroid SDK and emulator in Docker for testing\u00a0 \u25baAutomated Unit- and GUI-Testing for Android in Jenkins\u00a0 Setting up the testing environment and workflow Setup: Jenkins CI Docker Container MongoDB Docker Container\u2026","rel":"","context":"In &quot;Databases&quot;","block_context":{"text":"Databases","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/databases\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3357,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/03\/28\/continuous-integration-move-fast-and-dont-break-things\/","url_meta":{"origin":3397,"position":4},"title":"Continuous Integration \u2013 Move fast and don\u2019t break things","author":"Alexander Wallrabenstein","date":"28. March 2018","format":false,"excerpt":"Continuous Integration is an increasingly popular topic in modern software development. Across many industries the companies acknowledging the importance of IT and delivering value to their customers through great software prevail against their competitors. Many reports indicate that Continuous Integration is one of the major contributing factors to developing high\u2026","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/devops\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/CIPipeline.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/CIPipeline.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2018\/03\/CIPipeline.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1758,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/01\/12\/snakes-exploring-pipelines-a-system-engineering-and-management-project-5\/","url_meta":{"origin":3397,"position":5},"title":"Snakes exploring Pipelines &#8211; A \u201cSystem Engineering and Management\u201d Project","author":"Yann Loic Philippczyk","date":"12. January 2017","format":false,"excerpt":"Part 4: Jenkins and Wrap Up This series of blog entries describes a student project focused on developing an application by using methods like pair programming, test driven development and deployment pipelines. Our first blog entry for this year will at the same time be the final one for this\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/01\/jenkins_code-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/01\/jenkins_code-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/01\/jenkins_code-1.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":744,"user_id":870,"is_guest":0,"slug":"bs092","display_name":"Benedikt Schrade","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/517ad70b0a65723a2366463b8788b94e94eec1a7dc0b91adf4d079bb342c7f90?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/3397","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/870"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=3397"}],"version-history":[{"count":7,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/3397\/revisions"}],"predecessor-version":[{"id":24748,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/3397\/revisions\/24748"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=3397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=3397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=3397"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=3397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}