<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-25456655</atom:id><lastBuildDate>Sat, 28 Jan 2012 20:31:56 +0000</lastBuildDate><category>thin client</category><category>instrumentation</category><category>mediawiki</category><category>Dogfish</category><category>slides</category><category>continuous integration</category><category>jelly</category><category>javascript</category><category>seamless</category><category>swing</category><category>Buenos Aires</category><category>jenkins</category><category>javadoc</category><category>junit</category><category>asus</category><category>pxes</category><category>mock</category><category>maven</category><category>github</category><category>fedora</category><category>486</category><category>eeepc</category><category>ica</category><category>webview</category><category>sqlite3</category><category>presentation</category><category>gnome</category><category>ndk</category><category>gpl</category><category>chimpchat</category><category>TDD</category><category>webkit</category><category>auito</category><category>easymock</category><category>shell</category><category>sdk</category><category>python</category><category>electron</category><category>autoglade</category><category>test driven development</category><category>busybox</category><category>meenie</category><category>eclipse</category><category>multiscreen</category><category>monkeyrunner</category><category>training</category><category>compaq</category><category>linux</category><category>zenity</category><category>ant</category><category>boot</category><category>java</category><category>fragments</category><category>kml</category><category>sourceforge</category><category>tutorial</category><category>intent</category><category>hamcrest</category><category>contacts</category><category>adb</category><category>UML</category><category>animations</category><category>gsm</category><category>Web services</category><category>hudson</category><category>gnome-terminal-launcher</category><category>NetBeans</category><category>bash</category><category>eye contact</category><category>gui</category><category>google chrome</category><category>positron</category><category>AATG</category><category>jemmy</category><category>gnome-terminal</category><category>android</category><category>tests</category><category>glade</category><category>citrix</category><category>appengine</category><category>emulator</category><category>sikuli</category><category>kernel</category><category>cult</category><category>japan</category><category>emma</category><category>maps</category><category>ubuntu</category><category>Glassfish</category><category>google</category><title>Diego Torres Milano's blog</title><description>I hope I can find a good description for this blog...</description><link>http://dtmilano.blogspot.com/</link><managingEditor>noreply@blogger.com (Diego Torres Milano)</managingEditor><generator>Blogger</generator><openSearch:totalResults>140</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/DiegoTorresMilanosBlog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="diegotorresmilanosblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-899257020381016474</guid><pubDate>Sat, 28 Jan 2012 20:31:00 +0000</pubDate><atom:updated>2012-01-28T15:31:56.196-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">chimpchat</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><title>monkeyrunner: testing views properties</title><description>There are several questions floating around, like this one in &lt;a href="http://stackoverflow.com/questions/9013379/can-i-read-the-label-on-a-button-with-monkeyrunner"&gt;stackoverflow&lt;/a&gt;, about how some view properties could be obtained from a monkeyrunner script or putting the question in more general terms:&lt;br /&gt;
how a test that&amp;nbsp;verifies&amp;nbsp;some properties can be created using monkeyrunner ?&lt;br /&gt;
&lt;br /&gt;
This is a required feature if we are going to create tests in monkeyrunner otherwise our alternatives to verify some state in the views is limited to visual comparison. These cases were treated in previous articles like:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://dtmilano.blogspot.com/2011/04/monkeyrunner-visual-image-comparison.html"&gt;monkeyrunner: visual image comparison&lt;/a&gt;, and&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dtmilano.blogspot.com/2012/01/automated-android-testing-using-sikuli.html"&gt;Automated Android testing using Sikuli&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
but now we will be using a logical approach rather than visual comparison. To be able to do it we need a mechanism of obtaining view properties values.&lt;br /&gt;
Lastest versions of monkeyrunner provides an extension to &lt;b&gt;MonkeyDevice&lt;/b&gt; called &lt;b&gt;EasyMonkeyDevice&lt;/b&gt; and this class has methods to get some properties like &lt;b&gt;MonkeyDevice.getText()&lt;/b&gt;.&lt;br /&gt;
This API is not documented so expect changes in the future.&lt;br /&gt;
TemperatureConverter, a sample application that has been used in other articles before, will be our application under test. The source code can be obtained from &lt;a href="https://github.com/dtmilano/TemperatureConverter"&gt;github&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The idea behind this test is, using monkeyrunner to connect to &amp;nbsp;the device, enter &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;123&lt;/b&gt;&lt;/span&gt; in the Celsius field and expect to find &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;253.40&lt;/b&gt;&lt;/span&gt; in the Fahrenheit field.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="background-color: #fbfbfb; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;&lt;span class="Comment"&gt;#! /usr/bin/env monkeyrunner&lt;/span&gt;

import sys
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
from com.android.monkeyrunner.easy import EasyMonkeyDevice
from com.android.monkeyrunner.easy import By

&lt;span class="Comment"&gt;# connect to the device&lt;/span&gt;
device = MonkeyRunner.waitForConnection()

&lt;span class="Comment"&gt;# start TemperatureConverter&lt;/span&gt;
device.startActivity(component=&lt;span class="String"&gt;"com.example.i2at.tc/.TemperatureConverterActivity"&lt;/span&gt;)

&lt;span class="Comment"&gt;# use the EasyMonkey API&lt;/span&gt;
easyDevice = EasyMonkeyDevice(device)

celsiusId = By.id(&lt;span class="String"&gt;'id/celsius'&lt;/span&gt;)
if not celsiusId:
   raise Exception(&lt;span class="String"&gt;"View with id/celsius not found"&lt;/span&gt;)

fahrenheitId = By.id(&lt;span class="String"&gt;'id/fahrenheit'&lt;/span&gt;)
if not fahrenheitId:
   raise Exception(&lt;span class="String"&gt;"View with id/fahrenheit not found"&lt;/span&gt;)

MonkeyRunner.sleep(3)
easyDevice.type(celsiusId, &lt;span class="String"&gt;'123'&lt;/span&gt;)
MonkeyRunner.sleep(3)

celsius = easyDevice.getText(celsiusId)
fahrenheit = easyDevice.getText(fahrenheitId)
expected = &lt;span class="String"&gt;'253.40'&lt;/span&gt;

if fahrenheit == expected:
   print &lt;span class="String"&gt;'PASS'&lt;/span&gt;
else:
   print &lt;span class="String"&gt;'FAIL: expected %s, actual %s'&lt;/span&gt; % (expected, fahrenheit)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
Unfortunately, it won't work in most of the cases. You are likely to receive this exception:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #cc0000;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; java.lang.RuntimeException: java.lang.RuntimeException: No text property on node&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I felt frustrated at first, but what the advantage of an Open Source project is other than going to the source code and find out why it's not working.&lt;/div&gt;
&lt;div&gt;
I dug into the Chimpchat, HierarchyView and ViewServer code and found out that for some reason EasyMonkeyDevice is looking for the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;text:mText&lt;/b&gt;&lt;/span&gt; property when in most of the cases it should be only &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;mText&lt;/b&gt;&lt;/span&gt;.&lt;/div&gt;
&lt;div&gt;
So here is the patch, that I will be uploading to android soon:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="background-color: #fbfbfb; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;&lt;span class="Type"&gt;diff --git a/chimpchat/src/com/android/chimpchat/hierarchyviewer/HierarchyViewer.java b/chimpchat/src/com/android/chimpchat/hierarchyviewer/HierarchyViewer.java&lt;/span&gt;
index 6ad98ad..6c34d71 100644
&lt;span class="Type"&gt;--- a/chimpchat/src/com/android/chimpchat/hierarchyviewer/HierarchyViewer.java&lt;/span&gt;
&lt;span class="Type"&gt;+++ b/chimpchat/src/com/android/chimpchat/hierarchyviewer/HierarchyViewer.java&lt;/span&gt;
&lt;span class="Statement"&gt;@@ -170,7 +170,11 @@&lt;/span&gt;&lt;span class="PreProc"&gt; public class HierarchyViewer {&lt;/span&gt;
         }
         ViewNode.Property textProperty = node.namedProperties.get("text:mText");
         if (textProperty == null) {
&lt;span class="Special"&gt;-            throw new RuntimeException("No text property on node");&lt;/span&gt;
&lt;span class="Identifier"&gt;+            // dtmilano: give it another chance, ICS ViewServer returns mText&lt;/span&gt;
&lt;span class="Identifier"&gt;+            textProperty = node.namedProperties.get("mText");&lt;/span&gt;
&lt;span class="Identifier"&gt;+            if ( textProperty == null ) {&lt;/span&gt;
&lt;span class="Identifier"&gt;+                throw new RuntimeException("No text property on node");&lt;/span&gt;
&lt;span class="Identifier"&gt;+            }&lt;/span&gt;
         }
         return textProperty.value;
     }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div&gt;
Once this patch is applied and you rebuild monkeyrunner or the entire SDK if you prefer, you will be presented with the expected result:

&lt;b&gt;      PASS&lt;/b&gt;

&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-899257020381016474?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2012/01/monkeyrunner-testing-views-properties.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1566307613802055087</guid><pubDate>Sat, 21 Jan 2012 06:28:00 +0000</pubDate><atom:updated>2012-01-21T02:07:36.530-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">emulator</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">sikuli</category><category domain="http://www.blogger.com/atom/ns#">android</category><title>Automated Android testing using Sikuli</title><description>&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;a href="http://sikuli.org/"&gt;Sikuli&lt;/a&gt; is a tool that can supplement you testing toolbox.&lt;br /&gt;It is a visual technology to automate and test graphical user interfaces (GUI) using images (screenshots). The scripts you create with this tool are in the &lt;i&gt;Sikuli Script&lt;/i&gt; language, which is a Python (Jython) extension. It also features &lt;i&gt;Sikuli IDE&lt;/i&gt; which is an integrated development environment for writing visual scripts with screenshots easily.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;There are plenty of examples and tutorials in its web site but most of them are intended for desktop operating systems. As usual here we will be focusing on its Android praxis.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif; font-size: large;"&gt;&lt;b&gt;Unlocking the emulator&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;Out example will be unlocking the emulator screen using some screenshots. That is, instead of guessing or finding out a-priori the coordinates of the touch events that are needed to achieve the goal of unlocking the screen we will use images.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;The &lt;i&gt;Sikuli IDE&lt;/i&gt; provides the means of obtaining the screenshots to complete the arguments of the specific methods.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;For example, if you select the &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;click()&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt; method to click over something, you are prompted to take a screenshot of an area of the screen that will be the target and the the IDE shows this thumbnail.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;Instead of trying to describe it, it's worth showing you the IDE window to understand what I mean.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-hATX5y-8VuY/TxpWayVwYwI/AAAAAAAABqQ/8zMFAcMT7qQ/s1600/sikuli-ide.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="228" src="http://2.bp.blogspot.com/-hATX5y-8VuY/TxpWayVwYwI/AAAAAAAABqQ/8zMFAcMT7qQ/s320/sikuli-ide.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;The idea is to click on the Android text, just to gain windows focus in case it was lost. The specific method to do this is &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;App.focus("5554")&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt; assuming that &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;"5554"&lt;/b&gt;&lt;/span&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt; appears in the emulator's window title, work on Windows and Linux but it doesn't work on Mac OSX.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;Then we search the screen for the image of the lock button, when we find it we touch with the mouse, wait a little, and drag till the position of the unlock dot, where we move up.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/N0r6u8WzjPk/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/N0r6u8WzjPk?version=3&amp;f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" /&gt;

&lt;param name="bgcolor" value="#FFFFFF" /&gt;

&lt;embed width="320" height="266"  src="http://www.youtube.com/v/N0r6u8WzjPk?version=3&amp;f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif; font-size: large;"&gt;&lt;b&gt;Unlocking a pattern lock&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;The previous example was very illustrative, but sincerely it was a bit simple and could have been done with other tools too.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;So, let's get things a bit more complicated as it is the phone locked by a pattern.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;As before we take the screenshot of the pattern but this time we double click on it in the IDE to get the &lt;b&gt;Pattern Settings&lt;/b&gt; window and there we set the &lt;b&gt;Target Offset&lt;/b&gt; to follow the shape of the pattern. This is then identified by a red cross over the screenshot as follows:&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-uUd9xp2RSf4/Txpjz2xcP2I/AAAAAAAABqc/Hb_oJrwJkzw/s1600/sikuli-ide-unlock-emulator-pattern.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="228" src="http://3.bp.blogspot.com/-uUd9xp2RSf4/Txpjz2xcP2I/AAAAAAAABqc/Hb_oJrwJkzw/s320/sikuli-ide-unlock-emulator-pattern.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;When you run this script you can see how the pattern is completed and consequently the phone unlocked.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;Pretty simple, right ?&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;Definitely something you should consider when automating GUI tests.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-1566307613802055087?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2012/01/automated-android-testing-using-sikuli.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-hATX5y-8VuY/TxpWayVwYwI/AAAAAAAABqQ/8zMFAcMT7qQ/s72-c/sikuli-ide.png" height="72" width="72" /><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-6475315797803196866</guid><pubDate>Thu, 22 Dec 2011 20:10:00 +0000</pubDate><atom:updated>2011-12-22T15:16:10.015-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AATG</category><category domain="http://www.blogger.com/atom/ns#">jenkins</category><category domain="http://www.blogger.com/atom/ns#">junit</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">maven</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">continuous integration</category><category domain="http://www.blogger.com/atom/ns#">emma</category><title>Android Continuous Integration Guide</title><description>&lt;a href="https://plus.google.com/b/107552891605530829455/"&gt;Android Application Testing Guide&lt;/a&gt; features a whole chapter about &lt;b&gt;Continuous Integration (Chapter 8)&lt;/b&gt;, however some latest changes and additions to the tools available may require a more in-depth coverage of the subject.&lt;br /&gt;
Consequently, I'm preparing an &lt;a href="https://plus.google.com/b/117397736323013374412/117397736323013374412/posts"&gt;Android Continuous Integration Guide&lt;/a&gt; to compile all the information laying around on the subject and to provide concise, working examples that you could use to base your own projects on.&lt;br /&gt;
In the creation of these examples using &lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt; and &lt;a href="http://emma.sourceforge.net/"&gt;EMMA&lt;/a&gt; for code coverage one of the most annoying things is the &lt;b&gt;R class&lt;/b&gt; affecting the results of the coverage report, as most probably you are not creating tests for such auto-generated class.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-A-OWKeqTHUw/TvOG6TDpXLI/AAAAAAAABow/-doPFy5Zhnw/s1600/jenkins-coverage-tests.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="http://4.bp.blogspot.com/-A-OWKeqTHUw/TvOG6TDpXLI/AAAAAAAABow/-doPFy5Zhnw/s320/jenkins-coverage-tests.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
This screenshot show how the coverage report for classes reaches 100% once we filter out the &lt;b&gt;R class&lt;/b&gt;.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
The problem is that in current &lt;b&gt;Android SDK Tools (Rev 16)&lt;/b&gt;, there's no way to filter classes from EMMA coverage unless you modify the file &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&lt;i&gt;&lt;sdk-dir&gt;&lt;/sdk-dir&gt;&lt;/i&gt;&lt;android-sdk&gt;/tools/ant/build.xml&lt;/android-sdk&gt;&lt;/b&gt;&lt;/span&gt;, changing the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;emma&lt;/b&gt;&lt;/span&gt; target to include the filters as showed in this code snippet:&lt;/div&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="background-color: #fbfbfb; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;

            &lt;span class="Comment"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="Comment"&gt;-- It only instruments class files, not any external libs --&lt;/span&gt;&lt;span class="Comment"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;emma&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;enabled&lt;/span&gt;=&lt;span class="String"&gt;"true"&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;
               &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Identifier"&gt;instr&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;verbosity&lt;/span&gt;=&lt;span class="String"&gt;"${verbosity}"&lt;/span&gt;
