{"id":1480,"date":"2013-11-26T02:18:52","date_gmt":"2013-11-26T09:18:52","guid":{"rendered":"http:\/\/wiebe-elsinga.com\/blog\/?p=1480"},"modified":"2013-11-26T02:23:58","modified_gmt":"2013-11-26T09:23:58","slug":"functional-testing-for-android","status":"publish","type":"post","link":"http:\/\/wiebe-elsinga.com\/blog\/functional-testing-for-android\/","title":{"rendered":"Functional testing for Android"},"content":{"rendered":"<div class=\"wpsso-pinterest-pin-it-image\" style=\"display:none !important;\">\n<\/div><!-- .wpsso-pinterest-pin-it-image -->\n\n<p>Applying functional testing is not a new technique during the development of Java software. Writing functional tests gives you a good understanding about the stability of an application or system, during code modifications or if new features are added.\u00a0But what about using functional testing when developing an Android application, it is also easy to achieve?<\/p>\n<p>&#8220;And, is the application still works?&#8221; or &#8220;Is the application broken?&#8221;,\u00a0these are questions that developers should be able to answer if a code change has been made or an improvement has been added.\u00a0This is no different when developing an Android application.\u00a0Also, the use of TDD (Test Driven Development), in which first the test is written,\u00a0after which the code follows, is good practice.\u00a0Automated functional testing has become part of software development. Using Selenium and Fitnesse for testing Java application,\u00a0combined with Jenkins has become avery day pratice to most Java developers.\u00a0So you would expect that this would differ during the development of Android app. Unfortunately this is not (yet) the case.\u00a0Because of the relatively rapid growth of Android, these testing methods aren&#8217;t yet mature enough.<\/p>\n<p>Lets look at four testing framework that can be used during Android app development:<\/p>\n<div style=\"background: lightgray; padding: 12pt;\">How to install the specific framework is not part of this article. With the use of code examples pros and cons will be explained for the specific framework.<\/div>\n<p>&nbsp;<br \/>\nThe <a href=\"https:\/\/github.com\/welsinga\/sample_testsing\" target=\"_blank\">Android application<\/a> that is being tested is a simple calculator. The common test scenario we will be implementing is testing if \u20181\u2019 + \u20183\u2019 gives a result of \u20184\u2019.<\/p>\n<h2>UIAutomator<\/h2>\n<p>The Google test framework <a href=\"http:\/\/developer.android.com\/tools\/help\/uiautomator\/index.html\">UIAutomator<\/a>\u00a0makes it possible to write simple Java (and JUnit) functional tests.\u00a0The framework is not tied to the application that needs to be tested, but also has access to the Android platform itself.<br \/>\nThis makes it possible to adjust your Android emulator or physical phone settings while running your test(s). This means that you can test the behavior of the test application if, for example, the internet connection is being switched off.<\/p>\n<div class=\"codecolorer-container java default\" style=\"overflow:auto;white-space:nowrap;width:100%;height:100%;\"><div class=\"java codecolorer\">UiObject allAppsButton <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> UiObject<span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">description<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;Apps&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nallAppsButton.<span class=\"me1\">clickAndWaitForNewWindow<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nUiObject appsTab <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> UiObject<span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">text<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;Apps&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nappsTab.<span class=\"me1\">click<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nUiScrollable appViews <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> UiScrollable<span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">scrollable<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw2\">true<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nappViews.<span class=\"me1\">setAsHorizontalList<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nUiObject calculatorApp <span class=\"sy0\">=<\/span> appViews.<span class=\"me1\">getChildByText<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">className<\/span><span class=\"br0\">&#40;<\/span>android.<span class=\"me1\">widget<\/span>.<span class=\"me1\">TextView<\/span>.<span class=\"kw1\">class<\/span>.<span class=\"me1\">getName<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span>, <span class=\"st0\">&quot;Calculator app&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\ncalculatorApp.<span class=\"me1\">clickAndWaitForNewWindow<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nUiObject oneButton <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> UiObject<span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">text<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;1&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\noneButton.<span class=\"me1\">click<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nUiObject plusButton <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> UiObject<span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">text<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;+&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nplusButton.<span class=\"me1\">click<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nUiObject threeButton <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> UiObject<span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">text<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;3&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nthreeButton.<span class=\"me1\">click<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nUiObject eqButton <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> UiObject<span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">text<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;=&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\neqButton.<span class=\"me1\">click<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nUiObject text <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> UiObject<span class=\"br0\">&#40;<\/span><span class=\"kw1\">new<\/span> UiSelector<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">className<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;android.widget.EditText&quot;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">text<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;4&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nassertTrue<span class=\"br0\">&#40;<\/span>text.<span class=\"me1\">exists<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/div>\n<p>Unfortunately there is little documentation available. Also the framework only supports Android 4.1 or higher.<br \/>\nIn short:<\/p>\n<ul>\n<li><span style=\"color: #339966;\">Fully control device<\/span><\/li>\n<li><span style=\"color: #339966;\">Code written in Java<\/span><\/li>\n<li><span style=\"color: #339966;\">Extends JUnit framework<\/span><\/li>\n<li><span style=\"color: #339966;\">Easy to read<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Only for Android 4.1 and higher<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Little documentation available<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>Robolectric<\/h2>\n<p>The Java-based testing framework <a href=\"http:\/\/pivotal.github.io\/robolectric\/index.html\" target=\"_blank\">Robolectric<\/a> is the best of the tested frameworks in terms of performance. This is because it is not running on a device or on the Android emulator, but uses his own visual UI simulator. As a result, the delaying factor of starting an emulator or installing the app on a device has no influence on running the test(s).\u00a0This makes Robolectric a good choice for TDD.<\/p>\n<div class=\"codecolorer-container java default\" style=\"overflow:auto;white-space:nowrap;width:100%;height:100%;\"><div class=\"java codecolorer\">@RunWith<span class=\"br0\">&#40;<\/span>RobolectricTestRunner.<span class=\"kw1\">class<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw1\">class<\/span> MainActivityTest<br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw1\">private<\/span> MainActivity _activity<span class=\"sy0\">;<\/span><br \/>\n<br \/>\n@Before<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> setUp<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw1\">throws<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+exception\"><span class=\"kw3\">Exception<\/span><\/a><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n_activity <span class=\"sy0\">=<\/span> Robolectric.<span class=\"me1\">buildActivity<\/span><span class=\"br0\">&#40;<\/span>MainActivity.<span class=\"kw1\">class<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">create<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">get<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n@Test<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> testAdding<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw1\">throws<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+exception\"><span class=\"kw3\">Exception<\/span><\/a><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n<a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+button\"><span class=\"kw3\">Button<\/span><\/a> btnOne <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+button\"><span class=\"kw3\">Button<\/span><\/a><span class=\"br0\">&#41;<\/span> _activity.<span class=\"me1\">findViewById<\/span><span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">num_1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+button\"><span class=\"kw3\">Button<\/span><\/a> btnAdd <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+button\"><span class=\"kw3\">Button<\/span><\/a><span class=\"br0\">&#41;<\/span> _activity.<span class=\"me1\">findViewById<\/span><span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">op_add<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+button\"><span class=\"kw3\">Button<\/span><\/a> btnThree <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+button\"><span class=\"kw3\">Button<\/span><\/a><span class=\"br0\">&#41;<\/span> _activity.<span class=\"me1\">findViewById<\/span><span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">num_3<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+button\"><span class=\"kw3\">Button<\/span><\/a> btnEquals <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+button\"><span class=\"kw3\">Button<\/span><\/a><span class=\"br0\">&#41;<\/span> _activity.<span class=\"me1\">findViewById<\/span><span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">op_equ<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nbtnOne.<span class=\"me1\">performClick<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nbtnAdd.<span class=\"me1\">performClick<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nbtnThree.<span class=\"me1\">performClick<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nbtnEquals.<span class=\"me1\">performClick<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nEditText resultText <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span>EditText<span class=\"br0\">&#41;<\/span> _activity.<span class=\"me1\">findViewById<\/span><span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">editText1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nassertEquals<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;4&quot;<\/span>, resultText.<span class=\"me1\">getText<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">toString<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Because Robolectric uses a non-visual UI simulator its not possible to test a problem which only occurs on say a Samsung device.<br \/>\nIn short:<\/p>\n<ul>\n<li><span style=\"color: #339966;\">Does not require emulator or device<\/span><\/li>\n<li><span style=\"color: #339966;\">Code written in Java<\/span><\/li>\n<li><span style=\"color: #339966;\">Extends JUnit framework<\/span><\/li>\n<li><span style=\"color: #339966;\">Fastest in terms of performance<\/span><\/li>\n<li><span style=\"color: #ff0000;\">Does not run on actual device<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>Robotium<\/h2>\n<p>The idea behind <a href=\"https:\/\/code.google.com\/p\/robotium\/\" target=\"_blank\">Robotium<\/a> is that a functional test should description what the user sees and can do. This framework is a good choice if you are just &#8220;black box&#8221; testing your application. Besides extensive documentation, there are some well described examples available and the API is easy to use.<\/p>\n<div class=\"codecolorer-container java default\" style=\"overflow:auto;white-space:nowrap;width:100%;height:100%;\"><div class=\"java codecolorer\"><span class=\"kw1\">public<\/span> <span class=\"kw1\">class<\/span> MainActivityTest <span class=\"kw1\">extends<\/span> ActivityInstrumentationTestCase2<br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">private<\/span> Solo _solo<span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">public<\/span> MainActivityTest<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw1\">super<\/span><span class=\"br0\">&#40;<\/span>MainActivity.<span class=\"kw1\">class<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n@Override<br \/>\n<span class=\"kw1\">protected<\/span> <span class=\"kw4\">void<\/span> setUp<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"kw1\">throws<\/span> <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+exception\"><span class=\"kw3\">Exception<\/span><\/a><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw1\">super<\/span>.<span class=\"me1\">setUp<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n_solo <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> Solo<span class=\"br0\">&#40;<\/span>getInstrumentation<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>, getActivity<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> testAdding<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n_solo.<span class=\"me1\">assertCurrentActivity<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;Is app started&quot;<\/span>, MainActivity.<span class=\"kw1\">class<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n_solo.<span class=\"me1\">clickOnButton<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;CLR&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n_solo.<span class=\"me1\">clickOnButton<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;1&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n_solo.<span class=\"me1\">clickOnButton<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;+&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n_solo.<span class=\"me1\">clickOnButton<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;3&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n_solo.<span class=\"me1\">clickOnButton<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;=&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\nEditText editText <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span>EditText<span class=\"br0\">&#41;<\/span> getActivity<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">findViewById<\/span><span class=\"br0\">&#40;<\/span>com.<span class=\"me1\">elsinga<\/span>.<span class=\"me1\">calculator<\/span>.<span class=\"me1\">R<\/span>.<span class=\"me1\">id<\/span>.<span class=\"me1\">editText1<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nassertEquals<span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;4&quot;<\/span>, editText.<span class=\"me1\">getText<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">toString<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>In short:<\/p>\n<ul>\n<li><span style=\"color: #339966;\">APIs are easy to use<\/span><\/li>\n<li><span style=\"color: #339966;\">Tests are text-based<\/span><\/li>\n<li><span style=\"color: #339966;\">Good for &#8220;black box&#8221; testing<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>Calabash-Android<\/h2>\n<p>Like Robotium, the functional tests described in <a href=\"https:\/\/github.com\/calabash\/calabash-android\" target=\"_blank\">Calabash Android<\/a>\u00a0is written as &#8220;What you see you test&#8221;. The only difference is that the tests are not written in Java, but in <a href=\"http:\/\/cukes.info\/\" target=\"_blank\">Cucumber<\/a> (a text-based structure). This makes it possible that tests can be written\/used by non developers. A drawback, because test(s) aren&#8217;t written in Java, is that &#8220;debugging&#8221; a failing test is not possible.<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><div class=\"text codecolorer\">Feature: Adding<br \/>\n<br \/>\nScenario: add<br \/>\nI should see &quot;1&quot;<br \/>\nThen I press &quot;1&quot;<br \/>\nAnd I press &quot;+&quot;<br \/>\nAnd I press &quot;3&quot;<br \/>\nAnd I press &quot;=&quot;<br \/>\nThen I see &quot;4&quot;<\/div><\/div>\n<p>In short:<\/p>\n<ul>\n<li><span style=\"color: #339966;\">Well documented<\/span><\/li>\n<li><span style=\"color: #339966;\">Test(s) can be writen\/used bij non developers<\/span><\/li>\n<li><span style=\"color: #339966;\">What you see, you test<\/span><\/li>\n<li><span style=\"color: #ff0000;\">\u2018Debuggen\u2019 of tests isn&#8217;t possible<\/span><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>Conclusion<\/h2>\n<p>Functional testing of Android applications is possible. Which test framework you want to use, dependents on the what you want to do with it. To choice with one fits best, ask yourself who is going to make the tests, what needs to be tested and\/or on which device the tests are running on.In any cast, there is enough choice to start writing functional tests.<\/p>\n<p>Source code can be found <a href=\"https:\/\/github.com\/welsinga\/sample_testsing\" target=\"_blank\">here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Applying functional testing is not a new technique during the development of Java software. Writing functional tests gives you a good understanding about the stability of an application or system, during code modifications or if new features are added.\u00a0But what about using functional testing when developing an Android application, it is also easy to achieve? &#8220;And, is the application still works?&#8221; or &#8220;Is the application broken?&#8221;,\u00a0these are questions that developers should be able to answer if a code change has been made or an improvement has been added.\u00a0This is no different when developing an Android application.\u00a0Also, the use of TDD (Test Driven Development), in which first the test is written,\u00a0after which the code follows, is good practice.\u00a0Automated functional testing has become part of software development. Using Selenium and Fitnesse for testing Java application,\u00a0combined with Jenkins has become avery day pratice to most Java developers.\u00a0So you would expect that this would differ during the development of Android app. Unfortunately this is not (yet) the case.\u00a0Because of the relatively rapid growth of Android, these testing methods aren&#8217;t yet mature enough. Lets look at four testing framework that can be used during Android app development: How to install the specific framework is not part of this article. With the use of code examples pros and cons will be explained for the specific framework. &nbsp; The Android application that is being tested is a simple calculator. The common test scenario we will be implementing is testing if \u20181\u2019 + \u20183\u2019 gives a result of \u20184\u2019. UIAutomator The Google test framework UIAutomator\u00a0makes it possible to write simple Java (and JUnit) functional tests.\u00a0The framework is not tied to the application that needs to be tested, but also has access to the Android platform itself. This makes it possible to adjust your Android emulator or physical phone settings while running your test(s). This means that you can test the behavior of the test application if, for example, the internet connection is being switched off. UiObject allAppsButton = new UiObject&#40;new UiSelector&#40;&#41;.description&#40;&quot;Apps&quot;&#41;&#41;; allAppsButton.clickAndWaitForNewWindow&#40;&#41;; UiObject appsTab = new UiObject&#40;new UiSelector&#40;&#41;.text&#40;&quot;Apps&quot;&#41;&#41;; appsTab.click&#40;&#41;; UiScrollable appViews = new UiScrollable&#40;new UiSelector&#40;&#41;.scrollable&#40;true&#41;&#41;; appViews.setAsHorizontalList&#40;&#41;; UiObject calculatorApp = appViews.getChildByText&#40;new UiSelector&#40;&#41;.className&#40;android.widget.TextView.class.getName&#40;&#41;&#41;, &quot;Calculator app&quot;&#41;; calculatorApp.clickAndWaitForNewWindow&#40;&#41;; UiObject oneButton = new UiObject&#40;new UiSelector&#40;&#41;.text&#40;&quot;1&quot;&#41;&#41;; oneButton.click&#40;&#41;; UiObject plusButton = new UiObject&#40;new UiSelector&#40;&#41;.text&#40;&quot;+&quot;&#41;&#41;; plusButton.click&#40;&#41;; UiObject threeButton = new UiObject&#40;new UiSelector&#40;&#41;.text&#40;&quot;3&quot;&#41;&#41;; threeButton.click&#40;&#41;; UiObject eqButton = new UiObject&#40;new UiSelector&#40;&#41;.text&#40;&quot;=&quot;&#41;&#41;; eqButton.click&#40;&#41;; UiObject text = new UiObject&#40;new UiSelector&#40;&#41;.className&#40;&quot;android.widget.EditText&quot;&#41;.text&#40;&quot;4&quot;&#41;&#41;; assertTrue&#40;text.exists&#40;&#41;&#41;; Unfortunately there is little documentation available. Also the framework only supports Android 4.1 or higher. In short: Fully control device Code written in Java Extends JUnit framework Easy to read Only for Android 4.1 and higher Little documentation available &nbsp; Robolectric The Java-based testing framework Robolectric is the best of the tested frameworks in terms of performance. This is because it is not running on a device or on the Android emulator, but uses his own visual UI simulator. As a result, the delaying factor of starting an emulator or installing the app on a device has no influence on running the test(s).\u00a0This makes Robolectric a good choice for TDD. @RunWith&#40;RobolectricTestRunner.class&#41; public class MainActivityTest &#123; private MainActivity _activity; @Before public void setUp&#40;&#41; throws Exception &#123; _activity = Robolectric.buildActivity&#40;MainActivity.class&#41;.create&#40;&#41;.get&#40;&#41;; &#125; @Test public void testAdding&#40;&#41; throws Exception &#123; Button btnOne = &#40;Button&#41; _activity.findViewById&#40;R.id.num_1&#41;; Button btnAdd = &#40;Button&#41; _activity.findViewById&#40;R.id.op_add&#41;; Button btnThree = &#40;Button&#41; _activity.findViewById&#40;R.id.num_3&#41;; Button btnEquals = &#40;Button&#41; _activity.findViewById&#40;R.id.op_equ&#41;; btnOne.performClick&#40;&#41;; btnAdd.performClick&#40;&#41;; btnThree.performClick&#40;&#41;; btnEquals.performClick&#40;&#41;; EditText resultText = &#40;EditText&#41; _activity.findViewById&#40;R.id.editText1&#41;; assertEquals&#40;&quot;4&quot;, resultText.getText&#40;&#41;.toString&#40;&#41;&#41;; &#125; &#125; Because Robolectric uses a non-visual UI simulator its not possible to test a problem which only occurs on say a Samsung device. In short: Does not require emulator or device Code written in Java Extends JUnit framework Fastest in terms of performance Does not run on actual device &nbsp; Robotium The idea behind Robotium is that a functional test should description what the user sees and can do. This framework is a good choice if you are just &#8220;black box&#8221; testing your application. Besides extensive documentation, there are some well described examples available and the API is easy to use. public class MainActivityTest extends ActivityInstrumentationTestCase2 &#123; private Solo _solo; public MainActivityTest&#40;&#41; &#123; super&#40;MainActivity.class&#41;; &#125; @Override protected void setUp&#40;&#41; throws Exception &#123; super.setUp&#40;&#41;; _solo = new Solo&#40;getInstrumentation&#40;&#41;, getActivity&#40;&#41;&#41;; &#125; public void testAdding&#40;&#41; &#123; _solo.assertCurrentActivity&#40;&quot;Is app started&quot;, MainActivity.class&#41;; _solo.clickOnButton&#40;&quot;CLR&quot;&#41;; _solo.clickOnButton&#40;&quot;1&quot;&#41;; _solo.clickOnButton&#40;&quot;+&quot;&#41;; _solo.clickOnButton&#40;&quot;3&quot;&#41;; _solo.clickOnButton&#40;&quot;=&quot;&#41;; EditText editText = &#40;EditText&#41; getActivity&#40;&#41;.findViewById&#40;com.elsinga.calculator.R.id.editText1&#41;; assertEquals&#40;&quot;4&quot;, editText.getText&#40;&#41;.toString&#40;&#41;&#41;; &#125; &#125; In short: APIs are easy to use Tests are text-based Good for &#8220;black box&#8221; testing &nbsp; Calabash-Android Like Robotium, the functional tests described in Calabash Android\u00a0is written as &#8220;What you see you test&#8221;. The only difference is that the tests are not written in Java, but in Cucumber (a text-based structure). This makes it possible that tests can be written\/used by non developers. A drawback, because test(s) aren&#8217;t written in Java, is that &#8220;debugging&#8221; a failing test is not possible. Feature: Adding Scenario: add I should see &quot;1&quot; Then I press &quot;1&quot; And I press &quot;+&quot; And I press &quot;3&quot; And I press &quot;=&quot; Then I see &quot;4&quot; In short: Well documented Test(s) can be writen\/used bij non developers What you see, you test \u2018Debuggen\u2019 of tests isn&#8217;t possible &nbsp; Conclusion Functional testing of Android applications is possible. Which test framework you want to use, dependents on the what you want to do with it. To choice with one fits best, ask yourself who is going to make the tests, what needs to be tested and\/or on which device the tests are running on.In any cast, there is enough choice to start writing functional tests. Source code can be found here<\/p>\n","protected":false},"author":1,"featured_media":1247,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[154,135],"_links":{"self":[{"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/posts\/1480"}],"collection":[{"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/comments?post=1480"}],"version-history":[{"count":0,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/posts\/1480\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/media\/1247"}],"wp:attachment":[{"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/media?parent=1480"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/categories?post=1480"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/tags?post=1480"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}