&lt;span class="Identifier"&gt;                               &lt;/span&gt;&lt;span class="Type"&gt;mode&lt;/span&gt;=&lt;span class="String"&gt;"overwrite"&lt;/span&gt;
&lt;span class="Identifier"&gt;                               &lt;/span&gt;&lt;span class="Type"&gt;instrpath&lt;/span&gt;=&lt;span class="String"&gt;"${out.absolute.dir}/classes"&lt;/span&gt;
&lt;span class="Identifier"&gt;                               &lt;/span&gt;&lt;span class="Type"&gt;outdir&lt;/span&gt;=&lt;span class="String"&gt;"${out.absolute.dir}/classes"&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="Comment"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="Comment"&gt;-- DTM: 2011-12-23: added filter for R --&lt;/span&gt;&lt;span class="Comment"&gt;&amp;gt;&lt;/span&gt;
                     &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;filter&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;excludes&lt;/span&gt;=&lt;span class="String"&gt;"*.R"&lt;/span&gt;&lt;span class="Identifier"&gt; /&amp;gt;&lt;/span&gt;
                     &lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;filter&lt;/span&gt;&lt;span class="Identifier"&gt; &lt;/span&gt;&lt;span class="Type"&gt;excludes&lt;/span&gt;=&lt;span class="String"&gt;"*.R$*"&lt;/span&gt;&lt;span class="Identifier"&gt; /&amp;gt;&lt;/span&gt;
                &lt;span class="Identifier"&gt;&amp;lt;/instr&amp;gt;&lt;/span&gt;
                &lt;span class="Comment"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="Comment"&gt;-- &lt;/span&gt;&lt;span class="Todo"&gt;TODO&lt;/span&gt;&lt;span class="Comment"&gt;: exclusion filters on R*.class and allowing custom exclusion from&lt;/span&gt;
&lt;span class="Comment"&gt;                             user defined file --&lt;/span&gt;&lt;span class="Comment"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="Identifier"&gt;&amp;lt;/emma&amp;gt;&lt;/span&gt;

&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
I hope this help you getting started and stay tuned, &lt;b&gt;Android Continuous Integration Guide&lt;/b&gt; is scheduled to be released by the end of January 2012.&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Any comments, suggestions and requests are welcome and can be entered using the &lt;b&gt;&lt;span style="color: #cc0000;"&gt;Google+&lt;/span&gt;&lt;/b&gt; pages.&amp;nbsp;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-6475315797803196866?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/12/android-continuous-integration-guide.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-A-OWKeqTHUw/TvOG6TDpXLI/AAAAAAAABow/-doPFy5Zhnw/s72-c/jenkins-coverage-tests.png" height="72" width="72" /><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-3961948815387938542</guid><pubDate>Wed, 16 Nov 2011 04:13:00 +0000</pubDate><atom:updated>2011-12-12T00:15:39.552-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">instrumentation</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">github</category><category domain="http://www.blogger.com/atom/ns#">emulator</category><category domain="http://www.blogger.com/atom/ns#">ant</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">emma</category><category domain="http://www.blogger.com/atom/ns#">adb</category><title>Obtaining code coverage of a running Android application</title><description>How can we obtain the code coverage of a running application, not just its tests ?&lt;br /&gt;
I have been asked this question many times. Recently, &lt;a href="http://www.blogger.com/profile/02275026013942641493"&gt;Jonas&lt;/a&gt; posted a similar question as&amp;nbsp;comment&amp;nbsp;to &lt;a href="http://dtmilano.blogspot.com/2011/07/eclipse-android-and-emma-code-coverage.html"&gt;Eclipse, Android and EMMA code coverage&lt;/a&gt;. So we will elaborate the solution to this problem.&lt;br /&gt;
But firstly, let's do a brief introduction of the concepts.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;EMMA: a free Java code coverage tool&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;a href="http://emma.sourceforge.net/"&gt;EMMA&lt;/a&gt; is an open-source toolkit for measuring and reporting Java code coverage. EMMA distinguishes itself from other tools by going after a unique feature combination: support for large-scale enterprise software development while keeping individual developer's work fast and iterative.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Android includes &lt;b&gt;EMMA v2.0, build 5312&lt;/b&gt;, which includes some minor changes introduced by Android to adapt it for the platform specifics.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Android Instrumentation&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
The instrumentation framework is the foundation of the testing framework. Instrumentation controls the application under test and permits the injection of mock components required by the application to run.&lt;br /&gt;
&lt;div&gt;
Usually, an &lt;a href="http://developer.android.com/reference/android/test/InstrumentationTestRunner.html"&gt;InstrumentationTestRunner&lt;/a&gt;, a special class the extends Instrumentation, is used to run various types of TestCases, against an android application.&lt;/div&gt;
&lt;div&gt;
Typically, this Instrumentation is declared in the &lt;b&gt;test project&lt;/b&gt;'s &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;AndroidManifest.xml&lt;/span&gt; and then run from Eclipse or from the command line using &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;am instrument&lt;/b&gt;&lt;/span&gt;.&lt;/div&gt;
&lt;div&gt;
Also, to generate EMMA code coverage &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;-e coverage true&lt;/span&gt;&lt;/b&gt;&amp;nbsp;option is added to the command line.&lt;/div&gt;
&lt;div&gt;
Basically, we have all the components but in different places because we want to obtain the code coverage from the running application not from its tests.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;b&gt;EmmaInstrumentation&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
The first thing we need to do is to create a new Instrumentation that starts the Activity Under Test using EMMA instrumentation and when this Activity is finished the coverage data is saved to a file.&lt;br /&gt;
To be notified of this Activity finish we need a listener that we can set extending the AUT because one of our objectives is to keep it unchanged.&lt;br /&gt;
&lt;br /&gt;
To illustrate this technique we will be using the &lt;b&gt;Temperature Converter&lt;/b&gt; application that we have used many times in other &lt;a href="http://dtmilano.blogspot.com/2011/08/android-application-testing-guide-q_26.html"&gt;posts&lt;/a&gt;. The source code is as usual available through &lt;a href="https://github.com/dtmilano/TemperatureConverter"&gt;github&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="background-color: #fbfbfb; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;
&lt;span class="PreProc"&gt;package&lt;/span&gt; com.example.instrumentation;

&lt;span class="PreProc"&gt;import&lt;/span&gt; java.lang.reflect.InvocationTargetException;
&lt;span class="PreProc"&gt;import&lt;/span&gt; java.lang.reflect.Method;

&lt;span class="PreProc"&gt;import&lt;/span&gt; com.example.i2at.tc.TemperatureConverterActivity;
&lt;span class="Comment"&gt;//import com.vladium.emma.rt.RT;&lt;/span&gt;

&lt;span class="PreProc"&gt;import&lt;/span&gt; android.app.Activity;
&lt;span class="PreProc"&gt;import&lt;/span&gt; android.app.Instrumentation;
&lt;span class="PreProc"&gt;import&lt;/span&gt; android.content.Intent;
&lt;span class="PreProc"&gt;import&lt;/span&gt; android.os.Bundle;
&lt;span class="PreProc"&gt;import&lt;/span&gt; android.os.Looper;
&lt;span class="PreProc"&gt;import&lt;/span&gt; android.util.Log;

&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; EmmaInstrumentation &lt;span class="Type"&gt;extends&lt;/span&gt; Instrumentation &lt;span class="Type"&gt;implements&lt;/span&gt; FinishListener {

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; String TAG = &lt;span class="String"&gt;"EmmaInstrumentation"&lt;/span&gt;;

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; &lt;span class="Type"&gt;boolean&lt;/span&gt; LOGD = &lt;span class="Boolean"&gt;true&lt;/span&gt;;

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; String DEFAULT_COVERAGE_FILE_PATH = &lt;span class="String"&gt;"/mnt/sdcard/coverage.ec"&lt;/span&gt;;

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; Bundle mResults = &lt;span class="Statement"&gt;new&lt;/span&gt; Bundle();

    &lt;span class="Type"&gt;private&lt;/span&gt; Intent mIntent;

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;boolean&lt;/span&gt; mCoverage = &lt;span class="Boolean"&gt;true&lt;/span&gt;;

    &lt;span class="Type"&gt;private&lt;/span&gt; String mCoverageFilePath;

    &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;     *&lt;/span&gt;&lt;span class="Special"&gt; Extends the AUT to provide the necessary behavior to invoke the&lt;/span&gt;
&lt;span class="Comment"&gt;     *&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Special"&gt;{@link FinishListener}&lt;/span&gt;&lt;span class="Special"&gt; that may have been provided using&lt;/span&gt;
&lt;span class="Comment"&gt;     *&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Special"&gt;{@link #setFinishListener(FinishListener)}&lt;/span&gt;&lt;span class="Special"&gt;.&lt;/span&gt;
&lt;span class="Comment"&gt;     * &lt;/span&gt;
&lt;span class="Comment"&gt;     * It's important to note that the original Activity has not been modified.&lt;/span&gt;
&lt;span class="Comment"&gt;     * Also, the Activity must be declared in the&lt;/span&gt;
&lt;span class="Comment"&gt;     * &lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="Statement"&gt;code&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Comment"&gt;AndroidManifest.xml&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="Statement"&gt;code&lt;/span&gt;&lt;span class="Identifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="Comment"&gt; because it is started by an intent in&lt;/span&gt;
&lt;span class="Comment"&gt;     * &lt;/span&gt;&lt;span class="Special"&gt;{@link EmmaInstrumentation#onStart()}&lt;/span&gt;&lt;span class="Comment"&gt;. This turns more difficult to use&lt;/span&gt;
&lt;span class="Comment"&gt;     * other methods like using template classes. This latter method could be&lt;/span&gt;
&lt;span class="Comment"&gt;     * viable, but all Activity methods should be re-written to invoke the&lt;/span&gt;
&lt;span class="Comment"&gt;     * template parameter class corresponding methods.&lt;/span&gt;
&lt;span class="Comment"&gt;     * &lt;/span&gt;
&lt;span class="Comment"&gt;     * &lt;/span&gt;&lt;span class="Special"&gt;@author&lt;/span&gt;&lt;span class="Comment"&gt; diego&lt;/span&gt;
&lt;span class="Comment"&gt;     * &lt;/span&gt;
&lt;span class="Comment"&gt;     */&lt;/span&gt;
    &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; InstrumentedActivity &lt;span class="Type"&gt;extends&lt;/span&gt;
    TemperatureConverterActivity {
        &lt;span class="Type"&gt;private&lt;/span&gt; FinishListener mListener;

        &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; setFinishListener(FinishListener listener) {
            mListener = listener;
        }

        &lt;span class="PreProc"&gt;@Override&lt;/span&gt;
        &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; finish() {
            &lt;span class="Statement"&gt;if&lt;/span&gt; (LOGD)
                Log.d(TAG + &lt;span class="String"&gt;".InstrumentedActivity"&lt;/span&gt;, &lt;span class="String"&gt;"finish()"&lt;/span&gt;);
            &lt;span class="Type"&gt;super&lt;/span&gt;.finish();
            &lt;span class="Statement"&gt;if&lt;/span&gt; (mListener != &lt;span class="Constant"&gt;null&lt;/span&gt;) {
                mListener.onActivityFinished();
            }
        }

    }

    &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;     *&lt;/span&gt;&lt;span class="Special"&gt; Constructor&lt;/span&gt;
&lt;span class="Special"&gt;     &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
    &lt;span class="Type"&gt;public&lt;/span&gt; EmmaInstrumentation() {

    }

    &lt;span class="PreProc"&gt;@Override&lt;/span&gt;
    &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; onCreate(Bundle arguments) {
        &lt;span class="Statement"&gt;if&lt;/span&gt; (LOGD)
            Log.d(TAG, &lt;span class="String"&gt;"onCreate("&lt;/span&gt; + arguments + &lt;span class="String"&gt;")"&lt;/span&gt;);
        &lt;span class="Type"&gt;super&lt;/span&gt;.onCreate(arguments);

        &lt;span class="Statement"&gt;if&lt;/span&gt; (arguments != &lt;span class="Constant"&gt;null&lt;/span&gt;) {
            mCoverage = getBooleanArgument(arguments, &lt;span class="String"&gt;"coverage"&lt;/span&gt;);
            mCoverageFilePath = arguments.getString(&lt;span class="String"&gt;"coverageFile"&lt;/span&gt;);
        }

        mIntent = &lt;span class="Statement"&gt;new&lt;/span&gt; Intent(getTargetContext(), InstrumentedActivity.&lt;span class="Type"&gt;class&lt;/span&gt;);
        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        start();
    }

    &lt;span class="PreProc"&gt;@Override&lt;/span&gt;
    &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; onStart() {
        &lt;span class="Statement"&gt;if&lt;/span&gt; (LOGD)
            Log.d(TAG, &lt;span class="String"&gt;"onStart()"&lt;/span&gt;);
        &lt;span class="Type"&gt;super&lt;/span&gt;.onStart();

        Looper.prepare();
        InstrumentedActivity activity = (InstrumentedActivity) startActivitySync(mIntent);
        activity.setFinishListener(&lt;span class="Type"&gt;this&lt;/span&gt;);
    }

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;boolean&lt;/span&gt; getBooleanArgument(Bundle arguments, String tag) {
        String tagString = arguments.getString(tag);
        &lt;span class="Statement"&gt;return&lt;/span&gt; tagString != &lt;span class="Constant"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; Boolean.parseBoolean(tagString);
    }

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; generateCoverageReport() {
        &lt;span class="Statement"&gt;if&lt;/span&gt; (LOGD)
            Log.d(TAG, &lt;span class="String"&gt;"generateCoverageReport()"&lt;/span&gt;);

        java.io.File coverageFile = &lt;span class="Statement"&gt;new&lt;/span&gt; java.io.File(getCoverageFilePath());

        &lt;span class="Comment"&gt;// We may use this if we want to avoid refecltion and we include&lt;/span&gt;
        &lt;span class="Comment"&gt;// emma.jar&lt;/span&gt;
        &lt;span class="Comment"&gt;// RT.dumpCoverageData(coverageFile, false, false);&lt;/span&gt;

        &lt;span class="Comment"&gt;// Use reflection to call emma dump coverage method, to avoid&lt;/span&gt;
        &lt;span class="Comment"&gt;// always statically compiling against emma jar&lt;/span&gt;
        &lt;span class="Statement"&gt;try&lt;/span&gt; {
            Class&amp;lt;?&amp;gt; emmaRTClass = Class.forName(&lt;span class="String"&gt;"com.vladium.emma.rt.RT"&lt;/span&gt;);
            Method dumpCoverageMethod = emmaRTClass.getMethod(
                    &lt;span class="String"&gt;"dumpCoverageData"&lt;/span&gt;, coverageFile.getClass(), &lt;span class="Type"&gt;boolean&lt;/span&gt;.&lt;span class="Type"&gt;class&lt;/span&gt;,
                    &lt;span class="Type"&gt;boolean&lt;/span&gt;.&lt;span class="Type"&gt;class&lt;/span&gt;);
            dumpCoverageMethod.invoke(&lt;span class="Constant"&gt;null&lt;/span&gt;, coverageFile, &lt;span class="Boolean"&gt;false&lt;/span&gt;, &lt;span class="Boolean"&gt;false&lt;/span&gt;);
        } &lt;span class="Statement"&gt;catch&lt;/span&gt; (ClassNotFoundException e) {
            reportEmmaError(&lt;span class="String"&gt;"Is emma jar on classpath?"&lt;/span&gt;, e);
        } &lt;span class="Statement"&gt;catch&lt;/span&gt; (SecurityException e) {
            reportEmmaError(e);
        } &lt;span class="Statement"&gt;catch&lt;/span&gt; (NoSuchMethodException e) {
            reportEmmaError(e);
        } &lt;span class="Statement"&gt;catch&lt;/span&gt; (IllegalArgumentException e) {
            reportEmmaError(e);
        } &lt;span class="Statement"&gt;catch&lt;/span&gt; (IllegalAccessException e) {
            reportEmmaError(e);
        } &lt;span class="Statement"&gt;catch&lt;/span&gt; (InvocationTargetException e) {
            reportEmmaError(e);
        }
    }

    &lt;span class="Type"&gt;private&lt;/span&gt; String getCoverageFilePath() {
        &lt;span class="Statement"&gt;if&lt;/span&gt; (mCoverageFilePath == &lt;span class="Constant"&gt;null&lt;/span&gt;) {
            &lt;span class="Statement"&gt;return&lt;/span&gt; DEFAULT_COVERAGE_FILE_PATH;
        } &lt;span class="Statement"&gt;else&lt;/span&gt; {
            &lt;span class="Statement"&gt;return&lt;/span&gt; mCoverageFilePath;
        }
    }

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; reportEmmaError(Exception e) {
        reportEmmaError(&lt;span class="String"&gt;""&lt;/span&gt;, e);
    }

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; reportEmmaError(String hint, Exception e) {
        String msg = &lt;span class="String"&gt;"Failed to generate emma coverage. "&lt;/span&gt; + hint;
        Log.e(TAG, msg, e);
        mResults.putString(Instrumentation.REPORT_KEY_STREAMRESULT, &lt;span class="String"&gt;"&lt;/span&gt;&lt;span class="Special"&gt;\n&lt;/span&gt;&lt;span class="String"&gt;Error: "&lt;/span&gt;
                + msg);
    }

    &lt;span class="Comment"&gt;/* (non-Javadoc)&lt;/span&gt;
&lt;span class="Comment"&gt;     * @see com.example.instrumentation.FinishListener#onActivityFinished()&lt;/span&gt;
&lt;span class="Comment"&gt;     */&lt;/span&gt;
    &lt;span class="PreProc"&gt;@Override&lt;/span&gt;
    &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; onActivityFinished() {
        &lt;span class="Statement"&gt;if&lt;/span&gt; (LOGD)
            Log.d(TAG, &lt;span class="String"&gt;"onActivityFinished()"&lt;/span&gt;);
        &lt;span class="Statement"&gt;if&lt;/span&gt; (mCoverage) {
            generateCoverageReport();
        }
        finish(Activity.RESULT_OK, mResults);
    }

}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
We are also implementing the FinishListener interface, which is defined as
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="background-color: #fbfbfb; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;
&lt;span class="PreProc"&gt;package&lt;/span&gt; com.example.instrumentation;

&lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt; *&lt;/span&gt;&lt;span class="Special"&gt; Listen for an Activity to finish and invokes &lt;/span&gt;&lt;span class="Special"&gt;{@link #onActivityFinished()}&lt;/span&gt;&lt;span class="Special"&gt; when this happens.&lt;/span&gt;
&lt;span class="Comment"&gt; * &lt;/span&gt;
&lt;span class="Comment"&gt; * &lt;/span&gt;&lt;span class="Special"&gt;@author&lt;/span&gt;&lt;span class="Comment"&gt; diego&lt;/span&gt;
&lt;span class="Comment"&gt; *&lt;/span&gt;
&lt;span class="Comment"&gt; */&lt;/span&gt;
&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;interface&lt;/span&gt; FinishListener {

        &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;         *&lt;/span&gt;&lt;span class="Special"&gt; Invoked when the Activity finishes.&lt;/span&gt;
&lt;span class="Comment"&gt;         */&lt;/span&gt;
        &lt;span class="Type"&gt;void&lt;/span&gt; onActivityFinished();

}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Running the instrumented application

&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Once we have the EmmaInstrumentation class in place we need a few more adjustments to be able to get the coverage report of the running application.&lt;/div&gt;
&lt;div&gt;
Firstly, we need to add the new Activity to the manifest. Secondly, we should allow our application to write to the &lt;b&gt;sdcard&lt;/b&gt; if this is where we decided to generate the coverage report. To do it you should grant the&amp;nbsp;&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;android.permission.WRITE_EXTERNAL_STORAGE&lt;/span&gt;&lt;/b&gt; permission.&lt;/div&gt;
&lt;div&gt;
Then, it's time to build and install the instrumented apk:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;$ ant clean&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;$ ant instrument&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;$ ant installi&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Everything is ready to start the instrumented application&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;$ adb shell am instrument -e coverage true \&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;-w com.example.i2at.tc/\&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; com.example.instrumentation.EmmaInstrumentation&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
If everything went well, the Temperature Converter application will be running and we can use it for a while&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-tGfZnESRQEc/TsNUBTkYdzI/AAAAAAAABj4/II4vI90Blag/s1600/device-2011-11-16-011032.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-tGfZnESRQEc/TsNUBTkYdzI/AAAAAAAABj4/II4vI90Blag/s320/device-2011-11-16-011032.png" width="192" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
when we exit by pressing the &lt;b&gt;BACK&lt;/b&gt; button we can see that the coverage data was written to the file and reflected in the logcat&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;b&gt;I/System.out(2453): EMMA: runtime coverage data written to [/mnt/sdcard/coverage.ec] {in 975 ms}&lt;/b&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
this file can then be moved to the host computer using &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;adb pull&lt;/b&gt;&lt;/span&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Hope this helps you obtaining the code coverage for your application to help you understand its usage patterns. As always, comments and questions are always welcome.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-3961948815387938542?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/11/obtaining-code-coverage-of-running.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-tGfZnESRQEc/TsNUBTkYdzI/AAAAAAAABj4/II4vI90Blag/s72-c/device-2011-11-16-011032.png" height="72" width="72" /><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-8031336503349116937</guid><pubDate>Fri, 11 Nov 2011 04:31:00 +0000</pubDate><atom:updated>2011-11-11T00:43:50.606-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">chimpchat</category><category domain="http://www.blogger.com/atom/ns#">sdk</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">emulator</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">adb</category><title>Android: Using monkey from Java</title><description>&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;The latest version of the Android SDK and tools include &lt;b&gt;chimpchat&lt;/b&gt;, a library that facilitates the use of monkey from Java. This is equivalent to &lt;b&gt;monkeyrunner&lt;/b&gt;, which is the bridge between monkey and the Python scripting language.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;While Python is an&amp;nbsp;incredibly&amp;nbsp;powerful and&amp;nbsp;expressive&amp;nbsp;scripting language and will permit you creating tests with just a few statements, there are some&amp;nbsp;occasions&amp;nbsp;when you don't want to introduce a new language to the project leaving your Java confort zone or you prefer to leverage the use of previously created libraries instead of writing new ones.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;In such cases, you can now have the same access to monkey running on the device with the help of &lt;b&gt;chimpchat&lt;/b&gt;, as we are going to demonstrate.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; font-size: large;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;Creating a Java project&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;Our first step will be to create a new Java project and we will add the required libraries to the Java Build Path as External Jars.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;We are naming the project JavaMonkey, for obvious reasons.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-zwjopsDR1qs/TryrhiPI_XI/AAAAAAAABjc/ERqgw1Vr4Ow/s1600/Java+Build+Path.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="198" src="http://1.bp.blogspot.com/-zwjopsDR1qs/TryrhiPI_XI/AAAAAAAABjc/ERqgw1Vr4Ow/s320/Java+Build+Path.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;We are adding these libraries from Android SDK, which are used directly or indirectly by our project, to the Java Build Path:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;b&gt;chimpchat.jar&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;b&gt;ddmlib.jar&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;b&gt;guavalib.jar&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;b&gt;sdklib.jar&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; font-size: large;"&gt;JavaMonkey.java&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;Our intention is to create a simple class, serving the purpose of a simple example to get as started. We will be simply:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;Creating a JavaMonkey object&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;initializing it, this implies creating the connection with any emulator or device found or throwing an exception is not connection was made before the timeout expires&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;listing all the properties in the device or emulator&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;shutting down the connection&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;Following, is the &lt;b&gt;JavaMonkey&lt;/b&gt; class&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;:&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;style type="text/css"&gt;
&lt;!--
.Identifier { color: #458b74; }
.Statement { color: #b03060; font-weight: bold; }
.Constant { color: #ff8c00; }
.String { color: #4a708b; }
.Type { color: #008b00; font-weight: bold; }
.PreProc { color: #1874cd; }
.Special { color: #8a2be2; }
.Comment { color: #0000ee; font-style: italic; }
--&gt;
&lt;/style&gt;

&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="background-color: #fbfbfb; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;

&lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt; *&lt;/span&gt;&lt;span class="Special"&gt; Copyright (C) 2011  Diego Torres Milano&lt;/span&gt;
&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="PreProc"&gt;package&lt;/span&gt; com.example.javamonkey;

&lt;span class="PreProc"&gt;import&lt;/span&gt; java.util.TreeMap;

&lt;span class="PreProc"&gt;import&lt;/span&gt; com.android.chimpchat.ChimpChat;
&lt;span class="PreProc"&gt;import&lt;/span&gt; com.android.chimpchat.core.IChimpDevice;

&lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt; &lt;/span&gt;&lt;span class="Comment"&gt;* &lt;/span&gt;&lt;span class="Special"&gt;@author&lt;/span&gt;&lt;span class="Comment"&gt; diego&lt;/span&gt;
&lt;span class="Comment"&gt; *&lt;/span&gt;
&lt;span class="Comment"&gt; */&lt;/span&gt;
&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; JavaMonkey {

        &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; String ADB = &lt;span class="String"&gt;"/Users/diego/opt/android-sdk/platform-tools/adb"&lt;/span&gt;;
        &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; TIMEOUT = &lt;span class="Constant"&gt;5000&lt;/span&gt;;
        &lt;span class="Type"&gt;private&lt;/span&gt; ChimpChat mChimpchat;
        &lt;span class="Type"&gt;private&lt;/span&gt; IChimpDevice mDevice;

        &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;         *&lt;/span&gt;&lt;span class="Special"&gt; Constructor&lt;/span&gt;
&lt;span class="Special"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
        &lt;span class="Type"&gt;public&lt;/span&gt; JavaMonkey() {
                &lt;span class="Type"&gt;super&lt;/span&gt;();
        TreeMap&amp;lt;String, String&amp;gt; options = &lt;span class="Statement"&gt;new&lt;/span&gt; TreeMap&amp;lt;String, String&amp;gt;();
        options.put(&lt;span class="String"&gt;"backend"&lt;/span&gt;, &lt;span class="String"&gt;"adb"&lt;/span&gt;);
        options.put(&lt;span class="String"&gt;"adbLocation"&lt;/span&gt;, ADB);
        mChimpchat = ChimpChat.getInstance(options);
        }

        &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;         *&lt;/span&gt;&lt;span class="Special"&gt; Initializes the JavaMonkey.&lt;/span&gt;
&lt;span class="Comment"&gt;         */&lt;/span&gt;
        &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; init() {
                mDevice = mChimpchat.waitForConnection(TIMEOUT, &lt;span class="String"&gt;".*"&lt;/span&gt;);
                &lt;span class="Statement"&gt;if&lt;/span&gt; ( mDevice == &lt;span class="Constant"&gt;null&lt;/span&gt; ) {
                        &lt;span class="Statement"&gt;throw&lt;/span&gt; &lt;span class="Statement"&gt;new&lt;/span&gt; RuntimeException(&lt;span class="String"&gt;"Couldn't connect."&lt;/span&gt;);
                }
                mDevice.wake();
        }

        &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;         *&lt;/span&gt;&lt;span class="Special"&gt; List all properties.&lt;/span&gt;
&lt;span class="Comment"&gt;         */&lt;/span&gt;
        &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; listProperties() {
                &lt;span class="Statement"&gt;if&lt;/span&gt; ( mDevice == &lt;span class="Constant"&gt;null&lt;/span&gt; ) {
                        &lt;span class="Statement"&gt;throw&lt;/span&gt; &lt;span class="Statement"&gt;new&lt;/span&gt; IllegalStateException(&lt;span class="String"&gt;"init() must be called first."&lt;/span&gt;);
                }
                &lt;span class="Statement"&gt;for&lt;/span&gt; (String prop: mDevice.getPropertyList()) {
                        System.out.println(prop + &lt;span class="String"&gt;": "&lt;/span&gt; + mDevice.getProperty(prop));
                }
        }

        &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;         *&lt;/span&gt;&lt;span class="Special"&gt; Terminates this JavaMonkey.&lt;/span&gt;
&lt;span class="Comment"&gt;         */&lt;/span&gt;
        &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; shutdown() {
                mChimpchat.shutdown();
                mDevice = &lt;span class="Constant"&gt;null&lt;/span&gt;;
        }

        &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;         &lt;/span&gt;&lt;span class="Comment"&gt;* &lt;/span&gt;&lt;span class="Special"&gt;@param&lt;/span&gt;&lt;span class="Identifier"&gt; args&lt;/span&gt;
&lt;span class="Comment"&gt;         */&lt;/span&gt;
        &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; main(String[] args) {
                &lt;span class="Type"&gt;final&lt;/span&gt; JavaMonkey javaMonkey = &lt;span class="Statement"&gt;new&lt;/span&gt; JavaMonkey();
                javaMonkey.init();
                javaMonkey.listProperties();
                javaMonkey.shutdown();
        }

}

&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; font-size: large;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;Configuration&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;One of the important things you have to adapt to your environment is the location of the adb command. Otherwise if you don't set it you will receive:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="p1"&gt;
&lt;b&gt;E/adb: Failed to get the adb version: Cannot run program "adb": error=2, No such file or directory&lt;/b&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;Hope this helps you get started with &lt;b&gt;chimpchat&lt;/b&gt;. As always, comments and questions are always welcome.&lt;/span&gt;&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-8031336503349116937?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/11/android-using-monkey-from-java.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-zwjopsDR1qs/TryrhiPI_XI/AAAAAAAABjc/ERqgw1Vr4Ow/s72-c/Java+Build+Path.png" height="72" width="72" /><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-7261614934837723374</guid><pubDate>Thu, 03 Nov 2011 18:25:00 +0000</pubDate><atom:updated>2011-11-11T00:47:06.094-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AATG</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><title>Android Application Testing Guide: Q&amp;A</title><description>&lt;span class="first"&gt;Q:&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;
Hi Diego, I wanted to ask that can i write a monkey runner script which controls a web based apk ?&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;Eg; I install &lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; color: #333333; line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;youtube.apk&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt; which is nothing but a browser with hardcoded youtube url.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;Now my &lt;b&gt;monkeyrunner&lt;/b&gt; script shall install this apk and then pass events such as a search string etc on this web based application.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;All this i want to do and control externally through the monkey runner script. Is this possible? If yes, then could you please guide me by some pseudo code?&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;Comment on &lt;a href="http://dtmilano.blogspot.com/2011/03/using-android-monkeyrunner-from-eclipse.html?showComment=1317358675751#c6426792505323535040"&gt;Using Android monkeyrunner from Eclipse&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: right;"&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;i&gt;Posted by&amp;nbsp;latha&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span class="first"&gt;A:&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;
This is an interesting question and a good monkeyrunner example, so here we go. &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;monkeyrunner&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt; has the ability of installing APKs after obtaining the connection with the device. Then we start &lt;b&gt;Youtube&lt;/b&gt; main activity, sleep for a bit to let things settle down.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;Once we have the activity running is time to start our search. To do it, we touch the &lt;b&gt;Search&lt;/b&gt; icon, enter the desired search string, 'android' in this particular case and the we touch the &lt;b&gt;Search&lt;/b&gt; button again to actually start the action.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;Following, is the script that translates our plan to &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;monkeyrunner&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;:&lt;/span&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="background-color: #fbfbfb; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;
&lt;span class="Comment"&gt;#! /usr/bin/env monkeyrunner&lt;/span&gt;

&lt;span class="PreProc"&gt;import&lt;/span&gt; sys
&lt;span class="PreProc"&gt;import&lt;/span&gt; os
&lt;span class="PreProc"&gt;from&lt;/span&gt; com.android.monkeyrunner &lt;span class="PreProc"&gt;import&lt;/span&gt; MonkeyRunner, MonkeyDevice

YOUTUBE = &lt;span class="String"&gt;'com.google.android.youtube-2.1.6.apk'&lt;/span&gt;
prog = os.path.basename(sys.argv[&lt;span class="Constant"&gt;0&lt;/span&gt;])

&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;usage&lt;/span&gt;():
        &lt;span class="Identifier"&gt;print&lt;/span&gt; &amp;gt;&amp;gt;sys.stderr, &lt;span class="String"&gt;"usage: %s"&lt;/span&gt; % prog
        sys.exit(&lt;span class="Constant"&gt;1&lt;/span&gt;)

&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;main&lt;/span&gt;():
        &lt;span class="Statement"&gt;if&lt;/span&gt; &lt;span class="Identifier"&gt;len&lt;/span&gt;(sys.argv) != &lt;span class="Constant"&gt;1&lt;/span&gt;:
                usage()

        &lt;span class="Identifier"&gt;print&lt;/span&gt; &lt;span class="String"&gt;"waiting for connection..."&lt;/span&gt;
        device = MonkeyRunner.waitForConnection()

        &lt;span class="Identifier"&gt;print&lt;/span&gt; &lt;span class="String"&gt;"installing youtube"&lt;/span&gt;
        device.installPackage(YOUTUBE)

        device.startActivity(component=&lt;span class="String"&gt;"com.google.android.youtube/.HomeActivity"&lt;/span&gt;)
        MonkeyRunner.sleep(&lt;span class="Constant"&gt;3&lt;/span&gt;)
        &lt;span class="Comment"&gt;# search&lt;/span&gt;
        device.touch(&lt;span class="Constant"&gt;450&lt;/span&gt;, &lt;span class="Constant"&gt;80&lt;/span&gt;, MonkeyDevice.DOWN_AND_UP)
        MonkeyRunner.sleep(&lt;span class="Constant"&gt;5&lt;/span&gt;)
        device.&lt;span class="Identifier"&gt;type&lt;/span&gt;(&lt;span class="String"&gt;'android'&lt;/span&gt;)
        &lt;span class="Comment"&gt;# done&lt;/span&gt;
        device.touch(&lt;span class="Constant"&gt;450&lt;/span&gt;, &lt;span class="Constant"&gt;740&lt;/span&gt;, MonkeyDevice.DOWN_AND_UP)



&lt;span class="Statement"&gt;if&lt;/span&gt; __name__ == &lt;span class="String"&gt;'__main__'&lt;/span&gt;:
    main()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;This script covers the case described in the question but it could be easily adapted for other cases and application.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;I hope this is the answer you were looking for.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-7261614934837723374?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/11/android-application-testing-guide-q.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4508741383040053480</guid><pubDate>Sat, 01 Oct 2011 04:09:00 +0000</pubDate><atom:updated>2011-10-01T00:09:50.267-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><title>Android Application Testing Guide: Q&amp;A</title><description>&lt;span class="first"&gt;Q:&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;i am working on android on automation i have setup all the environment required for it like(eclipse,jdk, Android SDk) and i am having monkeyrunner installed.&lt;br /&gt;&lt;br /&gt;Now i want to automate the process to do this task--The monkeyrunner API can apply one or more test&lt;br /&gt;suites across multiple devices or emulators. You can physically attach all the&lt;br /&gt;devices or start up all the emulators (or both) at once, connect to each one in&lt;br /&gt;turn programmatically, and then run one or more tests&lt;br /&gt;&lt;br /&gt;i thought of doing this through monkeyrunner extending plugins concept, this concept doesn't help me becoz communicaton between two or more plugins creating a new problem. so ,please help me how to get my task done through other approach&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: right;"&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;i&gt;Posted by&amp;nbsp;vijju&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif; line-height: 18px;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;
&lt;span class="first"&gt;A:&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; color: #333333;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;Probably the best solution to your problem is based on the &lt;/span&gt;&lt;i style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;divide and conquer&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&amp;nbsp;philosophy. Create your test scripts in a way that they receive a serial number argument to determine which device to connect to. The following is a very simple example of this concept. We will call it &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;getprop.mr&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;
&lt;span class="Comment"&gt;#! /usr/bin/env monkeyrunner&lt;/span&gt;

&lt;span class="PreProc"&gt;import&lt;/span&gt; sys, os
&lt;span class="PreProc"&gt;from&lt;/span&gt; com.android.monkeyrunner &lt;span class="PreProc"&gt;import&lt;/span&gt; MonkeyRunner

prog = os.path.basename(sys.argv[&lt;span class="Constant"&gt;0&lt;/span&gt;])

&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;usage&lt;/span&gt;():
        &lt;span class="Identifier"&gt;print&lt;/span&gt; &amp;gt;&amp;gt;sys.stderr, &lt;span class="String"&gt;"usage: %s serial-no"&lt;/span&gt; % prog
        sys.exit(&lt;span class="Constant"&gt;1&lt;/span&gt;)

&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;main&lt;/span&gt;():
        &lt;span class="Statement"&gt;if&lt;/span&gt; &lt;span class="Identifier"&gt;len&lt;/span&gt;(sys.argv) != &lt;span class="Constant"&gt;2&lt;/span&gt;:
                usage()

        serialno = sys.argv[&lt;span class="Constant"&gt;1&lt;/span&gt;]
        &lt;span class="Identifier"&gt;print&lt;/span&gt; &lt;span class="String"&gt;"waiting for connection to %s..."&lt;/span&gt; % serialno
        device = MonkeyRunner.waitForConnection(&lt;span class="Constant"&gt;30&lt;/span&gt;, serialno)

        s = &lt;span class="String"&gt;""&lt;/span&gt;
        &lt;span class="Statement"&gt;for&lt;/span&gt; p &lt;span class="Statement"&gt;in&lt;/span&gt; [&lt;span class="String"&gt;'build.manufacturer'&lt;/span&gt;, &lt;span class="String"&gt;'build.device'&lt;/span&gt;, &lt;span class="String"&gt;'build.model'&lt;/span&gt;]:
                s += &lt;span class="String"&gt;" "&lt;/span&gt; + device.getProperty(p)
        &lt;span class="Identifier"&gt;print&lt;/span&gt; s

&lt;span class="Statement"&gt;if&lt;/span&gt; __name__ == &lt;span class="String"&gt;'__main__'&lt;/span&gt;:
    main()

&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;This script expects the first argument to be the serial number of the emulator or device where the specific tests will be run. In this simple case we are just obtaining some properties to identify it.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;Once we have our test script we need a driver to run it in every device we specify. In this example we will be using a python script but a bash script would be good enough.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;
&lt;span class="Comment"&gt;#! /usr/bin/env python&lt;/span&gt;

&lt;span class="PreProc"&gt;import&lt;/span&gt; os

devices = [ &lt;span class="String"&gt;'XXX00000001'&lt;/span&gt;, &lt;span class="String"&gt;'emulator-5554'&lt;/span&gt; ]
cmd = &lt;span class="String"&gt;'getprop.mr'&lt;/span&gt;

&lt;span class="Statement"&gt;for&lt;/span&gt; d &lt;span class="Statement"&gt;in&lt;/span&gt; devices:
        os.system(cmd + &lt;span class="String"&gt;" "&lt;/span&gt; + d)

&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;This script will run the test, getprop.mr in this case, for each of the devices which serial numbers are in the list.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'Trebuchet MS', Verdana, Arial, sans-serif;"&gt;&lt;span class="Apple-style-span" style="line-height: 18px;"&gt;I hope this is the answer you were looking for.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-4508741383040053480?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/10/android-application-testing-guide-q.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-7546000981851205735</guid><pubDate>Thu, 08 Sep 2011 04:04:00 +0000</pubDate><atom:updated>2011-09-08T00:04:01.983-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">instrumentation</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">adb</category><title>Android Testing: Running tests from code</title><description>&lt;style type="text/css"&gt;
&lt;!--
span.first {
   float: left;
   font-family: Old English, Georgia,serif;
   font-size: 300%;
   line-height: 0.85em;
   margin-right: 0.03em;
   margin-bottom:-0.25em;
   }

.prettyprint {
   background-color: #fafafa;
   border-bottom-color: rgb(204, 204, 204);
   border-bottom-style: solid;
   border-bottom-width: 1px;
   border-left-color: rgb(204, 204, 204);
   border-left-style: solid;
   border-left-width: 1px;
   border-right-color: rgb(204, 204, 204);
   border-right-style: solid;
   border-right-width: 1px;
   border-top-color: rgb(204, 204, 204);
   border-top-style: solid; border-top-width: 1px;
   margin-bottom: 1em;
   margin-left: 1em;
   margin-right: 0px;
   margin-top: 0px;
   overflow-x: auto;
   overflow-y: auto;
   padding-bottom: 10px;
   padding-left: 10px;
   padding-right: 10px;
   padding-top: 10px;
   line-height:1.0em;
   }
.Boolean { color: #cd0000; }
.Statement { color: #b03060; font-weight: bold; }
.Identifier { color: #458b74; }
.Constant { color: #ff8c00; }
.String { color: #4a708b; }
.Type { color: #008b00; font-weight: bold; }
.PreProc { color: #1874cd; }
.Special { color: #8a2be2; }
.Comment { color: #0000ee; font-style: italic; }
--&gt;
&lt;/style&gt;&lt;br /&gt;
I was answering some questions at &lt;a href="http://stackoverflow.com/questions"&gt;StackOverflow&lt;/a&gt; today and one caught my attention. It was asking, well, not directly but I understood this was the intention, how to run the tests not from another computer using &lt;b&gt;adb&lt;/b&gt; or &lt;b&gt;Eclipse&lt;/b&gt; but from an android application itself. Then, here we are presenting a solution to run instrumentation from code.

&lt;br/&gt;
&lt;br/&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;

&lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; runTests() {
   &lt;span class="Type"&gt;final&lt;/span&gt; String packageName = getPackageName();
   &lt;span class="Type"&gt;final&lt;/span&gt; List&amp;lt;InstrumentationInfo&amp;gt; list = 
         getPackageManager().queryInstrumentation(packageName, &lt;span class="Constant"&gt;0&lt;/span&gt;);
   &lt;span class="Statement"&gt;if&lt;/span&gt; ( list.isEmpty() ) {
      Toast.makeText(&lt;span class="Type"&gt;this&lt;/span&gt;, &lt;span class="String"&gt;&amp;quot;Cannot find instrumentation for &amp;quot;&lt;/span&gt; + packageName,
         Toast.LENGTH_SHORT).show();
      &lt;span class="Statement"&gt;return&lt;/span&gt;;
   }
   &lt;span class="Type"&gt;final&lt;/span&gt; InstrumentationInfo instrumentationInfo = list.get(&lt;span class="Constant"&gt;0&lt;/span&gt;);
   &lt;span class="Type"&gt;final&lt;/span&gt; ComponentName componentName = 
         &lt;span class="Statement"&gt;new&lt;/span&gt; ComponentName(instrumentationInfo.packageName,
         instrumentationInfo.name);
   &lt;span class="Statement"&gt;if&lt;/span&gt; ( !startInstrumentation(componentName, &lt;span class="Constant"&gt;null&lt;/span&gt;, &lt;span class="Constant"&gt;null&lt;/span&gt;) ) {
      Toast.makeText(&lt;span class="Type"&gt;this&lt;/span&gt;, &lt;span class="String"&gt;&amp;quot;Cannot run instrumentation for &amp;quot;&lt;/span&gt; + packageName,
         Toast.LENGTH_SHORT).show();
   }
}

&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;

You need a valid context to call &lt;tt&gt;startInstrumentation()&lt;/tt&gt; so this is probably added to an Activity.
&lt;br/&gt;
&lt;br/&gt;
I can imagine only a valid use case for this, which is running the tests when you don't have the device connected to a computer.
&lt;br/&gt;
Do you have another use case ?
&lt;br/&gt;
Speak out.
&lt;br/&gt;
&lt;br/&gt;
Hope this helps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-7546000981851205735?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/09/android-testing-running-tests-from-code.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-2170587665048692209</guid><pubDate>Sat, 27 Aug 2011 01:22:00 +0000</pubDate><atom:updated>2011-08-26T21:22:17.582-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AATG</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">android</category><title>Android Application Testing Guide: Q&amp;A</title><description>&lt;style type="text/css"&gt;
&lt;!--
span.first {
   float: left;
   font-family: Old English, Georgia,serif;
   font-size: 300%;
   line-height: 0.85em;
   margin-right: 0.03em;
   margin-bottom:-0.25em;
   }

.prettyprint {
   background-color: #fafafa;
   border-bottom-color: rgb(204, 204, 204);
   border-bottom-style: solid;
   border-bottom-width: 1px;
   border-left-color: rgb(204, 204, 204);
   border-left-style: solid;
   border-left-width: 1px;
   border-right-color: rgb(204, 204, 204);
   border-right-style: solid;
   border-right-width: 1px;
   border-top-color: rgb(204, 204, 204);
   border-top-style: solid; border-top-width: 1px;
   margin-bottom: 1em;
   margin-left: 1em;
   margin-right: 0px;
   margin-top: 0px;
   overflow-x: auto;
   overflow-y: auto;
   padding-bottom: 10px;
   padding-left: 10px;
   padding-right: 10px;
   padding-top: 10px;
   line-height:1.0em;
   }
.Boolean { color: #cd0000; }
.Statement { color: #b03060; font-weight: bold; }
.Identifier { color: #458b74; }
.Constant { color: #ff8c00; }
.String { color: #4a708b; }
.Type { color: #008b00; font-weight: bold; }
.PreProc { color: #1874cd; }
.Special { color: #8a2be2; }
.Comment { color: #0000ee; font-style: italic; }
--&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;span class="first"&gt;Q:&lt;/span&gt;I followed your example. I set up the test project in a similar way.&lt;br /&gt;
But try to write a &lt;b&gt;TestCase&lt;/b&gt; for the utility class from the original&lt;br /&gt;
project.&lt;br /&gt;
Eclipse says "Class under test does not exist in the current project."&lt;br /&gt;
&lt;br /&gt;
It's kind of reasonable to me, since that class is indeed in another&lt;br /&gt;
project.&lt;br /&gt;
I only have experienced using &lt;b&gt;JUnit&lt;/b&gt; to test normal Java Project where&lt;br /&gt;
the test directory is inside the project.&lt;br /&gt;
&lt;br /&gt;
Also, I checked out the two example projects and found there is a&lt;br /&gt;
build.properties and build.xml. Is that the reason that you can import&lt;br /&gt;
the original class:&lt;br /&gt;
"&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;import com.example.i2at.tc.TemperatureConverter;&lt;/span&gt;"?&lt;br /&gt;
&lt;br /&gt;
Thanks&lt;br /&gt;
&lt;br /&gt;
Best wishes,&lt;br /&gt;
Ryan&lt;br /&gt;
&lt;div style="align: right;"&gt;&lt;div style="text-align: right;"&gt;&lt;i&gt;Posted by Ryan Huang.&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;span class="first"&gt;A:&lt;/span&gt;If you have imported both projects (main &amp;amp; test) into Eclipse you should have no problems because the versions&amp;nbsp;available&amp;nbsp;at &lt;a href="https://github.com/dtmilano"&gt;github&lt;/a&gt;&amp;nbsp;have the required properties set.&lt;br /&gt;
However, if for some reason they were not set properly, this is what you should verify in your test project's &lt;b&gt;&lt;i&gt;Java Build Path -&amp;gt; Libraries&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-G53h3EyWn74/Tlg5WOAA2tI/AAAAAAAABdQ/REFFGM43vaU/s1600/Properties-for-TemperatureConverterTest.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="272" src="http://1.bp.blogspot.com/-G53h3EyWn74/Tlg5WOAA2tI/AAAAAAAABdQ/REFFGM43vaU/s400/Properties-for-TemperatureConverterTest.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="first"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The other files you mentioned are used when you build with &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ant&lt;/span&gt;&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-2170587665048692209?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/08/android-application-testing-guide-q_26.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-G53h3EyWn74/Tlg5WOAA2tI/AAAAAAAABdQ/REFFGM43vaU/s72-c/Properties-for-TemperatureConverterTest.png" height="72" width="72" /><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4246447549585830941</guid><pubDate>Thu, 18 Aug 2011 22:04:00 +0000</pubDate><atom:updated>2011-08-18T18:04:43.256-04:00</atom:updated><title>LinuxCon 2011 North America: Introduction to Android Testing</title><description>It was terrific having such a great audience showing a big interest in the topic of my tutorial, asking questions and starting discussions that made the presentation more enjoyable. I really want to thank you all.&lt;br /&gt;
&lt;br /&gt;
For those who missed it, here are the slides that should be available at the Linux Foundation web site any time soon too.&lt;br /&gt;
&lt;br /&gt;
&lt;div align="center"&gt;&lt;div align="center" style="width:425px;" id="__ss_8908484"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/dtmilano/introduction-to-android-testing" title="Introduction to android testing"&gt;Introduction to android testing&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse8908484" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=introductiontoandroidtesting-110818162813-phpapp01&amp;stripped_title=introduction-to-android-testing&amp;userName=dtmilano" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed name="__sse8908484" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=introductiontoandroidtesting-110818162813-phpapp01&amp;stripped_title=introduction-to-android-testing&amp;userName=dtmilano" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/dtmilano"&gt;dtmilano&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-4246447549585830941?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/08/linuxcon-2011-north-america.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4693075530624599417</guid><pubDate>Fri, 05 Aug 2011 06:17:00 +0000</pubDate><atom:updated>2011-08-05T02:17:07.620-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">webview</category><category domain="http://www.blogger.com/atom/ns#">mock</category><category domain="http://www.blogger.com/atom/ns#">AATG</category><category domain="http://www.blogger.com/atom/ns#">junit</category><title>Android Application Testing Guide: Q&amp;A</title><description>&lt;style type="text/css"&gt;
&lt;!--
span.first {
   float: left;
   font-family: Old English, Georgia,serif;
   font-size: 300%;
   line-height: 0.85em;
   margin-right: 0.03em;
   margin-bottom:-0.25em;
   }

.prettyprint {
   background-color: #fafafa;
   border-bottom-color: rgb(204, 204, 204);
   border-bottom-style: solid;
   border-bottom-width: 1px;
   border-left-color: rgb(204, 204, 204);
   border-left-style: solid;
   border-left-width: 1px;
   border-right-color: rgb(204, 204, 204);
   border-right-style: solid;
   border-right-width: 1px;
   border-top-color: rgb(204, 204, 204);
   border-top-style: solid; border-top-width: 1px;
   margin-bottom: 1em;
   margin-left: 1em;
   margin-right: 0px;
   margin-top: 0px;
   overflow-x: auto;
   overflow-y: auto;
   padding-bottom: 10px;
   padding-left: 10px;
   padding-right: 10px;
   padding-top: 10px;
   line-height:1.0em;
   }
.Boolean { color: #cd0000; }
.Statement { color: #b03060; font-weight: bold; }
.Identifier { color: #458b74; }
.Constant { color: #ff8c00; }
.String { color: #4a708b; }
.Type { color: #008b00; font-weight: bold; }
.PreProc { color: #1874cd; }
.Special { color: #8a2be2; }
.Comment { color: #0000ee; font-style: italic; }
--&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;span class="first"&gt;Q:&lt;/span&gt;Diego, if we were to test something that is asynchronous, like in my case I'm wanting to test if a webview loads an URL how would I go about waiting for the webpage to finish loading in my webview ?&lt;br /&gt;
&lt;div style="align: right;"&gt;&lt;div style="text-align: right;"&gt;&lt;i&gt;Posted by Pedro Veloso.&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;span class="first"&gt;A:&lt;/span&gt;Actually this is a very interesting question as there are many ways and you should be cautious about&amp;nbsp;&lt;a href="http://developer.android.com/reference/android/webkit/WebView.html"&gt;WebView&lt;/a&gt; semantics and how some of the &lt;a href="http://developer.android.com/reference/android/webkit/WebViewClient.html"&gt;WebViewClient&lt;/a&gt; methods are called.&lt;br /&gt;
&lt;br /&gt;
For example &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;onPageFinished&lt;/b&gt;&lt;/span&gt; may be invoked wether the page was successfully loaded or there was an error. So, you may need a different approach if your intention is to test if an url was successfully loaded.&lt;br /&gt;
&lt;br /&gt;
In this code snippet I'm using a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;MockWebViewClient&lt;/b&gt;&lt;/span&gt; to detect error conditions and simply waiting some time for the page to load. We could also iterate over a period of time checking if the value has changed instead of just waiting but we are keeping this as simple as possible. This is also assuming you have an &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Activity&lt;/span&gt;&lt;/b&gt; holding the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;WebView&lt;/b&gt;&lt;/span&gt; and it has the required getters.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;
&lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt; *&lt;/span&gt;&lt;span class="Special"&gt; &lt;/span&gt;
&lt;span class="Special"&gt; &lt;/span&gt;&lt;span class="Comment"&gt;*/&lt;/span&gt;
&lt;span class="PreProc"&gt;package&lt;/span&gt; com.example.aatg.webview.test;

&lt;span class="PreProc"&gt;import&lt;/span&gt; android.test.ActivityInstrumentationTestCase2;
&lt;span class="PreProc"&gt;import&lt;/span&gt; android.test.suitebuilder.annotation.Suppress;
&lt;span class="PreProc"&gt;import&lt;/span&gt; android.webkit.WebView;
&lt;span class="PreProc"&gt;import&lt;/span&gt; android.webkit.WebViewClient;

&lt;span class="PreProc"&gt;import&lt;/span&gt; com.example.aatg.webview.AndroidHelloWebViewActivity;

&lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt; &lt;/span&gt;&lt;span class="Comment"&gt;* &lt;/span&gt;&lt;span class="Special"&gt;@author&lt;/span&gt;&lt;span class="Comment"&gt; diego&lt;/span&gt;
&lt;span class="Comment"&gt; *&lt;/span&gt;
&lt;span class="Comment"&gt; */&lt;/span&gt;
&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; AndroidHelloWebViewActivityTests &lt;span class="Type"&gt;extends&lt;/span&gt;
        ActivityInstrumentationTestCase2&amp;lt;AndroidHelloWebViewActivity&amp;gt; {

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; String VALID_URL = &lt;span class="String"&gt;"&lt;a href="http://developer.android.com/"&gt;http://developer.android.com&lt;/a&gt;"&lt;/span&gt;;
    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; String INVALID_URL = &lt;span class="String"&gt;"&lt;a href="http://invalid.url.doesnotexist987.com/"&gt;http://invalid.url.doesnotexist987.com&lt;/a&gt;"&lt;/span&gt;;

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; &lt;span class="Type"&gt;long&lt;/span&gt; TIMEOUT = &lt;span class="Constant"&gt;5000&lt;/span&gt;;

    &lt;span class="Type"&gt;private&lt;/span&gt; AndroidHelloWebViewActivity mActivity;
    &lt;span class="Type"&gt;private&lt;/span&gt; WebView mWebView;
    &lt;span class="Type"&gt;private&lt;/span&gt; MockWebViewClient mMockWebViewClient;

    &lt;span class="Comment"&gt;/**&lt;/span&gt;
&lt;span class="Comment"&gt;     &lt;/span&gt;&lt;span class="Comment"&gt;* &lt;/span&gt;&lt;span class="Special"&gt;@param&lt;/span&gt;&lt;span class="Identifier"&gt; name&lt;/span&gt;
&lt;span class="Comment"&gt;     */&lt;/span&gt;
    &lt;span class="Type"&gt;public&lt;/span&gt; AndroidHelloWebViewActivityTests() {
        &lt;span class="Type"&gt;super&lt;/span&gt;(AndroidHelloWebViewActivity.&lt;span class="Type"&gt;class&lt;/span&gt;);
    }

    &lt;span class="Comment"&gt;/* (non-Javadoc)&lt;/span&gt;
&lt;span class="Comment"&gt;     * @see android.test.ActivityInstrumentationTestCase2#setUp()&lt;/span&gt;
&lt;span class="Comment"&gt;     */&lt;/span&gt;
    &lt;span class="Type"&gt;protected&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; setUp() &lt;span class="Type"&gt;throws&lt;/span&gt; Exception {
        &lt;span class="Type"&gt;super&lt;/span&gt;.setUp();
        mActivity = getActivity();
        mWebView = mActivity.getWebView();
        mMockWebViewClient = &lt;span class="Statement"&gt;new&lt;/span&gt; MockWebViewClient();
        mWebView.setWebViewClient(mMockWebViewClient);
    }

    &lt;span class="Comment"&gt;/* (non-Javadoc)&lt;/span&gt;
&lt;span class="Comment"&gt;     * @see android.test.ActivityInstrumentationTestCase2#tearDown()&lt;/span&gt;
&lt;span class="Comment"&gt;     */&lt;/span&gt;
    &lt;span class="Type"&gt;protected&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; tearDown() &lt;span class="Type"&gt;throws&lt;/span&gt; Exception {
        &lt;span class="Type"&gt;super&lt;/span&gt;.tearDown();
    }

    &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; testLoadValidUrl() {
        assertLoadUrl(VALID_URL);
        assertFalse(mMockWebViewClient.mError);
    }

    &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;final&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; testLoadInvalidUrl() {
        assertLoadUrl(INVALID_URL);
        assertTrue(mMockWebViewClient.mError);
    }

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; assertLoadUrl(String url) {
        mWebView.loadUrl(url);
        sleep();
        assertTrue(!(mWebView.getProgress() &amp;lt; &lt;span class="Constant"&gt;100&lt;/span&gt;));
    }

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; sleep() {
        &lt;span class="Statement"&gt;try&lt;/span&gt; {
            Thread.sleep(TIMEOUT);
        } &lt;span class="Statement"&gt;catch&lt;/span&gt; (InterruptedException e) {
            fail(&lt;span class="String"&gt;"Unexpected timeout"&lt;/span&gt;);
        }
    }

    &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; MockWebViewClient &lt;span class="Type"&gt;extends&lt;/span&gt; WebViewClient {
        &lt;span class="Type"&gt;boolean&lt;/span&gt; mError;

        &lt;span class="PreProc"&gt;@Override&lt;/span&gt;
        &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; onReceivedError(WebView view, &lt;span class="Type"&gt;int&lt;/span&gt; errorCode,
                String description, String failingUrl) {
            mError = &lt;span class="Boolean"&gt;true&lt;/span&gt;;
        }
    }
}
&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
Hope this helps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-4693075530624599417?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/08/android-application-testing-guide-q_05.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4491241648374674116</guid><pubDate>Wed, 03 Aug 2011 03:59:00 +0000</pubDate><atom:updated>2011-08-02T23:59:35.965-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">AATG</category><title>Android Application Testing Guide: Q&amp;A</title><description>Lately I've been receiving some comments or questions about some of the &lt;a href="http://www.packtpub.com/android-application-testing-guide/book"&gt;book&lt;/a&gt;'s subjects in my email. To help the community the best I think that is preferable that you share your questions here, as comments to this post if you cannot find a post dealing with the same topic. If possible I will answer also here for the benefit of all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-4491241648374674116?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/08/android-application-testing-guide-q.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-2041779298702223196</guid><pubDate>Fri, 08 Jul 2011 20:57:00 +0000</pubDate><atom:updated>2011-07-08T16:58:49.398-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><category domain="http://www.blogger.com/atom/ns#">junit</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">presentation</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><category domain="http://www.blogger.com/atom/ns#">emma</category><title>Eclipse, Android and EMMA code coverage</title><description>On of the examples I'm including in the tutorial I will be presenting at &lt;a href="http://dtmilano.blogspot.com/2011/06/save-date-android-testing-at-linuxcon.html"&gt;LinuxCon North America 2011&lt;/a&gt; is a step by step use of &lt;a href="http://emma.sourceforge.net/"&gt;EMMA code coverage&lt;/a&gt; from Eclipse to help you navigate through the Android application source code while applying &lt;b&gt;Test Driven Development&lt;/b&gt; techniques.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-PX4hXsnSuic/ThdsLKpmBFI/AAAAAAAABXY/oON37X7dKUc/s1600/eclipse-android-emma.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="193" src="http://4.bp.blogspot.com/-PX4hXsnSuic/ThdsLKpmBFI/AAAAAAAABXY/oON37X7dKUc/s320/eclipse-android-emma.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
This screenshot, taken from the tutorial examples, shows:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;The code coverage results directly summarized and highlighted in the Activity source code inside Eclipse editor&lt;/li&gt;
&lt;li&gt;The coverage view lists coverage summaries for the Android project, allowing drill-down to method level&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;If you are seriously developing Android applications you shouldn't miss this tutorial.&lt;/div&gt;&lt;div&gt;Hope to see you there.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-2041779298702223196?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/07/eclipse-android-and-emma-code-coverage.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-PX4hXsnSuic/ThdsLKpmBFI/AAAAAAAABXY/oON37X7dKUc/s72-c/eclipse-android-emma.png" height="72" width="72" /><thr:total>8</thr:total><georss:featurename>Vancouver, BC, Canada</georss:featurename><georss:point>49.261226 -123.1139268</georss:point><georss:box>49.2016675 -123.2147628 49.3207845 -123.0130908</georss:box></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4913337035449650702</guid><pubDate>Fri, 24 Jun 2011 05:07:00 +0000</pubDate><atom:updated>2011-06-24T01:07:00.188-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><title>Using Android monkeyrunner to automate test steps</title><description>It is not unlikely that in writing your tests you discover that some simple steps are required by several tests.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;monkeyrunner&lt;/span&gt; is a great tool in this respect because it offers a tremendously powerful and complete language like python.&lt;br /&gt;
You can write your tests using python but also you can build libraries containing primitives belonging to the test domain.&lt;br /&gt;
This example shows how you can &lt;b&gt;lock&lt;/b&gt; and &lt;b&gt;unlock&lt;/b&gt; the device screen. Usually this methods should be in a different class or module but for the sake of simplicity we are including &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;lockDevice()&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;unlockDevice()&lt;/span&gt; here in the main script.&lt;br /&gt;
&lt;br /&gt;
&lt;style type="text/css"&gt;
&lt;!--
.prettyprint {
   background-color: #fafafa;
   border-bottom-color: rgb(204, 204, 204);
   border-bottom-style: solid;
   border-bottom-width: 1px;
   border-left-color: rgb(204, 204, 204);
   border-left-style: solid;
   border-left-width: 1px;
   border-right-color: rgb(204, 204, 204);
   border-right-style: solid;
   border-right-width: 1px;
   border-top-color: rgb(204, 204, 204);
   border-top-style: solid; border-top-width: 1px;
   margin-bottom: 1em;
   margin-left: 1em;
   margin-right: 0px;
   margin-top: 0px;
   overflow-x: auto;
   overflow-y: auto;
   padding-bottom: 10px;
   padding-left: 10px;
   padding-right: 10px;
   padding-top: 10px; }
.Constant { color: #880000; }
.Identifier { color: #000000; font-weight: bold; }
.Statement { color: #0000cc; }
.PreProc { color: #0000cc; }
.String { color: #008800; }
.Comment { color: #cccccc; font-style: italic; }
.Doc { color: #008800; font-style: italic; }
--&gt;
&lt;/style&gt;&lt;br /&gt;
&lt;pre class="prettyprint"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="font-family: monospace;"&gt;&lt;span class="Comment"&gt;#! /usr/bin/env monkeyrunner&lt;/span&gt;
&lt;span class="Doc"&gt;'''&lt;/span&gt;
&lt;span class="Doc"&gt;Created on Jun 22, 2011&lt;/span&gt;

&lt;span class="Doc"&gt;@author: diego&lt;/span&gt;
&lt;span class="Doc"&gt;'''&lt;/span&gt;

&lt;span class="PreProc"&gt;from&lt;/span&gt; com.android.monkeyrunner &lt;span class="PreProc"&gt;import&lt;/span&gt; MonkeyRunner, MonkeyDevice


&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;lockDevice&lt;/span&gt;(device):
    &lt;span class="Statement"&gt;return&lt;/span&gt; device.press(&lt;span class="String"&gt;"POWER"&lt;/span&gt;, MonkeyDevice.DOWN_AND_UP)


&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;unlockDevice&lt;/span&gt;(device):
    device.wake()
    device.drag((&lt;span class="Constant"&gt;130&lt;/span&gt;, &lt;span class="Constant"&gt;620&lt;/span&gt;), (&lt;span class="Constant"&gt;350&lt;/span&gt;, &lt;span class="Constant"&gt;620&lt;/span&gt;), &lt;span class="Constant"&gt;1.0&lt;/span&gt;, &lt;span class="Constant"&gt;120&lt;/span&gt;)

&lt;span class="Statement"&gt;def&lt;/span&gt; &lt;span class="Identifier"&gt;main&lt;/span&gt;():
    device = MonkeyRunner.waitForConnection()
    &lt;span class="Statement"&gt;if&lt;/span&gt; device:
        lockDevice(device)
        MonkeyRunner.sleep(&lt;span class="Constant"&gt;5.0&lt;/span&gt;)
        unlockDevice(device)

&lt;span class="Statement"&gt;if&lt;/span&gt; __name__ == &lt;span class="String"&gt;'__main__'&lt;/span&gt;:
    main()
&lt;/span&gt;&lt;/span&gt;
&lt;/pre&gt;Now, a demonstration of this script running on a Nexus One, locking, waking up, and unlocking the screen.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object width="320" height="266" class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/fTdSrtr_-5Y/0.jpg"&gt;&lt;param name="movie" value="http://www.youtube.com/v/fTdSrtr_-5Y?f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="320" height="266"  src="http://www.youtube.com/v/fTdSrtr_-5Y?f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Hope this helps you start creating you &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;monkeyrunner&lt;/span&gt; libraries.&lt;br /&gt;
Comments are welcome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-4913337035449650702?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/06/using-android-monkeyrunner-to-automate.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>7</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-229821337342459086</guid><pubDate>Mon, 20 Jun 2011 00:17:00 +0000</pubDate><atom:updated>2011-06-19T20:20:54.714-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">test driven development</category><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">tutorial</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">presentation</category><title>Save the date: Android Testing at LinuxCon North America 2011</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Emn0tQG7Dlc/Tf6OUkCeBiI/AAAAAAAABTY/nc-bnfvBwSY/s1600/header_linuxcon.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-Emn0tQG7Dlc/Tf6OUkCeBiI/AAAAAAAABTY/nc-bnfvBwSY/s1600/header_linuxcon.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;Mark your calendars. On Wednesday August 17th, 2011, 10:30 (&lt;a href="http://events.linuxfoundation.org/events/linuxcon/schedule"&gt;schedule&lt;/a&gt;) I will be presenting&amp;nbsp;the tutorial&amp;nbsp;&lt;span style="font-weight: bold;"&gt;Introduction to Android Testing.&lt;/span&gt;&amp;nbsp;It will give you an overview of current methodologies and tools available on Android. This tutorial will also introduce&amp;nbsp;&lt;i&gt;Test Driven Development&lt;/i&gt;, &lt;i&gt;Behaviour Driven Development&lt;/i&gt; and &lt;i&gt;Continuous Integration,&lt;/i&gt; techniques that every serious development project should at least consider.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;More information at &lt;a href="http://events.linuxfoundation.org/events/linuxcon"&gt;LinuxCon North America 2011&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: Arial, Tahoma, Helvetica, FreeSans, sans-serif; font-size: 15px; line-height: 20px;"&gt;Hope to see you there.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-229821337342459086?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/06/save-date-android-testing-at-linuxcon.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-Emn0tQG7Dlc/Tf6OUkCeBiI/AAAAAAAABTY/nc-bnfvBwSY/s72-c/header_linuxcon.png" height="72" width="72" /><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1917729524302955690</guid><pubDate>Fri, 03 Jun 2011 04:04:00 +0000</pubDate><atom:updated>2011-06-03T00:04:52.216-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">hamcrest</category><category domain="http://www.blogger.com/atom/ns#">AATG</category><category domain="http://www.blogger.com/atom/ns#">instrumentation</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">easymock</category><category domain="http://www.blogger.com/atom/ns#">junit</category><category domain="http://www.blogger.com/atom/ns#">hudson</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">continuous integration</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>Android Application Testing Guide</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.packtpub.com/android-application-testing-guide/book" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-99BY8DOzDTM/TehX55pspCI/AAAAAAAABRE/E2QIxBbdcBo/s320/cover.jpg" width="259" /&gt;&lt;/a&gt;&lt;/div&gt;The wait is almost over and after a year of hard work the book is finished and is expected to be published by &lt;a href="http://www.packtpub.com/android-application-testing-guide/book"&gt;PACKT&lt;/a&gt; this month (June 2011).&lt;br /&gt;
&lt;br /&gt;
You can &lt;a href="http://www.packtpub.com/android-application-testing-guide/book"&gt;Pre-order&lt;/a&gt; now !&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif; font-size: large;"&gt;Approach&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Adroid Application Testing Guide&lt;/b&gt; is a highly detailed book which gives step-by-step examples for a great variety of real-world cases, providing professional guidelines and recommendations that will be extremely valuable for optimizing your development time and resources. In the chapters you will find an introduction to specific testing techniques, and tools for specific situations.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif; font-size: large;"&gt;Overview of Android Application Testing Guide&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The first and only book that focuses on testing Android applications&lt;/li&gt;
&lt;li&gt;Step-by-step approach clearly explaining the most efficient testing methodologies&lt;/li&gt;
&lt;li&gt;Real world examples with practical test cases that you can reuse&lt;/li&gt;
&lt;li&gt;eBook available as PDF and ePub downloads and also on PacktLib&lt;/li&gt;
&lt;/ul&gt;More detailed information can be obtained from its web page at &lt;a href="http://www.packtpub.com/android-application-testing-guide/book"&gt;PACKT&lt;/a&gt;.&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-1917729524302955690?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/06/android-application-testing-guide.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-99BY8DOzDTM/TehX55pspCI/AAAAAAAABRE/E2QIxBbdcBo/s72-c/cover.jpg" height="72" width="72" /><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1759741821294138788</guid><pubDate>Sat, 23 Apr 2011 20:54:00 +0000</pubDate><atom:updated>2011-04-23T16:54:47.130-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">instrumentation</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><title>Running instrumentation from monkeyrunner</title><description>Sometimes you may want to run the instrumentation for a package from &lt;b&gt;monkeyrunner&lt;/b&gt;, and the following script does just this. It has the advantage of using the &lt;b&gt;package manager&lt;/b&gt; to find the correct instrumentation for the specified package simplifying the parameters you must provide.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1em; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;span style="color: blue; font-family: monospace;"&gt;#! /usr/bin/env monkeyrunner&lt;/span&gt;

import sys
import os
from com.android.monkeyrunner import MonkeyRunner

PLI = &lt;span style="color: magenta; font-family: monospace;"&gt;'pm list instrumentation'&lt;/span&gt;
prog = os.path.basename(sys.argv[0])

def usage():
&amp;nbsp;&amp;nbsp; print &amp;gt;&amp;gt;sys.stderr, \
       &lt;span style="color: magenta; font-family: monospace;"&gt;"usage: %s target-package-name"&lt;/span&gt;&amp;nbsp;% prog
&amp;nbsp;&amp;nbsp; sys.exit(1)

def main():
&amp;nbsp;&amp;nbsp; if len(sys.argv) != 2:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;usage()

&amp;nbsp;&amp;nbsp; pkg = sys.argv[1]

&amp;nbsp;&amp;nbsp; print &lt;span style="color: magenta; font-family: monospace;"&gt;"waiting for connection..."&lt;/span&gt;
&amp;nbsp;&amp;nbsp; device = MonkeyRunner.waitForConnection()

&amp;nbsp;&amp;nbsp; print &lt;span style="color: magenta; font-family: monospace;"&gt;"running istrumentation for %s"&lt;/span&gt;&amp;nbsp;% pkg
&amp;nbsp;&amp;nbsp; for (i, t) in map(lambda l: l.split(), device.shell(PLI).splitlines()):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if t == &lt;span style="color: magenta; font-family: monospace;"&gt;'(target=%s)'&lt;/span&gt;&amp;nbsp;% pkg:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print device.instrument(i.split(&lt;span style="color: magenta; font-family: monospace;"&gt;':'&lt;/span&gt;)[1], { &lt;span style="color: magenta; font-family: monospace;"&gt;'wait'&lt;/span&gt;:True })[&lt;span style="color: magenta; font-family: monospace;"&gt;'stream'&lt;/span&gt;]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return
&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp; print &amp;gt;&amp;gt;sys.stderr, &lt;span style="color: magenta; font-family: monospace;"&gt;"ERROR: instrumentation for %s not found"&lt;/span&gt;&amp;nbsp;% pkg


if __name__ == &lt;span style="color: magenta; font-family: monospace;"&gt;'__main__'&lt;/span&gt;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;main()&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;
You can invoke this script as in the following command line:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; $ instrumentation.mr com.example.package&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
compare this against the command line you may need to invoke the same instrumentation using plain&lt;b&gt; am instrument&lt;/b&gt;.&lt;br /&gt;
Once you invoke the script with the correct package name, the instrumentation for that package is run and the results are presented, like in this example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;waiting for connection...&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;running istrumentation for com.example.package&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Test results for InstrumentationTestRunner=..................................&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;Time: 37.844&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: x-small;"&gt;OK (34 tests)&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-1759741821294138788?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/04/running-instrumentation-from.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-3200440943426550894</guid><pubDate>Sun, 10 Apr 2011 22:38:00 +0000</pubDate><atom:updated>2011-04-25T23:52:25.899-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">adb</category><title>monkeyrunner: visual image comparison</title><description>We have discussed taking screenshots with &lt;b&gt;monkeyrunner&lt;/b&gt; in &lt;a href="http://dtmilano.blogspot.com/2011/01/obtaining-android-screenshots-in-tests.html"&gt;previous posts&lt;/a&gt;, but now we are taking a step further by comparing the screenshots obtained during the test run against some reference image.&lt;br /&gt;
&lt;br /&gt;
Firstly, we need these reference images that you can obtain by running specific cases of the tests specially designed to do it. It's not recommended to use &lt;a href="http://developer.android.com/guide/developing/debugging/ddms.html"&gt;DDMS&lt;/a&gt; to take the reference image as in some cases the image format and compression may slightly differ from the ones taken by &lt;b&gt;monkeyrunner&lt;/b&gt; leading to false positive identification of the dissimilarity.&lt;br /&gt;
&lt;br /&gt;
As a fairly simple example we will be creating a test to verify the correct drag and drop to a new position of a screen widget &amp;nbsp;, in this case the &lt;b&gt;Home screen tips&lt;/b&gt;. We will be sending touch events to move it from its original position in row 2:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-x06UnEX3QdA/TaHfGJ00GII/AAAAAAAABMQ/nq1j5noQZOw/s1600/reference-0-ddms.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-x06UnEX3QdA/TaHfGJ00GII/AAAAAAAABMQ/nq1j5noQZOw/s320/reference-0-ddms.png" width="192" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;to row 4:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-vLEB9pBmqvI/TaHfb-mGyYI/AAAAAAAABMU/0FMGtClQKbE/s1600/reference.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-vLEB9pBmqvI/TaHfb-mGyYI/AAAAAAAABMU/0FMGtClQKbE/s320/reference.png" width="192" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;This second image, showing the &lt;b&gt;Home screen tips&lt;/b&gt; widget in row 4 will be our reference image or the final state we want to verify in our test.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;There are some items we can anticipate will be different, like the time in the status bar, the battery level, &amp;nbsp;the connectivity, etc. Thus why we expect some degree of flexibility in our test not to fail under these&amp;nbsp;circumstances.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;We also use &lt;a href="http://www.imagemagick.org/script/compare.php"&gt;compare&lt;/a&gt; from the great &lt;b&gt;ImageMagick&lt;/b&gt; package that you should have installed for this script to work.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;In Debian/Ubuntu and derivatives&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; $ sudo apt-get install&amp;nbsp;imagemagick&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Having this in mind, our &lt;b&gt;monkeyrunner&lt;/b&gt; test would look something like this.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1em; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #880000; line-height: inherit;"&gt;&lt;span class="Apple-style-span" style="color: black;"&gt;&lt;span style="color: blue; font-size: x-small;"&gt;#! /usr/bin/env monkeyrunner&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;

&lt;/span&gt;&lt;span style="color: #a020f0; font-family: monospace; font-size: x-small; white-space: pre;"&gt;import&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;sys
&lt;/span&gt;&lt;span style="color: #a020f0; font-family: monospace; font-size: x-small; white-space: pre;"&gt;import&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;subprocess
&lt;/span&gt;&lt;span style="color: #a020f0; font-family: monospace; font-size: x-small; white-space: pre;"&gt;from&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;com.android.monkeyrunner
&lt;/span&gt;&lt;span style="color: #a020f0; font-family: monospace; font-size: x-small; white-space: pre;"&gt;import&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&amp;nbsp;MonkeyRunner, MonkeyDevice, MonkeyImage

TIMEOUT = &lt;/span&gt;&lt;span style="color: magenta; font-family: monospace; font-size: x-small; white-space: pre;"&gt;30
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;SERIALNO = &lt;/span&gt;&lt;span style="color: magenta; font-family: monospace; font-size: x-small; white-space: pre;"&gt;'emulator-5554'
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;REF = &lt;/span&gt;&lt;span style="color: magenta; font-family: monospace; font-size: x-small; white-space: pre;"&gt;'reference.png'
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;SCR = &lt;/span&gt;&lt;span style="color: magenta; font-family: monospace; font-size: x-small; white-space: pre;"&gt;'screenshot.png'
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;CMP = &lt;/span&gt;&lt;span style="color: magenta; font-family: monospace; font-size: x-small; white-space: pre;"&gt;'comparison.png'
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;ACCEPTANCE = &lt;/span&gt;&lt;span style="color: magenta; font-family: monospace; font-size: x-small; white-space: pre;"&gt;0.9
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace; font-size: x-small; line-height: inherit; white-space: pre;"&gt;
device = &lt;span style="color: darkcyan;"&gt;None&lt;/span&gt;

&lt;span style="color: brown;"&gt;&lt;b&gt;
def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: darkcyan;"&gt;testDropWidgetIntoFourthRow&lt;/span&gt;():
&amp;nbsp;&amp;nbsp; &amp;nbsp;reference = MonkeyImage.loadFromFile(REF)
&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: darkcyan;"&gt;print&lt;/span&gt;&amp;nbsp;&lt;span style="color: magenta;"&gt;"moving widget..."
&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;device.drag((&lt;span style="color: magenta;"&gt;230&lt;/span&gt;, &lt;span style="color: magenta;"&gt;300&lt;/span&gt;), (&lt;span style="color: magenta;"&gt;230&lt;/span&gt;, &lt;span style="color: magenta;"&gt;600&lt;/span&gt;), &lt;span style="color: magenta;"&gt;2.0&lt;/span&gt;, &lt;span style="color: magenta;"&gt;125&lt;/span&gt;)
&amp;nbsp;&amp;nbsp; &amp;nbsp;MonkeyRunner.sleep(&lt;span style="color: magenta;"&gt;3&lt;/span&gt;)
&amp;nbsp;&amp;nbsp; &amp;nbsp;screenshot = device.takeSnapshot()
&amp;nbsp;&amp;nbsp; &amp;nbsp;screenshot.writeToFile(SCR)
&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: brown;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: brown;"&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt;&amp;nbsp;screenshot.sameAs(reference, ACCEPTANCE):
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;span style="color: darkcyan;"&gt;print&lt;/span&gt;&amp;nbsp;&lt;span style="color: magenta;"&gt;"comparison failed, getting visual comparison..."
&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; subprocess.call([&lt;span style="color: magenta;"&gt;"/usr/bin/compare"&lt;/span&gt;, REF, SCR, CMP])

&lt;span style="color: brown;"&gt;&lt;b&gt;def&lt;/b&gt;&lt;/span&gt;&amp;nbsp;&lt;span style="color: darkcyan;"&gt;main&lt;/span&gt;():
&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: brown;"&gt;&lt;b&gt;global&lt;/b&gt;&lt;/span&gt;&amp;nbsp;device
&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: darkcyan;"&gt;print&lt;/span&gt;&amp;nbsp;&lt;span style="color: magenta;"&gt;"waiting for connection..."
&lt;/span&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;device = MonkeyRunner.waitForConnection(TIMEOUT, SERIALNO)
&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span style="color: brown;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;device:
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; testDropWidgetIntoFourthRow()


&lt;span style="color: brown;"&gt;&lt;b&gt;if&lt;/b&gt;&lt;/span&gt;&amp;nbsp;__name__ == &lt;span style="color: magenta;"&gt;'__main__'&lt;/span&gt;:
&amp;nbsp;&amp;nbsp; &amp;nbsp; main()&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
We are using&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;MonkeyImage.loadFromFile()&lt;/span&gt;&amp;nbsp;to load the reference image from a file.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="background-color: #fff2cc;"&gt;&lt;span class="Apple-style-span" style="background-color: #fff2cc;"&gt;This method was not available in &lt;b&gt;monkeyrunner&lt;/b&gt; so I implemented it myself and I decided to do it in &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;MonkeyImage&lt;/span&gt;, but &amp;nbsp;it is now included in latest verions of&amp;nbsp;&lt;b&gt;monkeyrunner &lt;/b&gt;but as &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;MonkeyRunner.loadImageFromFile()&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
In case you don't have it in your version you can build it from source (being sure that this&amp;nbsp;&lt;a href="https://review.source.android.com//#change,21478"&gt;patch&lt;/a&gt;&amp;nbsp;is included).&lt;br /&gt;
&lt;b&gt;monkeyrunner&lt;/b&gt; is a SDK component and thus is included in this project that can be downloaded from&amp;nbsp;&lt;a href="http://android.git.kernel.org/?p=platform/sdk.git;a=summary"&gt;android SDK source&lt;/a&gt;.&lt;br /&gt;
Anyway, if you can't do it you may just avoid this step and replace the condition in the if by&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;True&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A brief explanation of the script is:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;in the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;main&lt;/span&gt; method we obtain the connection with the device using the serial number specified in &lt;span class="Apple-style-span" style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"&gt;SERIALNO&lt;/span&gt;. A more sophisticated script should use parameters.&lt;/li&gt;
&lt;li&gt;if the connection was successful we run the test&lt;/li&gt;
&lt;li&gt;in the test method we load the reference image from the specified file&lt;/li&gt;
&lt;li&gt;we send a simulated drag event to move the widget from the second row to the fourth row, using screen coordinates&lt;/li&gt;
&lt;li&gt;sleep for a while&lt;/li&gt;
&lt;li&gt;get the screenshot&lt;/li&gt;
&lt;li&gt;if the images are not the same, considering 90% acceptance value, we use the visual comparison to get a clue of the difference&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;If you run the script you can verify that the screenshot is taken and the test succeed because they are the same. They only have minor differences in the time and battery level but they lie above the acceptance value.&lt;br /&gt;
Now, if we run the test again but this time using &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;(230, 400)&lt;/span&gt; instead of &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;(230, 600)&lt;/span&gt; in the drag command the widget will be dropped in the third line instead of the fourth and we expect this difference be detected as our reference image for the final state&amp;nbsp;contains&amp;nbsp;the widget in the fourth row, and thus precisely what&amp;nbsp;happens.&lt;br /&gt;
This is the comparison image highlighting in red the differences:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ma_VFro4_-c/TaIu57Mk0dI/AAAAAAAABMY/Gh_crKDcRRk/s1600/comparison.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-ma_VFro4_-c/TaIu57Mk0dI/AAAAAAAABMY/Gh_crKDcRRk/s320/comparison.png" width="192" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Check that as we mentioned before the&amp;nbsp;battery&amp;nbsp;level and time in the status bar are also detected as differences but they are usually under the threshold.&lt;br /&gt;
&lt;br /&gt;
This is not a real repeatable test as we are not leaving the system in the same state that was found but the idea is to present the subject in the simplest possible way to avoid deviating from the main goal which is demonstrating how you can add visual comparison to your tests using &lt;b&gt;monkeyrunner&lt;/b&gt; and &lt;b&gt;ImageMagick&lt;/b&gt;.&lt;br /&gt;
I'm sure this will give you lots of ideas to&amp;nbsp;implement&amp;nbsp;you own tests.&lt;br /&gt;
As always, comments are gladly welcome.&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-3200440943426550894?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/04/monkeyrunner-visual-image-comparison.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-x06UnEX3QdA/TaHfGJ00GII/AAAAAAAABMQ/nq1j5noQZOw/s72-c/reference-0-ddms.png" height="72" width="72" /><thr:total>23</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-3860365508849645863</guid><pubDate>Sun, 13 Mar 2011 01:40:00 +0000</pubDate><atom:updated>2011-09-13T10:42:35.700-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><title>Using Android monkeyrunner from Eclipse</title><description>You may want to edit scripts and run them from &lt;b&gt;Eclipse&lt;/b&gt;.&lt;br /&gt;
To be able to do this you must first install &lt;a href="http://pydev.sourceforge.net/"&gt;PyDev&lt;/a&gt; from &lt;b&gt;Eclipse Marketplace.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-AjFA3kTNCVA/TfuMnAeEm_I/AAAAAAAABTM/YLn18pZRaJA/s1600/important.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/-AjFA3kTNCVA/TfuMnAeEm_I/AAAAAAAABTM/YLn18pZRaJA/s1600/important.png" /&gt;&lt;/a&gt;&lt;/div&gt;
Latest versions of PyDev don't work with monkeyrunner because it is not detected as a valid interpreter. I'm sure this will be finxed in the future. In the meantime you should stick to &lt;b&gt;PyDev 1.6.5&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-TockP-Sq5O4/TfuLoCtlm2I/AAAAAAAABTE/YKvuaOS-gt4/s1600/Install+_002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="284" src="http://4.bp.blogspot.com/-TockP-Sq5O4/TfuLoCtlm2I/AAAAAAAABTE/YKvuaOS-gt4/s320/Install+_002.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Then you have to define a new python interpreter&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://lh3.googleusercontent.com/-ywo-mtEYABg/TXwbronMbwI/AAAAAAAABJs/YMx3h2AHhcc/s1600/Preferences+_001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="270" src="https://lh3.googleusercontent.com/-ywo-mtEYABg/TXwbronMbwI/AAAAAAAABJs/YMx3h2AHhcc/s400/Preferences+_001.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
but before you can do it you need to do some changes to the Android installation. We need to replace the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;monkeyrunner&lt;/span&gt; interpreter because Eclipse invokes it using the &lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;-u&lt;/span&gt;&lt;/b&gt; command line option, &amp;nbsp;unbuffer stdin, stdout and stderr,&amp;nbsp;which is not supported by &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;monkeyrunner&lt;/span&gt;. To solve it we should rename the original interpreter to &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;monkeyrunner-original&lt;/span&gt; and then use this script as a replacement for &amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;monkeyrunner&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1em; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="com" style="color: #880000; font-family: monospace; line-height: inherit;"&gt;# /bin/bash&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;span class="Apple-style-span" style="color: #007000;"&gt;&lt;span class="Apple-style-span" style="line-height: inherit;"&gt;
&lt;/span&gt;&lt;/span&gt;if [ "$1" = '-u' ]
then
 shift
fi

exec /opt/android-sdk-linux_86/tools/monkeyrunner-original "$@"&lt;span class="Apple-style-span" style="color: #007000;"&gt;&lt;span class="Apple-style-span" style="line-height: inherit;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
if you are using Microsoft Windows, you should use something like this (script contributed by &lt;a href="http://www.blogger.com/profile/00317442027842958878"&gt;tagmaster&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1em; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="com" style="color: #880000; font-family: monospace; line-height: inherit;"&gt;REM&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;span class="Apple-style-span" style="color: #007000;"&gt;&lt;span class="Apple-style-span" style="line-height: inherit;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse; font-size: 13px; white-space: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;@echo off
if("%1")==("-u") shift
"C:\Program Files\Android\android-sdk\&lt;wbr&gt;&lt;/wbr&gt;tools"/monkeyrunner-original %1 %2 %3 %4 %5 %6 %7 %8&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;span class="pln" style="color: black;"&gt;Once the new interpreter is defined and assigned to a &lt;b&gt;PyDev&lt;/b&gt; project you will be able to edit and run &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;monkeyrunner&lt;/span&gt; scripts from Eclipse&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://lh4.googleusercontent.com/-WqvaF7Xu0C4/TXwfxXXGC5I/AAAAAAAABJw/9X9Hf8abUpw/s1600/Pydev+-+Monkeyrunner+TemperatureConverter-src-test-TemperatureConverterTests.py+-+Eclipse+_002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="225" src="https://lh4.googleusercontent.com/-WqvaF7Xu0C4/TXwfxXXGC5I/AAAAAAAABJw/9X9Hf8abUpw/s400/Pydev+-+Monkeyrunner+TemperatureConverter-src-test-TemperatureConverterTests.py+-+Eclipse+_002.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="pln" style="color: black;"&gt;Don't forget to set the previously defined interpreter to the project properties.&lt;/span&gt;&lt;br /&gt;
&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-SKAA3TzPses/Te-oyntPInI/AAAAAAAABRk/yTZKVLoOVa4/s1600/Properties+for+Monkeyrunner+TemperatureConverter++%2528%2540ubuntu-10-04-64b%2529_002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="252" src="http://2.bp.blogspot.com/-SKAA3TzPses/Te-oyntPInI/AAAAAAAABRk/yTZKVLoOVa4/s320/Properties+for+Monkeyrunner+TemperatureConverter++%2528%2540ubuntu-10-04-64b%2529_002.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span class="pln" style="color: black;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="pln" style="color: black; font-family: Verdana, sans-serif; font-size: large;"&gt;&lt;b&gt;Update: July 2011&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="pln" style="color: black; font-family: Times, 'Times New Roman', serif;"&gt;This patch was added to monkeyrunner to ignore the &lt;b&gt;-u&lt;/b&gt; option sent by PyDev:&lt;/span&gt;&lt;br /&gt;
&lt;span class="pln" style="color: black;"&gt;&lt;a href="http://android.git.kernel.org/?p=platform/sdk.git;a=commitdiff;h=f07d8c2026606633f1de7e1ab9d985c74ad8b340"&gt;http://android.git.kernel.org/?p=platform/sdk.git;a=commitdiff;h=f07d8c2026606633f1de7e1ab9d985c74ad8b340&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="pln" style="color: black;"&gt;However, the usage string does not include the &lt;b&gt;-u&lt;/b&gt; option yet.&amp;nbsp;&lt;/span&gt;BTW, credit would be nice.&lt;br /&gt;
So, the wrapper is not needed any more.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif; font-size: large;"&gt;Update: September 2011&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;monkeyrunner&lt;/b&gt;&lt;/span&gt; included in &lt;b&gt;Android SDK Tools revision 12&lt;/b&gt; supports &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;-u&lt;/b&gt;&lt;/span&gt; option, however as it was mentioned before it is not described in the help text.&lt;br /&gt;
Come on, we are only one step behind...&amp;nbsp;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-3860365508849645863?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/03/using-android-monkeyrunner-from-eclipse.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-AjFA3kTNCVA/TfuMnAeEm_I/AAAAAAAABTM/YLn18pZRaJA/s72-c/important.png" height="72" width="72" /><thr:total>52</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-7250567586223652345</guid><pubDate>Tue, 01 Feb 2011 03:44:00 +0000</pubDate><atom:updated>2011-04-12T10:23:00.443-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><title>Obtaining Android screenshots in tests with monkeyrunner</title><description>Today I helped somebody that was asking &lt;a href="http://groups.google.com/group/android-developers/browse_thread/thread/557e4c0609b8b3ff"&gt;why an extremely simple monkeyrunner script fails&lt;/a&gt; to obtain the screenshot.&lt;br /&gt;
Interestingly enough, this script was almost a verbatim copy of what is specified in &lt;a href="http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html#SampleProgram"&gt;monkeyrunner documentation&lt;/a&gt;. So you guessed, the documentation is wrong and&amp;nbsp;unfortunately&amp;nbsp;there is no way of correcting it, Android documentation is not a wiki and the only way is reporting a bug that will be probably ignored sunk in a sea of&amp;nbsp;thousands&amp;nbsp;more important bugs.&lt;br /&gt;
&lt;br /&gt;
So here you have the problem and the solution.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The problem&lt;/b&gt;&lt;br /&gt;
The documentation includes this line to take the screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: #333333; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; color: #007000; font-family: monospace; line-height: inherit; margin-bottom: 1em; margin-left: 1em; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="com" style="color: #880000;"&gt;# Takes a screenshot&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;
result &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;=&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; device&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;takeSnapShot&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
if you run this, you soon realize that&amp;nbsp;something&amp;nbsp;is wrong. You will receive an error similar to this one:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;AttributeError: 'com.android.monkeyrunner.adb.AdbMonkeyDevice' object has no attribute 'takeSnapShot'&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The problem, or better I should say the problems, because there are two, are:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;missing&amp;nbsp;parenthesis, so instead of using the call operator on the callable object we are getting a reference to the object itself and then try to access one attribute&lt;/li&gt;
&lt;li&gt;if there were parenthesis, the call won't succeed anyway because the second 'S' is lowercase 's'&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The solution&lt;/b&gt;&lt;br /&gt;
Then this is the complete solution to obtain the screenshot:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; font-family: monospace; line-height: inherit; margin-bottom: 1em; margin-left: 1em; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="com" style="color: #880000;"&gt;# Imports the monkeyrunner modules used by this program&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;
&lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;from&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; com&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;android&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;monkeyrunner &lt;/span&gt;&lt;span class="kwd" style="color: #000088;"&gt;import&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="typ" style="color: #660066;"&gt;MonkeyRunner&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="typ" style="color: #660066;"&gt;MonkeyDevice&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;
&lt;/span&gt;&lt;span class="com" style="color: #880000;"&gt;# Connects to the current device, returning a MonkeyDevice object&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;
device &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;=&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; &lt;/span&gt;&lt;span class="typ" style="color: #660066;"&gt;MonkeyRunner&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;waitForConnection&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;()&lt;/span&gt;&lt;span class="pln"&gt;&lt;span class="Apple-style-span" style="color: #880000;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="com" style="color: #880000;"&gt;# Takes a screenshot&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;
result &lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;=&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt; device&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;&lt;b&gt;takeSnapshot()&lt;/b&gt;
&lt;/span&gt;&lt;span class="com" style="color: #880000;"&gt;# Writes the screenshot to a file&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;
result&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;.&lt;/span&gt;&lt;span class="pln" style="color: black;"&gt;writeToFile&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;(&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;'/tmp/device.png'&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;,&lt;/span&gt;&lt;span class="str" style="color: #008800;"&gt;'png'&lt;/span&gt;&lt;span class="pun" style="color: #666600;"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Extra tip&lt;/b&gt;&lt;br /&gt;
You can add the corresponding &lt;a href="http://en.wikipedia.org/wiki/Shebang_(Unix)"&gt;she-bang&lt;/a&gt; to the script and set the execution permission to be able to run it from the command line just invoking the script name:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="prettyprint" style="background-color: #fafafa; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; margin-bottom: 1em; margin-left: 1em; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 10px; padding-left: 10px; padding-right: 10px; padding-top: 10px;"&gt;&lt;span class="com" style="color: #880000; font-family: monospace; line-height: inherit;"&gt;#! /&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #880000;"&gt;opt/android-sdk-linux_86/tools/monkeyrunner
...&lt;/span&gt;&lt;/pre&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; white-space: normal;"&gt;This should include the path to your &lt;b&gt;monkeyrunner&lt;/b&gt; script, and because it&amp;nbsp;&lt;/span&gt;uses Jython, an implementation of Python that uses the Java programming language, thus allowing the use of Python syntax to access the constants, classes, and methods of the API.&lt;br /&gt;
Having added this she-bang line you can simply run your &lt;b&gt;monkeyrunner&lt;/b&gt; script by invoking its name:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;$ monkeyrunner-take-screenshot&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-7250567586223652345?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/01/obtaining-android-screenshots-in-tests.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1415637391809245967</guid><pubDate>Fri, 14 Jan 2011 23:48:00 +0000</pubDate><atom:updated>2011-01-14T18:48:40.913-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">emulator</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">gnome-terminal</category><category domain="http://www.blogger.com/atom/ns#">adb</category><title>Alternative logcat viewer</title><description>If you are developing &lt;b&gt;Android&lt;/b&gt; with &lt;b&gt;Eclipse&lt;/b&gt; and have several devices and emulators connected you may have been annoyed by the constant disconnection that the &lt;b&gt;DDMS&lt;/b&gt; view suffers, in such cases you could try to reconnect to the desired device by clicking on it, but this is not always successful.&lt;br /&gt;
&lt;br /&gt;
I've found as a workaround that sometimes is easier to reconnect if you reach another device or emulator first and then the desired one, so as a rule of thumb is probably better to always have more than one.&lt;br /&gt;
&lt;br /&gt;
Anyway, here you are a very simple trick that might turn you life a little easier just using a text logcat from adb in a gnome-terminal that will remain open no matter what have happened to the connection.&lt;br /&gt;
&lt;br /&gt;
First, you need to create a &lt;b&gt;gnome-terminal&lt;/b&gt; profile, &lt;b&gt;logcat&lt;/b&gt; in this case, an set the following values as dispalyed:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_9_trc1obptk/TTDdiUXz9-I/AAAAAAAABFw/qlv5fwSlpwM/s1600/Editing%2BProfile%2B%25E2%2580%259Clogcat%25E2%2580%259D_001.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="297" src="http://3.bp.blogspot.com/_9_trc1obptk/TTDdiUXz9-I/AAAAAAAABFw/qlv5fwSlpwM/s400/Editing%2BProfile%2B%25E2%2580%259Clogcat%25E2%2580%259D_001.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
The important things here are:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Run a custom command instead of my shell&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Custom command: &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sh -c '/opt/android-sdk/platform-tools/adb -e logcat | coloredlogcat.py'&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;When command exits: &lt;b&gt;Hold the terminal open&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;As a bonus, we are including &lt;a href="http://jsharkey.org/downloads/coloredlogcat.pytxt"&gt;coloredlogcat.py&lt;/a&gt;, a filter that will colorize our logcat output.&lt;br /&gt;
What's nice about this simple setup is that even if you are disconnected because you closed the emulator or unplugged the device, just clicking on the &lt;b&gt;Relaunch&lt;/b&gt; button will reconnect you again.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_9_trc1obptk/TTDgPZsuNyI/AAAAAAAABF8/XHNeNESfySk/s1600/Logcat_002.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="250" src="http://2.bp.blogspot.com/_9_trc1obptk/TTDgPZsuNyI/AAAAAAAABF8/XHNeNESfySk/s400/Logcat_002.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Hope you enjoy it and improve your development not having to&amp;nbsp;insistently&amp;nbsp;click on DDMS' &amp;nbsp;device list.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-1415637391809245967?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2011/01/alternative-logcat-viewer.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_9_trc1obptk/TTDdiUXz9-I/AAAAAAAABFw/qlv5fwSlpwM/s72-c/Editing%2BProfile%2B%25E2%2580%259Clogcat%25E2%2580%259D_001.png" height="72" width="72" /><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-7011780383156931829</guid><pubDate>Fri, 31 Dec 2010 19:38:00 +0000</pubDate><atom:updated>2010-12-31T14:38:54.559-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">sdk</category><category domain="http://www.blogger.com/atom/ns#">emulator</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">ubuntu</category><title>Problems updating Android to 2.3 in Ubuntu</title><description>If you were using Ubuntu 9.10 (karmic) because you wanted to avoid some issues with Eclipse and Android ADT plugin that happened on newer versions on Ubuntu, well now is time to upgrade to the latest Ubuntu 10.10 (maverick) if you want to update to the latest &lt;b&gt;Android 2.3 (gingerbread)&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
You may have discovered this after the update finished using &lt;b&gt;Android SDK and AVD Manager&lt;/b&gt; tool and you sadly realize that your Android development environment was turned useless without a single word of warning. Latest Android SDK version depends on &lt;b&gt;GLIBC_2.11&lt;/b&gt; but it's no available for previous versions of Ubuntu, so unless you want to take the risk of using a different repository trying to find an update with unknown consequences to other components, upgrading is your only possible path.&lt;br /&gt;
If this is not a serious bug we should reconsider the definition of the word.&lt;br /&gt;
&lt;br /&gt;
The origin of the problem is that Android SDK distribution is not package based and thus no dependencies are considered before updating the software. This is clearly a nonsense. Google has taken a completely different approach with &lt;b&gt;Chrome&lt;/b&gt; which is  cleverly distributed from a package repository as we can see in this screenshot of &lt;b&gt;Ubuntu Software Center&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_9_trc1obptk/TR4sKu_WD1I/AAAAAAAABFE/6IOXnu9gYvo/s1600/Screenshot-Ubuntu%2BSoftware%2BCentre.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="230" width="400" src="http://1.bp.blogspot.com/_9_trc1obptk/TR4sKu_WD1I/AAAAAAAABFE/6IOXnu9gYvo/s400/Screenshot-Ubuntu%2BSoftware%2BCentre.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Android SDK must be distributed as packages as Chrome does, otherwise there is no way to prevent this problems happening again and again in the future. We are only scaring people away of Android development with this poor policies. It's true that the &lt;a href="http://developer.android.com/sdk/requirements.html"&gt;requirements page&lt;/a&gt; was updated and &lt;b&gt;GLIBC 2.11&lt;/b&gt; is listed now as a requirement, but when you discover it, it's too late. You expect some verifications done from software doing an update that cannot easily be reverted.&lt;br /&gt;
&lt;br /&gt;
This is perhaps the most important bug, but there are others after upgrading to Ubuntu 10.10 (maverick) and Android SDK 2.3 (gingerbread) some other things are still broken, for example &lt;b&gt;hierarchyviewer&lt;/b&gt; does not run out of the box and you have to manually copy some libraries,  &lt;br /&gt;
&lt;b&gt;Android SDK and AVD Manager&lt;/b&gt; updates some packages again an again ignoring they are already installed and some deficiencies of the Android ADT Layout editor, to name a few.&lt;br /&gt;
&lt;br /&gt;
I complained about many things about Android in this blog and it seems that in one way or another they were fixed in following releases, so I hopefully think this would be the case.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-7011780383156931829?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2010/12/problems-updating-android-to-23-in.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_9_trc1obptk/TR4sKu_WD1I/AAAAAAAABFE/6IOXnu9gYvo/s72-c/Screenshot-Ubuntu%2BSoftware%2BCentre.png" height="72" width="72" /><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-5328362397780775261</guid><pubDate>Mon, 24 May 2010 23:43:00 +0000</pubDate><atom:updated>2010-05-24T19:58:18.979-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">continuous integration</category><title>Android 2.2 changes</title><description>Android 2.2, a minor platform release, arrived last week with a bunch of changes ranging from Dalvik JIT and Kernel Memory Management Boost to a new Launcher.&lt;br /&gt;&lt;br /&gt;You can check the &lt;a href="http://developer.android.com/intl/de/sdk/android-2.2-highlights.html"&gt;highlights&lt;/a&gt; to get a bigger picture.&lt;br /&gt;But there's one change that's almost not announced anywhere, and I consider it very important too.&lt;br /&gt;&lt;br /&gt;With the advent of Android 2.2 you can install or upgrade the SDK and tools in Linux as &lt;span style="font-weight:bold;"&gt;root&lt;/span&gt; and the permissions are (almost) correct and you don't need further changes in this situation, or what is almost the same we can declare &lt;a href="http://dtmilano.blogspot.com/2010/01/android-fixperms-updated.html"&gt;android-fixperms-updated&lt;/a&gt; defunct and no longer needed.&lt;br /&gt;&lt;br /&gt;This is very good news if you are using &lt;a href="http://dtmilano.blogspot.com/search/label/continuous%20integration"&gt;continuos integration&lt;/a&gt; on Android as was described by various posts in this blog.&lt;br /&gt;&lt;br /&gt;Great job Google.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-5328362397780775261?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2010/05/android-2.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>21</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-7306541961201629829</guid><pubDate>Sun, 28 Mar 2010 19:53:00 +0000</pubDate><atom:updated>2010-03-28T16:11:41.330-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">training</category><category domain="http://www.blogger.com/atom/ns#">android</category><title>Android course to be held at SkillsMater in April</title><description>The Android course authored by myself and published by Ricston is to be held at &lt;a href="http://skillsmatter.com/course/os-mobile-server/developing-mobile-applications-with-android"&gt;SkillsMater&lt;/a&gt; (London, UK) again on April 14-16 2010.&lt;br /&gt;&lt;br /&gt;There are still some seats available for those that want to attend.&lt;br /&gt;&lt;br /&gt;Ross Mason, founder and CTO at MuleSoft who attended this Android course said:&lt;br /&gt;&lt;blockquote&gt;&lt;div&gt; "&lt;i&gt;it provided a great introduction to developing on the Android platform. You can see that the author has crafted a well-structured course that covers the core knowledge required by developers to understand the potential of the platform and how build apps on it. Delivery was smooth, the instructor very well informed. This course provides an excellent way to get proficient in Android in a few days.&lt;/i&gt;"&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-7306541961201629829?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2010/03/android-course-to-be-held-at.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-7510012226034645748</guid><pubDate>Wed, 24 Feb 2010 23:48:00 +0000</pubDate><atom:updated>2010-02-24T19:06:24.895-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">java</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">javadoc</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">continuous integration</category><title>Android: Generate javadoc for your project</title><description>So you want to follow the best practices and generate the javadoc for your android project from Eclipse and as soon as you start you hit the first wall, messages like "&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;b&gt;package android.app does not exist&lt;/b&gt;&lt;/span&gt;" completely fill your output console.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;What's wrong ?&lt;/div&gt;&lt;div&gt;And most important, how can you generate complete javadoc with links to android documentation ?&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://docs.google.com/View?id=ddwc44gs_240hkc84xfd"&gt;&lt;br /&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 128px; height: 128px; background: #ffffff;" src="http://lh6.ggpht.com/_9_trc1obptk/S0DlMeUIwKI/AAAAAAAAAok/xmVpz45SPtw/docs.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Find out how reading the complete article in Google Docs:&lt;a href="http://docs.google.com/View?id=ddwc44gs_240hkc84xfd"&gt; http://docs.google.com/View?id=ddwc44gs_240hkc84xfd&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/25456655-7510012226034645748?l=dtmilano.blogspot.com' alt='' /&gt;&lt;/div&gt;</description><link>http://dtmilano.blogspot.com/2010/02/android-generate-javadoc-for-your.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_9_trc1obptk/S0DlMeUIwKI/AAAAAAAAAok/xmVpz45SPtw/s72-c/docs.png" height="72" width="72" /><thr:total>0</thr:total></item></channel></rss>

