<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" 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>Tue, 24 Mar 2026 07:56:34 +0000</lastBuildDate><category>android</category><category>AndroidViewClient</category><category>monkeyrunner</category><category>python</category><category>test driven development</category><category>adb</category><category>culebra</category><category>TDD</category><category>tests</category><category>gui</category><category>eclipse</category><category>java</category><category>emulator</category><category>junit</category><category>uiautomator</category><category>continuous integration</category><category>github</category><category>tutorial</category><category>unit test</category><category>google</category><category>presentation</category><category>chimpchat</category><category>linux</category><category>shell</category><category>ubuntu</category><category>NetBeans</category><category>sdk</category><category>AATG</category><category>dump.py</category><category>emma</category><category>autoglade</category><category>bash</category><category>easymock</category><category>instrumentation</category><category>jython</category><category>thin client</category><category>Buenos Aires</category><category>UML</category><category>amazon</category><category>glade</category><category>intent</category><category>jemmy</category><category>stackoverflow</category><category>alexa</category><category>ant</category><category>automated testing</category><category>contacts</category><category>electron</category><category>gnome</category><category>hamcrest</category><category>hudson</category><category>ndk</category><category>pxes</category><category>screenshot</category><category>test recorder</category><category>testing</category><category>training</category><category>Browser</category><category>Glassfish</category><category>Web services</category><category>animations</category><category>aws</category><category>boot</category><category>citrix</category><category>cult</category><category>dump</category><category>espresso</category><category>gist</category><category>gnome-terminal</category><category>gnome-terminal-launcher</category><category>google chrome</category><category>ica</category><category>japan</category><category>jenkins</category><category>kml</category><category>maven</category><category>meenie</category><category>performance</category><category>sikuli</category><category>skill</category><category>slides</category><category>sqlite3</category><category>webview</category><category>wiki</category><category>486</category><category>Dogfish</category><category>Google+</category><category>appengine</category><category>asus</category><category>auito</category><category>bot</category><category>busybox</category><category>compaq</category><category>eeepc</category><category>eye contact</category><category>fedora</category><category>fragments</category><category>gpl</category><category>gradle</category><category>gsm</category><category>imerj</category><category>javadoc</category><category>javascript</category><category>jelly</category><category>kernel</category><category>lex</category><category>maps</category><category>mediawiki</category><category>mock</category><category>multiscreen</category><category>nexus</category><category>positron</category><category>seamless</category><category>sourceforge</category><category>superbook</category><category>swing</category><category>voiceui</category><category>webkit</category><category>zenity</category><title>Diego Torres Milano&#39;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>198</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-2704746547051957483</guid><pubDate>Sat, 21 Mar 2020 07:19:00 +0000</pubDate><atom:updated>2020-03-21T03:19:47.036-04:00</atom:updated><title>CulebraTester2 ui preview 202003</title><description>&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;344&quot; src=&quot;https://www.youtube.com/embed/prE0aKoMLfc?clip=&amp;amp;clipt=EAAYAA%3D%3D&quot; width=&quot;459&quot;&gt;&lt;/iframe&gt;</description><link>http://dtmilano.blogspot.com/2020/03/culebratester2-ui-preview-202003.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/prE0aKoMLfc/default.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1716641517176087089</guid><pubDate>Sat, 12 Jan 2019 06:30:00 +0000</pubDate><atom:updated>2019-01-12T01:31:38.531-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><title>Happy New Year</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI8OD6BHJ0sem5qNt5Oln2AMCIrWWm41XPHE_hOP2Uwajz_JvNMqJzlwBv-1SBOC1h6vvkqm80zfMEbbbUkcSOjSa7zjQun5c3SvYhtub3dBtB0hPjwlK1bsrCi_Mres09SEBy/s1600/culebra-500k-white.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;267&quot; data-original-width=&quot;800&quot; height=&quot;131&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI8OD6BHJ0sem5qNt5Oln2AMCIrWWm41XPHE_hOP2Uwajz_JvNMqJzlwBv-1SBOC1h6vvkqm80zfMEbbbUkcSOjSa7zjQun5c3SvYhtub3dBtB0hPjwlK1bsrCi_Mres09SEBy/s400/culebra-500k-white.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h4&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;Happy New Year!&lt;/span&gt;&lt;/h4&gt;
&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;As of December 2018, &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot; target=&quot;_blank&quot;&gt;AndroidViewClient/culebra&lt;/a&gt;&amp;nbsp;reached&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;verdana&amp;quot; , sans-serif;&quot;&gt;500,000 downloads from PyPi alone.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: #24292e; font-family: , , &amp;quot;segoe ui&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif , &amp;quot;apple color emoji&amp;quot; , &amp;quot;segoe ui emoji&amp;quot; , &amp;quot;segoe ui symbol&amp;quot;; font-size: 16px;&quot;&gt;Thanks to all who made it possible.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #24292e; font-family: , , &amp;quot;segoe ui&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif , &amp;quot;apple color emoji&amp;quot; , &amp;quot;segoe ui emoji&amp;quot; , &amp;quot;segoe ui symbol&amp;quot;;&quot;&gt;&lt;span style=&quot;background-color: white;&quot;&gt;One of the most important items in the roadmap for 2019 is the long-awaited&amp;nbsp;migration to Python 3. Stay tuned and happy testing.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #24292e; font-family: , , &amp;quot;segoe ui&amp;quot; , &amp;quot;helvetica&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif , &amp;quot;apple color emoji&amp;quot; , &amp;quot;segoe ui emoji&amp;quot; , &amp;quot;segoe ui symbol&amp;quot;;&quot;&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;</description><link>http://dtmilano.blogspot.com/2019/01/happy-new-year-as-of-december-2018.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI8OD6BHJ0sem5qNt5Oln2AMCIrWWm41XPHE_hOP2Uwajz_JvNMqJzlwBv-1SBOC1h6vvkqm80zfMEbbbUkcSOjSa7zjQun5c3SvYhtub3dBtB0hPjwlK1bsrCi_Mres09SEBy/s72-c/culebra-500k-white.png" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4412570112945822705</guid><pubDate>Mon, 14 May 2018 20:54:00 +0000</pubDate><atom:updated>2018-05-14T16:54:52.668-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">alexa</category><category domain="http://www.blogger.com/atom/ns#">amazon</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">automated testing</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><category domain="http://www.blogger.com/atom/ns#">test driven development</category><category domain="http://www.blogger.com/atom/ns#">voiceui</category><title>Testing Android voice apps automatically</title><description>&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT-n_taYC4IWOG2yx65GYOzhm0ayKwRqUmRO-YeKjzPDMCSdVgcSjdVn8xgYxKxt31vqoLhvOyi3XgCercSQaaMPsmiHlXCxnIOYSNDi1gkbYpJRGHH0qoccfz9QOKLmhK0chy/s1600/culebra.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;836&quot; data-original-width=&quot;817&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT-n_taYC4IWOG2yx65GYOzhm0ayKwRqUmRO-YeKjzPDMCSdVgcSjdVn8xgYxKxt31vqoLhvOyi3XgCercSQaaMPsmiHlXCxnIOYSNDi1gkbYpJRGHH0qoccfz9QOKLmhK0chy/s200/culebra.png&quot; width=&quot;195&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Let’s review &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot; target=&quot;_blank&quot;&gt;AndroidViewClient/culebra&lt;/a&gt; concertina mode features, compare them with monkey, and see how we can use those features to test voice based UIs or Alexa Skills.&lt;br /&gt;
&lt;br /&gt;
Unlike monkey, which sends pseudo-random events, &lt;b&gt;Culebra concertina mode&lt;/b&gt; analyzes the content of the screen and randomly selects a suitable event or action for the also randomly chosen target, usually a View.&lt;br /&gt;
Also, unlike monkey, the generated actions and their parameters are saved in a python script that can be later executed as many times as needed.&lt;br /&gt;
&lt;br /&gt;
Read more at &lt;a href=&quot;https://medium.com/@dtmilano/testing-android-voice-apps-automatically-feaf7f79c635&quot; target=&quot;_blank&quot;&gt;https://medium.com/@dtmilano&lt;/a&gt;</description><link>http://dtmilano.blogspot.com/2018/05/testing-android-voice-apps-automatically.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT-n_taYC4IWOG2yx65GYOzhm0ayKwRqUmRO-YeKjzPDMCSdVgcSjdVn8xgYxKxt31vqoLhvOyi3XgCercSQaaMPsmiHlXCxnIOYSNDi1gkbYpJRGHH0qoccfz9QOKLmhK0chy/s72-c/culebra.png" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4666066690462799055</guid><pubDate>Thu, 22 Feb 2018 04:53:00 +0000</pubDate><atom:updated>2018-02-21T23:53:41.555-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">alexa</category><category domain="http://www.blogger.com/atom/ns#">amazon</category><category domain="http://www.blogger.com/atom/ns#">automated testing</category><category domain="http://www.blogger.com/atom/ns#">aws</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">skill</category><category domain="http://www.blogger.com/atom/ns#">testing</category><category domain="http://www.blogger.com/atom/ns#">unit test</category><title>Testing Alexa Skills — Autogenerated tests</title><description>&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;You almost finished your Amazon Alexa Skill and are now started the quest for the Holy Grail of Alexa Testing. Now, you are desperately searching for a way to automate it. Even, googling it gave no obvious outcome.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Fortunately, your search is over.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFZ7poXINDUrmLy-RU6uk-iQirOY1hBvzZ3WAgi5Rpf9LBoj9tNDsLbHjDclSrgc_1FCxgIFxLhgv5KTkqPrYP6g-4rC30WHCrmakBl3JrHxEqCOyC6710PkiyF1uxWxuQm_St/s1600/robot_small.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;868&quot; data-original-width=&quot;1600&quot; height=&quot;215&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFZ7poXINDUrmLy-RU6uk-iQirOY1hBvzZ3WAgi5Rpf9LBoj9tNDsLbHjDclSrgc_1FCxgIFxLhgv5KTkqPrYP6g-4rC30WHCrmakBl3JrHxEqCOyC6710PkiyF1uxWxuQm_St/s400/robot_small.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Now we will be analyzing how we can automate the code generation of such tests. Because some of the details needed to create the tests are available in the Skill’s Interaction Model, we will leverage this to reduce to a bare minimum the information that you have to provide to create a test.&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Verdana, sans-serif;&quot;&gt;Check&amp;nbsp;&lt;b&gt;&lt;a href=&quot;https://medium.com/@dtmilano/testing-alexa-skills-autogenerated-tests-cf1c42d5fe0e&quot;&gt;Testing Alexa Skills — Autogenerated tests&lt;/a&gt; &lt;/b&gt;for more.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://dtmilano.blogspot.com/2018/02/testing-alexa-skillsautogenerated-tests.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFZ7poXINDUrmLy-RU6uk-iQirOY1hBvzZ3WAgi5Rpf9LBoj9tNDsLbHjDclSrgc_1FCxgIFxLhgv5KTkqPrYP6g-4rC30WHCrmakBl3JrHxEqCOyC6710PkiyF1uxWxuQm_St/s72-c/robot_small.jpg" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1652198521084622985</guid><pubDate>Thu, 25 Jan 2018 22:12:00 +0000</pubDate><atom:updated>2018-01-25T17:12:02.253-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">alexa</category><category domain="http://www.blogger.com/atom/ns#">amazon</category><category domain="http://www.blogger.com/atom/ns#">automated testing</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">skill</category><category domain="http://www.blogger.com/atom/ns#">testing</category><title>Testing Alexa Skills — The grail quest</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://cdn-images-1.medium.com/max/2000/1*6AFmq034kuGlGfRR3u6zRg.jpeg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;533&quot; data-original-width=&quot;800&quot; height=&quot;266&quot; src=&quot;https://cdn-images-1.medium.com/max/2000/1*6AFmq034kuGlGfRR3u6zRg.jpeg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
You almost finished your &lt;b&gt;Amazon Alexa Skill&lt;/b&gt; and are now started the quest for the &lt;i&gt;Holy Grail&lt;/i&gt; of &lt;b&gt;Alexa Testing&lt;/b&gt;. Now, you are desperately searching for a way to automate it. Even, googling it gave no obvious outcome.&lt;br /&gt;
Fortunately, your search is over.&lt;br /&gt;
&lt;br /&gt;
Read the article on medium:&amp;nbsp;&lt;a href=&quot;https://medium.com/@dtmilano/testing-alexa-skills-the-grail-quest-3beba82450bb&quot;&gt;https://medium.com/@dtmilano/testing-alexa-skills-the-grail-quest-3beba82450bb&lt;/a&gt;</description><link>http://dtmilano.blogspot.com/2018/01/testing-alexa-skillsthe-grail-quest.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-2015969112832334271</guid><pubDate>Fri, 08 Dec 2017 04:34:00 +0000</pubDate><atom:updated>2017-12-07T23:34:15.604-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">amazon</category><category domain="http://www.blogger.com/atom/ns#">aws</category><category domain="http://www.blogger.com/atom/ns#">bot</category><category domain="http://www.blogger.com/atom/ns#">github</category><category domain="http://www.blogger.com/atom/ns#">lex</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">testing</category><title>Creating conversational AWS Lex Bot tests</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgufZNZ0goVsgL0l0YALiq4T39JAruO1Jqg_lEBuyYWzoydKyRgWvMRkIwH4f59Bt6Aerzx5kTMRy2ehtiZmgwPVfnsPmmBWLTh3pnBU0WUXDTNllL55hy94oFPQO8vvOS_byBv/s1600/pexels-photo-595804.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1067&quot; data-original-width=&quot;1600&quot; height=&quot;266&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgufZNZ0goVsgL0l0YALiq4T39JAruO1Jqg_lEBuyYWzoydKyRgWvMRkIwH4f59Bt6Aerzx5kTMRy2ehtiZmgwPVfnsPmmBWLTh3pnBU0WUXDTNllL55hy94oFPQO8vvOS_byBv/s400/pexels-photo-595804.jpeg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
There exist several ways of testing &lt;b&gt;Amazon AWS Lex Bots&lt;/b&gt;, however, either they are manual or require low-level use of the PostContent method. We will introduce here a way of automating part of the process using python.&lt;br /&gt;
Read the article at&amp;nbsp;&lt;a href=&quot;https://medium.com/@dtmilano/creating-conversational-aws-lex-bot-tests-da84a83fe688&quot;&gt;creating-conversational-aws-lex-bot-tests&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</description><link>http://dtmilano.blogspot.com/2017/12/creating-conversational-aws-lex-bot.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgufZNZ0goVsgL0l0YALiq4T39JAruO1Jqg_lEBuyYWzoydKyRgWvMRkIwH4f59Bt6Aerzx5kTMRy2ehtiZmgwPVfnsPmmBWLTh3pnBU0WUXDTNllL55hy94oFPQO8vvOS_byBv/s72-c/pexels-photo-595804.jpeg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-3869953580451265078</guid><pubDate>Tue, 24 Oct 2017 03:27:00 +0000</pubDate><atom:updated>2017-10-23T23:40:04.158-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">test driven development</category><category domain="http://www.blogger.com/atom/ns#">test recorder</category><category domain="http://www.blogger.com/atom/ns#">tests</category><title>AndroidViewClient/culebra reached 300,000 downloads</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFt2sJ8mMy4uwL2G_9UsMH9bhVzqpRPiACNTbhqcTMhRDIvOE2i33wxcGdqW6N3Zr_WLRn3YHSFFxk_OyEd2WPEcke5Yr7YcwTCGB_AkUo0EEO8Cq4XTiSCXv5Cwd_WMYbmhYZ/s1600/avc-300K-800x300.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;300&quot; data-original-width=&quot;800&quot; height=&quot;150&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFt2sJ8mMy4uwL2G_9UsMH9bhVzqpRPiACNTbhqcTMhRDIvOE2i33wxcGdqW6N3Zr_WLRn3YHSFFxk_OyEd2WPEcke5Yr7YcwTCGB_AkUo0EEO8Cq4XTiSCXv5Cwd_WMYbmhYZ/s400/avc-300K-800x300.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;AndroidViewClient/culebra&lt;/b&gt;&lt;/a&gt; reached 300.000 downloads this month. After some time flying blind, since &lt;a href=&quot;https://pypi.python.org/pypi/androidviewclient/&quot; target=&quot;_blank&quot;&gt;PyPi&lt;/a&gt; statistic stopped working some time ago, this&amp;nbsp;great surprise was awaiting when the counts were restored, now implemented using &lt;a href=&quot;https://bigquery.cloud.google.com/queries/culebra-tester&quot; target=&quot;_blank&quot;&gt;BigQuery&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Thanks to all who made it possible.&lt;/span&gt;</description><link>http://dtmilano.blogspot.com/2017/10/androidviewclientculebra-reached-300000.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFt2sJ8mMy4uwL2G_9UsMH9bhVzqpRPiACNTbhqcTMhRDIvOE2i33wxcGdqW6N3Zr_WLRn3YHSFFxk_OyEd2WPEcke5Yr7YcwTCGB_AkUo0EEO8Cq4XTiSCXv5Cwd_WMYbmhYZ/s72-c/avc-300K-800x300.png" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-2734234969944150211</guid><pubDate>Wed, 28 Jun 2017 05:08:00 +0000</pubDate><atom:updated>2017-06-28T01:08:23.940-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">performance</category><category domain="http://www.blogger.com/atom/ns#">uiautomator</category><category domain="http://www.blogger.com/atom/ns#">unit test</category><title>Analyzing Android UI Performance</title><description>&lt;div class=&quot;graf graf--p graf-after--h3&quot; id=&quot;facf&quot; name=&quot;facf&quot; style=&quot;--baseline-multiplier: 0.179; background-color: white; color: rgba(0, 0, 0, 0.8); font-family: medium-content-serif-font, Georgia, Cambria, &amp;quot;Times New Roman&amp;quot;, Times, serif; letter-spacing: -0.003em; line-height: 1.58; margin-top: 10px;&quot;&gt;
&lt;em class=&quot;markup--em markup--p-em&quot; style=&quot;font-feature-settings: &#39;liga&#39; 1, &#39;salt&#39; 1;&quot;&gt;Integrating UI Performance into your testing practices&amp;nbsp;&lt;/em&gt;guarantees&lt;em class=&quot;markup--em markup--p-em&quot; style=&quot;font-feature-settings: &#39;liga&#39; 1, &#39;salt&#39; 1;&quot;&gt;&amp;nbsp;interaction with your applications satisfies users’ demands.&lt;/em&gt;&lt;/div&gt;
&lt;div class=&quot;graf graf--p graf-after--h3&quot; id=&quot;facf&quot; name=&quot;facf&quot; style=&quot;--baseline-multiplier: 0.179; background-color: white; color: rgba(0, 0, 0, 0.8); font-family: medium-content-serif-font, Georgia, Cambria, &amp;quot;Times New Roman&amp;quot;, Times, serif; letter-spacing: -0.003em; line-height: 1.58; margin-top: 10px;&quot;&gt;
&lt;em class=&quot;markup--em markup--p-em&quot; style=&quot;font-feature-settings: &#39;liga&#39; 1, &#39;salt&#39; 1;&quot;&gt;&lt;br /&gt;&lt;/em&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsbjlG6uCFYPhsu0yU9haRrGuXycmQ1yDZ70DnnmQjJJPTVBuGol8SarzG_rk7pONrDsJuzTAtVYu6Ecdex7I6oiSKAuM4L90Oc7-8gaHHaP0JXlWSuQmZ3Wl4h4_tFp_DYclJ/s1600/Screen+Shot+2017-06-27+at+19.34.41.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;636&quot; data-original-width=&quot;1483&quot; height=&quot;171&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsbjlG6uCFYPhsu0yU9haRrGuXycmQ1yDZ70DnnmQjJJPTVBuGol8SarzG_rk7pONrDsJuzTAtVYu6Ecdex7I6oiSKAuM4L90Oc7-8gaHHaP0JXlWSuQmZ3Wl4h4_tFp_DYclJ/s400/Screen+Shot+2017-06-27+at+19.34.41.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span class=&quot;markup--em markup--p-em&quot; style=&quot;font-feature-settings: &#39;liga&#39; 1, &#39;salt&#39; 1;&quot;&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;Read the step by step guide:&amp;nbsp;&lt;a href=&quot;https://medium.com/@dtmilano/analyzing-android-ui-performance-52beb577c421&quot;&gt;https://medium.com/@dtmilano/analyzing-android-ui-performance-52beb577c421&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;</description><link>http://dtmilano.blogspot.com/2017/06/analyzing-android-ui-performance.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsbjlG6uCFYPhsu0yU9haRrGuXycmQ1yDZ70DnnmQjJJPTVBuGol8SarzG_rk7pONrDsJuzTAtVYu6Ecdex7I6oiSKAuM4L90Oc7-8gaHHaP0JXlWSuQmZ3Wl4h4_tFp_DYclJ/s72-c/Screen+Shot+2017-06-27+at+19.34.41.png" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4995303196817112430</guid><pubDate>Fri, 16 Jun 2017 05:49:00 +0000</pubDate><atom:updated>2017-06-16T01:49:36.083-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><category domain="http://www.blogger.com/atom/ns#">test driven development</category><title>Your first Android Kotlin test</title><description>&lt;em class=&quot;markup--em markup--p-em&quot; style=&quot;background-color: white; color: rgba(0, 0, 0, 0.8); font-family: medium-content-serif-font, Georgia, Cambria, &amp;quot;Times New Roman&amp;quot;, Times, serif; font-feature-settings: &#39;liga&#39; 1, &#39;salt&#39; 1; font-size: 21px; letter-spacing: -0.063px;&quot;&gt;The best part, you don’t have to know Kotlin as the test will be automatically generated for you.&lt;/em&gt;&lt;br /&gt;
&lt;em class=&quot;markup--em markup--p-em&quot; style=&quot;background-color: white; color: rgba(0, 0, 0, 0.8); font-family: medium-content-serif-font, Georgia, Cambria, &amp;quot;Times New Roman&amp;quot;, Times, serif; font-feature-settings: &#39;liga&#39; 1, &#39;salt&#39; 1; font-size: 21px; letter-spacing: -0.063px;&quot;&gt;&lt;br /&gt;&lt;/em&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-SNKdqTNLBDC1UeiZ0UQ10XQEhanKfXTguo-4eUojf-7FOqM_ABnuJGdt6x9_FLRpqyuaucCzMLjCrQD_tdNi21K0UPVP1NoyyjnYycxHYv97F1WR5FLnDtzT1W7fWhmhl3sn/s1600/Screen+Shot+2017-06-06+at+18.19.39.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1169&quot; data-original-width=&quot;1600&quot; height=&quot;291&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-SNKdqTNLBDC1UeiZ0UQ10XQEhanKfXTguo-4eUojf-7FOqM_ABnuJGdt6x9_FLRpqyuaucCzMLjCrQD_tdNi21K0UPVP1NoyyjnYycxHYv97F1WR5FLnDtzT1W7fWhmhl3sn/s400/Screen+Shot+2017-06-06+at+18.19.39.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif; font-size: large;&quot;&gt;Read the step by step guide:&amp;nbsp;&lt;a href=&quot;https://medium.com/@dtmilano/your-first-android-kotlin-test-fe007ec41bc5&quot;&gt;https://medium.com/@dtmilano/your-first-android-kotlin-test-fe007ec41bc5&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;em class=&quot;markup--em markup--p-em&quot; style=&quot;background-color: white; color: rgba(0, 0, 0, 0.8); font-family: medium-content-serif-font, Georgia, Cambria, &amp;quot;Times New Roman&amp;quot;, Times, serif; font-feature-settings: &#39;liga&#39; 1, &#39;salt&#39; 1; font-size: 21px; letter-spacing: -0.063px;&quot;&gt;&lt;br /&gt;&lt;/em&gt;</description><link>http://dtmilano.blogspot.com/2017/06/your-first-android-kotlin-test.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-SNKdqTNLBDC1UeiZ0UQ10XQEhanKfXTguo-4eUojf-7FOqM_ABnuJGdt6x9_FLRpqyuaucCzMLjCrQD_tdNi21K0UPVP1NoyyjnYycxHYv97F1WR5FLnDtzT1W7fWhmhl3sn/s72-c/Screen+Shot+2017-06-06+at+18.19.39.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-3685452430454245070</guid><pubDate>Tue, 06 Jun 2017 22:49:00 +0000</pubDate><atom:updated>2017-06-06T18:49:26.603-04:00</atom:updated><title>CulebraTester: Android Kotlin test generation</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwGi4FqhE9rIM0uDLLkxjZ-bWI_oGV_8O9giySAAjZBuArwHIJGbkGqFTt9kgbWCuNB7CqG5T3fGAohel6UxpSV7ewXOqrFAulGsCD2az31orwW1dJipF9CQD71xYflzNftDZS/s1600/Screen+Shot+2017-06-06+at+18.19.39.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1169&quot; data-original-width=&quot;1600&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwGi4FqhE9rIM0uDLLkxjZ-bWI_oGV_8O9giySAAjZBuArwHIJGbkGqFTt9kgbWCuNB7CqG5T3fGAohel6UxpSV7ewXOqrFAulGsCD2az31orwW1dJipF9CQD71xYflzNftDZS/s400/Screen+Shot+2017-06-06+at+18.19.39.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;Recently, Kotlin was made an official language on Android.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;It&#39;s very easy to get started using Kotlin as it works side by side with Java and C++ on Android.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;However, there are new syntax and new language features to learn, even more, when we talk about testing and creating tests for your application UI.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;You can gradually introduce Kotlin code to your project as it can coexist&amp;nbsp;with existing code and Android libraries.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;So, what&#39;s better than start incrementally adding Kotlin to your workflow starting by the tests?&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;And what is even better is that &lt;a href=&quot;http://culebra.dtmilano.com/&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;CulebraTester v0.9.0&lt;/b&gt;&lt;/a&gt; introduces Kotlin code generation as can be seen in the previous screenshot.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;You can start learning Kotlin now by taking a look at the generated code.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;As always, you can find more information about Open Source&amp;nbsp;&lt;/span&gt;&lt;b style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;AndroidViewClient/culebra&lt;/b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&amp;nbsp;in its wiki at&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki&quot; style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;https://github.com/dtmilano/AndroidViewClient/wiki&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;, about&amp;nbsp;&lt;/span&gt;&lt;b style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;CulebraTester&lt;/b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&amp;nbsp;at&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://culebra.dtmilano.com/&quot; style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;http://culebra.dtmilano.com/&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&amp;nbsp;and&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/dtmilano/CulebraTester-public/wiki&quot; style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;https://github.com/dtmilano/CulebraTester-public/wiki&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&amp;nbsp;and if you have any question you can ask in&amp;nbsp;&lt;/span&gt;&lt;b style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;Stackoverflow&lt;/b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&amp;nbsp;using&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://stackoverflow.com/questions/tagged/androidviewclient&quot; style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;http://stackoverflow.com/questions/tagged/androidviewclient&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;.&lt;/span&gt;</description><link>http://dtmilano.blogspot.com/2017/06/culebratester-android-kotlin-test.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwGi4FqhE9rIM0uDLLkxjZ-bWI_oGV_8O9giySAAjZBuArwHIJGbkGqFTt9kgbWCuNB7CqG5T3fGAohel6UxpSV7ewXOqrFAulGsCD2az31orwW1dJipF9CQD71xYflzNftDZS/s72-c/Screen+Shot+2017-06-06+at+18.19.39.png" height="72" width="72"/><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-6901298121820829646</guid><pubDate>Mon, 03 Apr 2017 00:06:00 +0000</pubDate><atom:updated>2017-04-02T20:06:13.983-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">performance</category><category domain="http://www.blogger.com/atom/ns#">tests</category><title>Testing Android UI Performance</title><description>&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;In a previous post, we were analyzing how to &lt;a href=&quot;http://dtmilano.blogspot.com/2017/03/detecting-memory-leaks-on-android-apps.html&quot;&gt;Detect&amp;nbsp;memory leaks on Android apps&lt;/a&gt;. That is a very important&amp;nbsp;step in testing and analyzing your application&#39;s performance.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;Once you are done, you may want to sure that user interactions with your app are smooth, and they run at a consistent &lt;b&gt;60 frames per second&lt;/b&gt; mark.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;We will explain here how &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot;&gt;AndroidViewClient/culebra&lt;/a&gt; can help automating and simplifying&amp;nbsp;some steps that usually require manual interaction. In such way, you can measure UI performance, and produce charts that will help you understand and locate the problems&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;Latest&amp;nbsp;&lt;b&gt;AndroidViewClient/culebra&lt;/b&gt;&amp;nbsp;versions have introduced the ability to plot some metrics from your device or emulator directly. The Dumpsys&amp;nbsp;module obtains and parses dumpsys&amp;nbsp;information to greatly&amp;nbsp;facilitate its usage converting it to objects.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6; font-family: &#39;Monaco&#39;; font-size: 13.5pt;&quot;&gt;
&lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;__plot_dumpsys_gfxinfo&lt;/span&gt;(&lt;span style=&quot;color: #94558d;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;pkg):&lt;br /&gt;    &lt;span style=&quot;color: #94558d;&quot;&gt;&amp;nbsp; &amp;nbsp; self&lt;/span&gt;.plot.append(Dumpsys(&lt;span style=&quot;color: #94558d;&quot;&gt;self&lt;/span&gt;.device&lt;span style=&quot;color: #cc7832;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #344134;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Dumpsys&lt;/span&gt;.GFXINFO&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;pkg&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;background-color: #344134;&quot;&gt;Dumpsys&lt;/span&gt;.FRAMESTATS)) \&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; .plot(&lt;span style=&quot;color: #aa4926;&quot;&gt;_type&lt;/span&gt;=&lt;span style=&quot;background-color: #344134;&quot;&gt;Dumpsys&lt;/span&gt;.FRAMESTATS)&lt;/div&gt;
&lt;br /&gt;&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;This helper method (that can be found in AndroidViewClient/culebra tests) appends to the plot the &lt;b class=&quot;&quot;&gt;framestats&lt;/b&gt; information obtained from &lt;b class=&quot;&quot;&gt;dumpsys&amp;nbsp;gfxinfo&lt;/b&gt; for the given package &lt;b&gt;pkg&lt;/b&gt;. Then it creates the histogram chart.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;This first chart shows the information obtained by running OPEN LIST VIEW from &lt;a href=&quot;https://codelabs.developers.google.com/codelabs/android-perf-testing/index.html?index=..%2F..%2Findex#0&quot; target=&quot;_blank&quot;&gt;Automated Performance Testing&lt;/a&gt;&amp;nbsp;after scrolling the lists.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKI0vuvIwUh8pTtLbcMwCY1SFy49P-qpvBPGwsTiiAxmRrn7Daf7s9SIi-dIp-j_xWnr6mJc8oCF-Vs_2mVg8hRornr-s1tOfa6nn-lNohwM9tajgIftF1HUMjpeDCl9cfTAYg/s1600/figure_1.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;300&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKI0vuvIwUh8pTtLbcMwCY1SFy49P-qpvBPGwsTiiAxmRrn7Daf7s9SIi-dIp-j_xWnr6mJc8oCF-Vs_2mVg8hRornr-s1tOfa6nn-lNohwM9tajgIftF1HUMjpeDCl9cfTAYg/s400/figure_1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&amp;nbsp;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;This second chart is then obtained by running OPEN RECYCLER VIEW from the same example.&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJwWZyrhRprNxwU0kVLC7igmWEsko43bWzNt-tsAWfYDNpK2XOGFKRPzWckzCah32SY04SxctAZuZ0mrbk6ZjWFWBEj3Xia41PnzJuFvI-5gKxVbEV6VLF6MXXVRV5w-dMIILh/s1600/figure_2.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;300&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJwWZyrhRprNxwU0kVLC7igmWEsko43bWzNt-tsAWfYDNpK2XOGFKRPzWckzCah32SY04SxctAZuZ0mrbk6ZjWFWBEj3Xia41PnzJuFvI-5gKxVbEV6VLF6MXXVRV5w-dMIILh/s400/figure_2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;The vertical lines indicate 60 and 30 FPS respectively.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;In this case, the improvements made by the RecyclerView are obvious.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;As always, you can find more information about&amp;nbsp;&lt;/span&gt;&lt;b style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;AndroidViewClient/culebra&lt;/b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;&amp;nbsp;in its wiki at&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki&quot; style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;https://github.com/dtmilano/AndroidViewClient/wiki&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;, about&amp;nbsp;&lt;/span&gt;&lt;b style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;CulebraTester&lt;/b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;&amp;nbsp;at&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://culebra.dtmilano.com/&quot; style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;http://culebra.dtmilano.com/&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;&amp;nbsp;and&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://github.com/dtmilano/CulebraTester-public/wiki&quot; style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;https://github.com/dtmilano/CulebraTester-public/wiki&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;&amp;nbsp;and if you have any question you can ask in&amp;nbsp;&lt;/span&gt;&lt;b style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;Stackoverflow&lt;/b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;&amp;nbsp;using&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;http://stackoverflow.com/questions/tagged/androidviewclient&quot; style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;http://stackoverflow.com/questions/tagged/androidviewclient&lt;/a&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot;, sans-serif;&quot;&gt;.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
</description><link>http://dtmilano.blogspot.com/2017/04/testing-android-ui-performance.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKI0vuvIwUh8pTtLbcMwCY1SFy49P-qpvBPGwsTiiAxmRrn7Daf7s9SIi-dIp-j_xWnr6mJc8oCF-Vs_2mVg8hRornr-s1tOfa6nn-lNohwM9tajgIftF1HUMjpeDCl9cfTAYg/s72-c/figure_1.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-8499341613540495992</guid><pubDate>Fri, 17 Mar 2017 05:24:00 +0000</pubDate><atom:updated>2017-03-17T01:24:29.565-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">stackoverflow</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">uiautomator</category><title>Detecting memory leaks on Android apps</title><description>&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;More often than&amp;nbsp;it should you find yourself wondering if your application is leaking memory and if so what, where and how.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;A lot of questions that usually don&#39;t have enough answers.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;There are many well know ways your application can leak memory. To name a few&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;static references to Contexts, Views or Activities&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;inner classes holding a reference to the outer class&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;anonymous classes, commonly used in listeners&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;drawables&amp;nbsp;holding a reference to the Context&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;and many more cases&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;If you are interested in more detailed descriptions of these common ways your app can leak memory this &lt;a href=&quot;https://developer.android.com/studio/profile/investigate-ram.html&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt; will help you.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;Also, as there are pitfalls there are tools to help you find them. Again, to name a few&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;Android Studio monitors&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;dalvik&amp;nbsp;and art GC log messages&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;heap dumps&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;dumpsys&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;etc.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;To do an effective use of these tools and uncover memory leaks you should stress your app, running it for a while, or forcing continuous invocations of Activities, perhaps navigation back to the Home screen and launching the Activity again and again. While you can do this manually and the most obvious cases will be detected, it is always more efficient to automate these steps so they can be run before and after to verify that you actually solved the problem.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;And what better than &lt;/span&gt;&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot; style=&quot;font-family: &amp;quot;Trebuchet MS&amp;quot;, sans-serif;&quot;&gt;&lt;b&gt;AndroidViewClient/culebra&lt;/b&gt;&lt;/a&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&amp;nbsp;to automate these steps as we have discussed so many times in previous articles. Precisely, one of the latest&amp;nbsp;additions is the ability to capture &lt;/span&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;dumpsys&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&amp;nbsp;information and create plots with it.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;This is an example of a method we can define to exercise&amp;nbsp;our Activities including some extra steps like stopping the application to start clean and forcing garbage collection along the way (see complete source code &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/blob/master/tests/com/dtmilano/android/plottests.py&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;pre style=&quot;background-color: #2b2b2b; color: #a9b7c6; font-family: Monaco;&quot;&gt;&lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;def &lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;__plot_dumpsys_meminfo&lt;/span&gt;(&lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;pkg&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;activity&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;method=&lt;span style=&quot;color: #8888c6;&quot;&gt;None&lt;/span&gt;):
    &lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.device.shell(&lt;span style=&quot;color: #a5c261;&quot;&gt;&quot;am force-stop %s&quot; &lt;/span&gt;% pkg)
    &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;for &lt;/span&gt;n &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;in &lt;/span&gt;&lt;span style=&quot;color: #8888c6;&quot;&gt;range&lt;/span&gt;(&lt;span style=&quot;color: #6897bb;&quot;&gt;20&lt;/span&gt;):
        &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;if &lt;/span&gt;n % &lt;span style=&quot;color: #6897bb;&quot;&gt;5 &lt;/span&gt;== &lt;span style=&quot;color: #6897bb;&quot;&gt;0&lt;/span&gt;:
            &lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.device.shell(
                &lt;span style=&quot;color: #a5c261;&quot;&gt;&quot;run-as %s pgrep -L 10 %s&quot; &lt;/span&gt;% (pkg&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;pkg))
        &lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.device.startActivity(&lt;span style=&quot;color: #a5c261;&quot;&gt;&quot;%s/%s&quot; &lt;/span&gt;% (pkg&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;activity))
        time.sleep(&lt;span style=&quot;color: #6897bb;&quot;&gt;2&lt;/span&gt;)
        &lt;span style=&quot;color: #cc7832; font-weight: bold;&quot;&gt;if &lt;/span&gt;method:
            method()
        &lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.plot.append(Dumpsys(&lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.device&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;Dumpsys.MEMINFO&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;pkg))
        &lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.device.press(&lt;span style=&quot;color: #a5c261;&quot;&gt;&#39;BACK&#39;&lt;/span&gt;)
        time.sleep(&lt;span style=&quot;color: #6897bb;&quot;&gt;0.5&lt;/span&gt;)
        &lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.device.press(&lt;span style=&quot;color: #a5c261;&quot;&gt;&#39;BACK&#39;&lt;/span&gt;)
        time.sleep(&lt;span style=&quot;color: #6897bb;&quot;&gt;0.5&lt;/span&gt;)
        &lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.device.press(&lt;span style=&quot;color: #a5c261;&quot;&gt;&#39;HOME&#39;&lt;/span&gt;)
        time.sleep(&lt;span style=&quot;color: #6897bb;&quot;&gt;0.5&lt;/span&gt;)
    &lt;span style=&quot;background-color: #344134;&quot;&gt;self&lt;/span&gt;.plot.plot()&lt;/pre&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;With every iteration, we are collecting the &lt;/span&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;dumpsys&amp;nbsp;meminfo&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&amp;nbsp;for the process, exiting the app by sending BACK and returning to Home, and at the end, we plot the chart.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-t_OSz23Q8_yX8Q3-hY_PkGNnL23ilxQuZ4aowWjKqhPDjAB0JZnRSi0WOQ5aWjI933YJApQQDs3itcjNHTQJxYpxAU6PycTmlynjcGbt_4tW6LMAlWfoVBqLyv71HSi_s3yP/s1600/plot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-t_OSz23Q8_yX8Q3-hY_PkGNnL23ilxQuZ4aowWjKqhPDjAB0JZnRSi0WOQ5aWjI933YJApQQDs3itcjNHTQJxYpxAU6PycTmlynjcGbt_4tW6LMAlWfoVBqLyv71HSi_s3yP/s400/plot.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;We can easily see that while we are forcing GC the amount of memory used, the number of Activities and Views are constantly&amp;nbsp;increasing.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;As always, you can find more information about &lt;b&gt;AndroidViewClient/culebra&lt;/b&gt;&amp;nbsp;in its wiki at&amp;nbsp;&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki&quot;&gt;https://github.com/dtmilano/AndroidViewClient/wiki&lt;/a&gt;, about &lt;b&gt;CulebraTester&lt;/b&gt; at&amp;nbsp;&lt;a href=&quot;http://culebra.dtmilano.com/&quot;&gt;http://culebra.dtmilano.com/&lt;/a&gt; and&amp;nbsp;&lt;a href=&quot;https://github.com/dtmilano/CulebraTester-public/wiki&quot;&gt;https://github.com/dtmilano/CulebraTester-public/wiki&lt;/a&gt; and if you have any question you can ask in &lt;b&gt;Stackoverflow&lt;/b&gt; using&amp;nbsp;&lt;a href=&quot;http://stackoverflow.com/questions/tagged/androidviewclient&quot;&gt;http://stackoverflow.com/questions/tagged/androidviewclient&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;Hope this help you spot some leaks in your app.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Trebuchet MS, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;</description><link>http://dtmilano.blogspot.com/2017/03/detecting-memory-leaks-on-android-apps.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-t_OSz23Q8_yX8Q3-hY_PkGNnL23ilxQuZ4aowWjKqhPDjAB0JZnRSi0WOQ5aWjI933YJApQQDs3itcjNHTQJxYpxAU6PycTmlynjcGbt_4tW6LMAlWfoVBqLyv71HSi_s3yP/s72-c/plot.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1452335969403980370</guid><pubDate>Thu, 27 Oct 2016 22:16:00 +0000</pubDate><atom:updated>2016-10-28T00:53:14.764-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">Browser</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">emulator</category><category domain="http://www.blogger.com/atom/ns#">espresso</category><category domain="http://www.blogger.com/atom/ns#">google chrome</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><category domain="http://www.blogger.com/atom/ns#">test driven development</category><category domain="http://www.blogger.com/atom/ns#">test recorder</category><category domain="http://www.blogger.com/atom/ns#">tests</category><title>CulebraTester Calculator Demo</title><description>&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;344&quot; src=&quot;https://www.youtube.com/embed/TeJNBU_5TAg&quot; width=&quot;459&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #606c71; font-family: &amp;quot;Open Sans&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-size: 17.6px;&quot;&gt;Android testing can be complicated, time-consuming, and tedious. What if it didn’t have to be?&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #606c71; font-family: &amp;quot;Open Sans&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-size: 17.6px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #606c71; font-family: &amp;quot;Open Sans&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-size: 17.6px;&quot;&gt;&lt;a href=&quot;http://culebra.dtmilano.com/&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;CulebraTester&lt;/b&gt;&lt;/a&gt; provides a real-time point and click test recording through a web browser.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #606c71; font-family: &amp;quot;Open Sans&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-size: 17.6px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;color: #606c71; font-family: &amp;quot;Open Sans&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-size: 17.6px;&quot;&gt;We are currently in private beta, so if you are interested in participating of this programme please fill the&amp;nbsp;&lt;/span&gt;&lt;b style=&quot;box-sizing: border-box; color: #606c71; font-family: &amp;quot;Open Sans&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-size: 17.6px; margin-top: 0px;&quot;&gt;&lt;a href=&quot;http://goo.gl/forms/aqLL7ni6NH&quot; style=&quot;box-sizing: border-box; color: #1e6bb8; margin-top: 0px; text-decoration: none;&quot;&gt;opt-in form&lt;/a&gt;&lt;/b&gt;&lt;span style=&quot;color: #606c71; font-family: &amp;quot;Open Sans&amp;quot;, &amp;quot;Helvetica Neue&amp;quot;, Helvetica, Arial, sans-serif; font-size: 17.6px;&quot;&gt;&amp;nbsp;and we will be adding your account as soon as possible.&amp;nbsp;&lt;/span&gt;</description><link>http://dtmilano.blogspot.com/2016/10/culebratester-calculator-demo.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/TeJNBU_5TAg/default.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1536050338303727391</guid><pubDate>Mon, 01 Aug 2016 22:18:00 +0000</pubDate><atom:updated>2016-08-13T15:08:20.746-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">imerj</category><category domain="http://www.blogger.com/atom/ns#">superbook</category><title>Turns your Android smartphone into a complete laptop</title><description>I do not usually mention third party products in this blog unless there is a very good reason. The &lt;a href=&quot;https://www.kickstarter.com/projects/andromium/the-superbook-turn-your-smartphone-into-a-laptop-f&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Superbook&lt;/a&gt;&amp;nbsp;certainly is one of those. &amp;nbsp;It is a smart laptop shell that provides a large screen, keyboard and multi-touch trackpad, 8+ hours of battery, and phone charging capabilities. When plugged into your Android smartphone, it launches our app to deliver the full laptop experience.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9eqrXFzA4IvRzn3ofaC_wDSDD7Ux3_XFiS2HrPQCh1c0ktI25tTBrgNzHUY-2EYmfnrkGNw2kIAc8ocK_lhUb-tYtmWIKipYGgNzxG3rN4JolD62e4vrrHS3wP6LUvyNu0mxh/s1600/superbook.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9eqrXFzA4IvRzn3ofaC_wDSDD7Ux3_XFiS2HrPQCh1c0ktI25tTBrgNzHUY-2EYmfnrkGNw2kIAc8ocK_lhUb-tYtmWIKipYGgNzxG3rN4JolD62e4vrrHS3wP6LUvyNu0mxh/s320/superbook.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
The idea of using the same core device for your mobile and desktop experiences has been tried before, but this time, the Superbook gives it a twist and uses a full Android desktop. This is mainly possible due to the huge improvement lastest Android versions received in areas as &lt;a href=&quot;https://developer.android.com/preview/features/multi-window.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;multi-window support&lt;/a&gt;, &amp;nbsp;&lt;a href=&quot;https://developer.android.com/preview/features/afw.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Android for work&lt;/a&gt;&amp;nbsp;and Keyboard Shortcuts screen that surely move &amp;nbsp;the platform in the desktop direction.&lt;br /&gt;
&lt;br /&gt;
That was not true some years ago. 6 years to be more precise, when one of the projects I was part of implemented the same concept but in the opposite direction I would say.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;A mobile computing device with a mobile operating system and desktop operating system running concurrently and independently on a shared kernel without virtualization. The mobile operating system provides a user experience for the mobile computing device that suits the mobile environment. The desktop operating system provides a full desktop user experience when the mobile computing device is docked to a secondary terminal environment. The mobile computing device was a smartphone running the Android mobile OS and a full desktop Linux distribution (Ubuntu) on a modified Android kernel.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9JE7_degLnaTgy3mA8oSA_gea_ntq9pwz6lJlOgQEhhIh2yoHr4leWsoVE4ga6Mqbm5J4Xwjfuv6Uf3l8QtMwPwbR1erSjOHqiqt_RdI9V3IRzaWTjHmGCfypbp5xUdt2zT2X/s1600/Screen+Shot+2016-08-01+at+18.06.41.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;214&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9JE7_degLnaTgy3mA8oSA_gea_ntq9pwz6lJlOgQEhhIh2yoHr4leWsoVE4ga6Mqbm5J4Xwjfuv6Uf3l8QtMwPwbR1erSjOHqiqt_RdI9V3IRzaWTjHmGCfypbp5xUdt2zT2X/s320/Screen+Shot+2016-08-01+at+18.06.41.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The concept included also a Smart book where you could dock your device.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidE1s2f2HLTTwuFROesaon7ledcG_lbawk_G2LgFV-IxZ8MfnKdGQRAwpqngNZ47kwiSylBfnIjXaTJhb2cc4yeYkvP3qUY7VOxXP4MCLxBNMY9KjnMXCfOojFCK9j6c9lAD9q/s1600/imerj-smart-book.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;180&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidE1s2f2HLTTwuFROesaon7ledcG_lbawk_G2LgFV-IxZ8MfnKdGQRAwpqngNZ47kwiSylBfnIjXaTJhb2cc4yeYkvP3qUY7VOxXP4MCLxBNMY9KjnMXCfOojFCK9j6c9lAD9q/s320/imerj-smart-book.jpeg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Unfortunately, this project was later discontinued.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
As I mentioned, a lot has changed in these last 6 years on Android and devices are much more powerful now to support this approach so take a look at &lt;a href=&quot;https://www.kickstarter.com/projects/andromium/the-superbook-turn-your-smartphone-into-a-laptop-f&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;Superbook&lt;/a&gt; as it might change your mobile and desktop experiences.&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://dtmilano.blogspot.com/2016/08/turns-your-android-smartphone-into.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9eqrXFzA4IvRzn3ofaC_wDSDD7Ux3_XFiS2HrPQCh1c0ktI25tTBrgNzHUY-2EYmfnrkGNw2kIAc8ocK_lhUb-tYtmWIKipYGgNzxG3rN4JolD62e4vrrHS3wP6LUvyNu0mxh/s72-c/superbook.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-2068891751921886530</guid><pubDate>Fri, 20 May 2016 21:09:00 +0000</pubDate><atom:updated>2016-05-20T17:11:51.485-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">espresso</category><category domain="http://www.blogger.com/atom/ns#">test recorder</category><title>No Espresso Test Recorder in Android Studio 2.2</title><description>&lt;span style=&quot;background-color: white; color: #333333; font-family: &amp;quot;roboto&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif; font-size: 13px; line-height: 16px; white-space: pre-wrap;&quot;&gt;After all the frustration you may have experienced after discovering that &lt;b&gt;Espresso Test Recorder&lt;/b&gt; is not in &lt;b&gt;Android Studio 2.2&lt;/b&gt; as announced in Google IO/16 presentation (see &lt;a href=&quot;https://code.google.com/p/android/issues/detail?id=210478&quot;&gt;https://code.google.com/p/android/issues/detail?id=210478&lt;/a&gt;) you can have something to play with today. Sign up for &lt;b&gt;CulebraTester&lt;/b&gt; private beta see &lt;/span&gt;&lt;span style=&quot;color: #333333; font-family: &amp;quot;roboto&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 13px; line-height: 16px; white-space: pre-wrap;&quot;&gt;&lt;a href=&quot;http://dtmilano.blogspot.ca/2016/05/culebratester-private-beta-opt-in.html&quot;&gt;opt-in form&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #333333; font-family: &amp;quot;roboto&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 13px; line-height: 16px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe allowfullscreen=&quot;&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/EuAX9T6yppE/0.jpg&quot; frameborder=&quot;0&quot; height=&quot;266&quot; src=&quot;https://www.youtube.com/embed/EuAX9T6yppE?feature=player_embedded&quot; width=&quot;320&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;span style=&quot;color: #333333; font-family: &amp;quot;roboto&amp;quot; , &amp;quot;arial&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;font-size: 13px; line-height: 16px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;</description><link>http://dtmilano.blogspot.com/2016/05/no-espresso-test-recorder-in-android.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img.youtube.com/vi/EuAX9T6yppE/default.jpg" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-3692550925826384433</guid><pubDate>Sat, 14 May 2016 16:50:00 +0000</pubDate><atom:updated>2016-05-14T12:50:14.343-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">continuous integration</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">uiautomator</category><title>CulebraTester Private Beta Opt-in</title><description>&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Android testing can be complicated, time-consuming, and tedious.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;What if it didn’t have to be?&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;CulebraTester&lt;/b&gt; provides a real-time point and click test recording through a web browser. This browser is connected to the Android device under test. Not sure what we mean?&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Visit &lt;a href=&quot;http://culebra.dtmilano.com/&quot;&gt;culebra.dtmilano.com&lt;/a&gt; for details.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;If you are interested in being part of the &lt;b&gt;Private Beta&lt;/b&gt; please fill out this form.﻿&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;

&lt;iframe frameborder=&quot;0&quot; height=&quot;500&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; src=&quot;https://docs.google.com/forms/d/1GIxANl0AOqKugCVlRD6VvR4vMNfCV2YA0CR_zoPI-4A/viewform?embedded=true&quot; width=&quot;600&quot;&gt;Loading...&lt;/iframe&gt;</description><link>http://dtmilano.blogspot.com/2016/05/culebratester-private-beta-opt-in.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-6287765057766055935</guid><pubDate>Tue, 22 Dec 2015 19:31:00 +0000</pubDate><atom:updated>2015-12-22T14:31:43.412-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">chimpchat</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">jython</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">screenshot</category><category domain="http://www.blogger.com/atom/ns#">stackoverflow</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">uiautomator</category><title>AndroidViewClient/culebra vs. MonkeyRunner</title><description>More than 2 years ago I took a crucial decision in &lt;b&gt;&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot; target=&quot;_blank&quot;&gt;AndroidViewClient/culebra&lt;/a&gt;&lt;/b&gt; development plan and that was to free it from `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;monkeyrunner&lt;/b&gt;&lt;/span&gt;`, Jython and Chimpchat.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;AndroidViewClient/culebra&lt;/b&gt; was liberated and starting with version &lt;b&gt;4.0.0&lt;/b&gt; it does not require any other runtime environment than python 2.x (read &lt;a href=&quot;http://dtmilano.blogspot.ca/2013/08/androidviewclientculebra-version-400.html&quot; target=&quot;_blank&quot;&gt;announcement&lt;/a&gt;). It can be installed and upgraded using the corresponding platform tools like &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;easy_install&lt;/b&gt;&lt;/span&gt; or &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;pip&lt;/b&gt;&lt;/span&gt; and can be easily integrated into IDEs like Eclipse PyDev or Pycharm. It also improves speed, solves &lt;a href=&quot;https://code.google.com/p/android/issues/detail?id=58912&quot; target=&quot;_blank&quot;&gt;chimpchat bugs&lt;/a&gt;, and even provides a &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/Culebra-GUI&quot; target=&quot;_blank&quot;&gt;GUI&lt;/a&gt;&amp;nbsp;whre you can automatically create tests or scripts without writing a single line of code.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvKI5nn1oDEToj-3qdDZIuawYDZBVnmVtV3tsh8hQy1KXUCaSD5wLRCx681IUEbBC1z3jLCX6oDnrJ3EG9JspvrJDrcUSiZ05VWxmwYxFeIRNqYPeIvZ0yl3T2vOI9aF9m1OoE/s1600/400000000000000-com_duolingo-com_duolingo_app_WelcomeFlowActivity-2015-12-22T12%253A04%253A56.932602.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvKI5nn1oDEToj-3qdDZIuawYDZBVnmVtV3tsh8hQy1KXUCaSD5wLRCx681IUEbBC1z3jLCX6oDnrJ3EG9JspvrJDrcUSiZ05VWxmwYxFeIRNqYPeIvZ0yl3T2vOI9aF9m1OoE/s320/400000000000000-com_duolingo-com_duolingo_app_WelcomeFlowActivity-2015-12-22T12%253A04%253A56.932602.png&quot; width=&quot;182&quot; /&gt;&lt;/a&gt;Nonetheless, from time to time, I receive some questions or reports about problems with scripts created with `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;culebra&lt;/b&gt;&lt;/span&gt;` that are attempted to run with `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;monkeyrunner&lt;/b&gt;&lt;/span&gt;` or some other combinations. I take the blame for it. I failed at communicating that &lt;b&gt;AndroidViewClient/culebra&lt;/b&gt; is a complete replacement and should not be used together.&lt;br /&gt;
&lt;br /&gt;
In order to improve the situation I gave a very detailed, easy to follow, step-by-step answer to&lt;br /&gt;
&lt;a href=&quot;http://stackoverflow.com/questions/34400803/erro-of-script-with-monkeyrunner-and-androidviewclient-touch&quot; target=&quot;_blank&quot;&gt;Error of Script with MonkeyRunner and AndroidViewClient (Touch)&lt;/a&gt;&amp;nbsp;on Stackoverflow, showing how you can create a test case that automatically starts.and Activity (Duolingo) , checks if some Views are on the screen, touches them and finally take the screenshot. All from the GUI.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I hope you find this explanation useful.&lt;/div&gt;
&lt;/div&gt;
</description><link>http://dtmilano.blogspot.com/2015/12/androidviewclientculebra-vs-monkeyrunner.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvKI5nn1oDEToj-3qdDZIuawYDZBVnmVtV3tsh8hQy1KXUCaSD5wLRCx681IUEbBC1z3jLCX6oDnrJ3EG9JspvrJDrcUSiZ05VWxmwYxFeIRNqYPeIvZ0yl3T2vOI9aF9m1OoE/s72-c/400000000000000-com_duolingo-com_duolingo_app_WelcomeFlowActivity-2015-12-22T12%253A04%253A56.932602.png" height="72" width="72"/><thr:total>5</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-9089802031978977452</guid><pubDate>Mon, 24 Aug 2015 05:05:00 +0000</pubDate><atom:updated>2015-08-24T01:05:12.699-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">contacts</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">dump</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">tests</category><title>culebra: concertina mode</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/images/culebra-logo-transparent-204x209-rb-border.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; class=&quot;noborder&quot; height=&quot;200&quot; src=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/images/culebra-logo-transparent-204x209-rb-border.png&quot; width=&quot;195&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
One of the latest additions to &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/culebra&quot;&gt;culebra&lt;/a&gt;&lt;/b&gt;&lt;/span&gt; is the &lt;b&gt;concertina mode&lt;/b&gt;. Named after the &lt;a href=&quot;https://en.wikipedia.org/wiki/Concertina_movement&quot;&gt;concertina movement&lt;/a&gt; occurring in snakes and other legless organisms that consists of gripping or anchoring with portions of the body while pulling/pushing other sections in the direction of movement, this mode allows culebra to move across the UI.&lt;br /&gt;
&lt;br /&gt;
You may have used android&#39;s &lt;a href=&quot;http://developer.android.com/tools/help/monkey.html&quot;&gt;monkey&lt;/a&gt; before. monkey is a &lt;i&gt;UI/Application exerciser&lt;/i&gt; that generates pseudo-random streams of user events such as clicks, touches, or gestures, as well as a number of system-level events. It is commonly used to stress-test application. While it may serve this purpose, it&#39;s overly complicated to be used in other scenarios.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then, it comes &lt;b&gt;culebra concertina mode&lt;/b&gt; that instead of sending pseudo-random events, analyzes the content of the screen and randomly selects a suitable event or action for the also randomly selected target, normally a View.&lt;br /&gt;
&lt;br /&gt;
For example, if the randomly selected view is an &lt;b&gt;EditText&lt;/b&gt;, culebra enters some random text. However if the &lt;b&gt;EditText&lt;/b&gt; turns to be a password, it sends random passwords, that is instead of just entering a normal sentence it selected sample passwords from a list like the infamous &quot;&lt;b&gt;querty&lt;/b&gt;&quot;.&lt;br /&gt;
Furthermore, if it detects the &lt;b&gt;EditText&lt;/b&gt; is expecting an email address, by inspecting the &lt;b&gt;id&lt;/b&gt;, the &lt;b&gt;hint&lt;/b&gt; or anything else that may suggest that, it sends random email addresses like &lt;b&gt;user@example.com&lt;/b&gt;. Of course, other Views, receive other treatment, like &lt;b&gt;Buttons&lt;/b&gt; being clicked, &lt;b&gt;Scrollables&lt;/b&gt; being scrolled, etc.&lt;br /&gt;
&lt;br /&gt;
Additionally, if the content description suggest the application may be awaiting for you to talk, like &#39;&lt;b&gt;Tap to Speak&lt;/b&gt;&#39; or &#39;&lt;b&gt;Voice Search&lt;/b&gt;&#39;, culebra will actually speak random text to the app (this feature is only available on Linux and OSX).&lt;br /&gt;
&lt;br /&gt;
You should check this aspect, it&#39;s sometimes hilarious.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Taking advantage of the &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/Culebra-GUI&quot;&gt;culebra GUI&lt;/a&gt; already described in previous posts, while it&#39;s running the randomly selected Views are highlighted. At the same time, the &lt;b&gt;python&lt;/b&gt; script is being generated. You can save it, modify it and run the same tests again and again. It&#39;s worth to mention that commonly the script eliminates the random selection of components and thus it runs deterministically.&lt;br /&gt;
&lt;br /&gt;
Run culebra in concertina mode&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;$ culebra --gui --concertina --scale=0.5&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
and you can obtain something like this, where the nickname of a new contact was randomly selected from the available Views and the random text &quot;chaos reigned&quot; was entered.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbawb9zz6Zbqplj7DWGsotri2oGUSpUXdb-8xg6ljwRWDkAqn4iE9UTAaTDD2XoTWOFjv8-ZMQdYrmyX-BEVQBh3eGv65MIXDpDr04EdOOXe0iQvFVjxUhefIYb16u7crUZ7Di/s1600/contacts.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbawb9zz6Zbqplj7DWGsotri2oGUSpUXdb-8xg6ljwRWDkAqn4iE9UTAaTDD2XoTWOFjv8-ZMQdYrmyX-BEVQBh3eGv65MIXDpDr04EdOOXe0iQvFVjxUhefIYb16u7crUZ7Di/s400/contacts.png&quot; width=&quot;227&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
BTW, this screenshot was taken via &lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;dump&lt;/span&gt;&lt;/b&gt; as described in&amp;nbsp;&lt;a href=&quot;http://dtmilano.blogspot.ca/2015/04/android-obtaining-beautiful-screenshots.html&quot;&gt;android: obtaining beautiful screenshots automatically&lt;/a&gt;.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://dtmilano.blogspot.com/2015/08/culebra-concertina-mode.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbawb9zz6Zbqplj7DWGsotri2oGUSpUXdb-8xg6ljwRWDkAqn4iE9UTAaTDD2XoTWOFjv8-ZMQdYrmyX-BEVQBh3eGv65MIXDpDr04EdOOXe0iQvFVjxUhefIYb16u7crUZ7Di/s72-c/contacts.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1141762462618576671</guid><pubDate>Fri, 29 May 2015 15:50:00 +0000</pubDate><atom:updated>2015-05-29T11:50:03.124-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">uiautomator</category><title>Google Cloud Test Lab</title><description>Yesterday, at Google I/O 2015, &lt;a href=&quot;https://developers.google.com/cloud-test-lab/&quot;&gt;Cloud Test Lab&lt;/a&gt; was announced. One of its promoted features is: &quot;&lt;i&gt;you can run all of your tests across all devices, all at the same time--giving you access to massively parallel testing, bringing you deep and scaled insight&lt;/i&gt;&quot;.&lt;br /&gt;
Wow, that&#39;s pretty much the same I described in my previous post,&lt;br /&gt;
&lt;div style=&quot;font-stretch: normal; margin: 0px; position: relative;&quot;&gt;
&lt;a href=&quot;http://dtmilano.blogspot.ca/2015/05/android-culebra-multi-device.html&quot;&gt;&lt;b&gt;android: culebra multi-device capabilities&lt;/b&gt;&lt;/a&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;, minus the devices of course. You have to provide them.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;font-stretch: normal; margin: 0px; position: relative;&quot;&gt;
Wouldn&#39;t&lt;span style=&quot;font-weight: normal;&quot;&gt;&amp;nbsp;it be great if &lt;/span&gt;&lt;b&gt;Cloud Test Lab&lt;/b&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt; allows you to create your personalized tests, in addition to the automatically generated ones, using something like &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/Culebra-GUI&quot;&gt;culebra GUI&lt;/a&gt;, where you can just point and click?&lt;/span&gt;&lt;/div&gt;
</description><link>http://dtmilano.blogspot.com/2015/05/google-cloud-test-lab.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-8929083316943243612</guid><pubDate>Tue, 19 May 2015 05:03:00 +0000</pubDate><atom:updated>2015-05-19T01:03:17.953-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><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#">uiautomator</category><category domain="http://www.blogger.com/atom/ns#">unit test</category><title>android: culebra multi-device capabilities</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkwZZ7zK9CO45huPHF3fTVAQmtFqRJWLNn90BZTmOakSvZDkA__6OLkpmSY8DdxdR8JuxUqHYxEuD4li2NfTp2jFsi1EiPC873bBRJWpaF5HvFW9XYfCovNq1xBWv3b9BIITxk/s1600/culebra.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkwZZ7zK9CO45huPHF3fTVAQmtFqRJWLNn90BZTmOakSvZDkA__6OLkpmSY8DdxdR8JuxUqHYxEuD4li2NfTp2jFsi1EiPC873bBRJWpaF5HvFW9XYfCovNq1xBWv3b9BIITxk/s200/culebra.png&quot; width=&quot;195&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/culebra&quot;&gt;&lt;b&gt;culebra&lt;/b&gt;&lt;/a&gt; and its &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/Culebra-GUI&quot;&gt;GUI&lt;/a&gt; both include &lt;i&gt;multi-device&lt;/i&gt; capabilities in auto-generated test cases and scripts.&lt;br /&gt;
&lt;br /&gt;
The test case or script is created as usual, but when the &lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;--multi-device&lt;/span&gt;&lt;/b&gt; option is present in the command line, the statements generated will be slightly different, still you can easily recognize them. These statements will include support for several devices using python&#39;s &lt;a href=&quot;https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions&quot;&gt;list comprehension&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
For example, a typical &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;self.vc.dump(window=-1)&lt;/b&gt;&lt;/span&gt; will become&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;&amp;nbsp;[vc.dump(window=-1) for vc in self.allVcs()]&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
that is, for all the ViewClient&#39;s dump the content of the default window. You may wonder where the list of all ViewClient&#39;s obtained by &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;self.allVcs()&lt;/b&gt;&lt;/span&gt; comes from. &lt;b&gt;CulebraTestCase&lt;/b&gt; class handles multiple devices in its &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;setUp()&lt;/b&gt;&lt;/span&gt; method and it&#39;s there where the lists of all devices, serial numbers and ViewClient&#39;s are handled&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;self.devices.append(ConnectedDevice(serialno=serialno, device=device, vc=vc))&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Everything is handled automatically, so there&#39;s nothing to worry about. If only one device is connected to adb or a single serial number is passed to the test case as an argument, then the test case behaves exactly as single-device. However, if more than one device is connected to adb and they are specified on the command line the &lt;i&gt;multi-device&lt;/i&gt; capabilities kicks-in and the test is run on &lt;i&gt;all devices at the same time&lt;/i&gt;.&lt;/div&gt;
&lt;div&gt;
The special command line keyword &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;all &lt;/b&gt;&lt;/span&gt;can be used to mean &lt;i&gt;all the connected devices&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
This trivial test for &lt;b&gt;Calculator&lt;/b&gt;&amp;nbsp;generated using&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #444444; padding: 8px;&quot;&gt;
&lt;span style=&quot;background-color: #444444; color: #f3f3f3; font-family: Courier New, Courier, monospace;&quot;&gt;$ culebra --gui --multi-device \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444; color: #f3f3f3; font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; --unit-test-class \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444; color: #f3f3f3; font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; --do-not-verify-screen-dump \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444; color: #f3f3f3; font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; -o ~/tmp/multi.py&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
shows&amp;nbsp;&lt;i&gt;multi-device&lt;/i&gt; capabilities.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: #fbfbfb; color: #333333;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 18px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: monospace;&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#! /usr/bin/env python&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&#39;&#39;&#39;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;Copyright (C) 2013-2014  Diego Torres Milano&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;Created on 2015-05-19 by Culebra v10.5.1&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                      __    __    __    __&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                     /  \  /  \  /  \  /  \ &lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;____________________/  __\/  __\/  __\/  __\_____________________________&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;___________________/  /__/  /__/  /__/  /________________________________&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                   | / \   / \   / \   / \   \___&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                   |/   \_/   \_/   \_/   \    o \ &lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                                           \_____/--&amp;lt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;@author: Diego Torres Milano&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;@author: Jennifer E. Swofford (ascii art snake)&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&#39;&#39;&#39;&lt;/span&gt;


&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; re
&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; sys
&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; os


&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; unittest


&lt;span class=&quot;Statement&quot;&gt;try&lt;/span&gt;:
    sys.path.insert(&lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;, os.path.join(os.environ[&lt;span class=&quot;String&quot;&gt;&#39;ANDROID_VIEW_CLIENT_HOME&#39;&lt;/span&gt;], &lt;span class=&quot;String&quot;&gt;&#39;src&#39;&lt;/span&gt;))
&lt;span class=&quot;Statement&quot;&gt;except&lt;/span&gt;:
    &lt;span class=&quot;Statement&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;PreProc&quot;&gt;from&lt;/span&gt; com.dtmilano.android.viewclient &lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; ViewClient, CulebraTestCase

TAG = &lt;span class=&quot;String&quot;&gt;&#39;CULEBRA&#39;&lt;/span&gt;


&lt;span class=&quot;Statement&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;CulebraTests&lt;/span&gt;(CulebraTestCase):

    &lt;span class=&quot;PreProc&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;Identifier&quot;&gt;classmethod&lt;/span&gt;
    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;setUpClass&lt;/span&gt;(cls):
        cls.kwargs1 = {&lt;span class=&quot;String&quot;&gt;&#39;ignoreversioncheck&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;verbose&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;ignoresecuredevice&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;}
        cls.kwargs2 = {&lt;span class=&quot;String&quot;&gt;&#39;compresseddump&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;startviewserver&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;forceviewserveruse&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;autodump&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;ignoreuiautomatorkilled&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;}
        cls.options = {&lt;span class=&quot;String&quot;&gt;&#39;start-activity&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;device-art&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;use-jar&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;multi-device&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;unit-test-class&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;save-screenshot&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;use-dictionary&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;glare&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;dictionary-keys-from&#39;&lt;/span&gt;: &lt;span class=&quot;String&quot;&gt;&#39;id&#39;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;scale&#39;&lt;/span&gt;: &lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;find-views-with-content-description&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;window&#39;&lt;/span&gt;: -&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;orientation-locked&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;save-view-screenshots&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;find-views-by-id&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;log-actions&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;use-regexps&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;null-back-end&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;auto-regexps&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;do-not-verify-screen-dump&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;verbose-comments&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;gui&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;find-views-with-text&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;prepend-to-sys-path&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;drop-shadow&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;output&#39;&lt;/span&gt;: &lt;span class=&quot;String&quot;&gt;&#39;/Users/diego/tmp/multi2.py&#39;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;unit-test-method&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;interactive&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;}
        cls.sleep = &lt;span class=&quot;Constant&quot;&gt;5&lt;/span&gt;

    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;setUp&lt;/span&gt;(self):
        &lt;span class=&quot;Identifier&quot;&gt;super&lt;/span&gt;(CulebraTests, self).setUp()

    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;tearDown&lt;/span&gt;(self):
        &lt;span class=&quot;Identifier&quot;&gt;super&lt;/span&gt;(CulebraTests, self).tearDown()

    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;preconditions&lt;/span&gt;(self):
        &lt;span class=&quot;Statement&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;Statement&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;super&lt;/span&gt;(CulebraTests, self).preconditions():
            &lt;span class=&quot;Statement&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;Statement&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;

    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;testSomething&lt;/span&gt;(self):
        &lt;span class=&quot;Statement&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;Statement&quot;&gt;not&lt;/span&gt; self.preconditions():
            self.fail(&lt;span class=&quot;String&quot;&gt;&#39;Preconditions failed&#39;&lt;/span&gt;)

        _s = CulebraTests.sleep
        _v = CulebraTests.verbose

        [_vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.findViewWithTextOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;2&#39;&lt;/span&gt;).touch() &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.sleep(_s) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.findViewWithContentDescriptionOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;&#39;&#39;plus&#39;&#39;&#39;&lt;/span&gt;).touch() &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.sleep(_s) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.findViewWithTextOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;1&#39;&lt;/span&gt;).touch() &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.sleep(_s) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.findViewWithContentDescriptionOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;&#39;&#39;equals&#39;&#39;&#39;&lt;/span&gt;).touch() &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.sleep(_s) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]
        [_vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;) &lt;span class=&quot;Statement&quot;&gt;for&lt;/span&gt; _vc &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; self.allVcs()]


&lt;span class=&quot;Statement&quot;&gt;if&lt;/span&gt; __name__ == &lt;span class=&quot;String&quot;&gt;&#39;__main__&#39;&lt;/span&gt;:
    CulebraTests.main()
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Then, when you run the test with several devices connected as&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #444444; padding: 8px;&quot;&gt;
&lt;span style=&quot;background-color: #444444;&quot;&gt;&lt;span style=&quot;color: #f3f3f3; font-family: Courier New, Courier, monospace;&quot;&gt;$ ~/tmp/multi.py -s all&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
you will obtain something like this&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe width=&quot;320&quot; height=&quot;266&quot; class=&quot;YOUTUBE-iframe-video&quot; data-thumbnail-src=&quot;https://i.ytimg.com/vi/siBjXEUH8FI/0.jpg&quot; src=&quot;https://www.youtube.com/embed/siBjXEUH8FI?feature=player_embedded&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</description><link>http://dtmilano.blogspot.com/2015/05/android-culebra-multi-device.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkwZZ7zK9CO45huPHF3fTVAQmtFqRJWLNn90BZTmOakSvZDkA__6OLkpmSY8DdxdR8JuxUqHYxEuD4li2NfTp2jFsi1EiPC873bBRJWpaF5HvFW9XYfCovNq1xBWv3b9BIITxk/s72-c/culebra.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-7626839686695823612</guid><pubDate>Thu, 14 May 2015 03:41:00 +0000</pubDate><atom:updated>2015-05-13T23:56:24.774-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">dump</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">screenshot</category><category domain="http://www.blogger.com/atom/ns#">uiautomator</category><title>android: beautiful screenshots, take 2</title><description>In my previous post,&amp;nbsp;&lt;a href=&quot;http://dtmilano.blogspot.ca/2015/04/android-obtaining-beautiful-screenshots.html&quot; style=&quot;background-color: white; color: #29aae1; font-family: &#39;Trebuchet MS&#39;, Trebuchet, sans-serif; font-stretch: normal; text-decoration: none;&quot;&gt;android: obtaining beautiful screenshots automatically&lt;/a&gt;, I introduced an automated way of obtaining screenshots of your application perhaps after doing some actions that would take considerably time to do manually over time.&lt;br /&gt;
&lt;br /&gt;
We described how &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/Culebra-GUI&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;culebra&lt;/span&gt;&lt;/b&gt;&lt;/a&gt; intuitive UI could help you create the automation script even if you don&#39;t know anything about programing or python.&lt;br /&gt;
&lt;br /&gt;
However, for simpler cases or when you just want to take one screenshot and an automation script is not worth the effort, &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/dump&quot;&gt;dump&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;, another tool in &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot;&gt;AndroidViewClient&lt;/a&gt;&#39;s toolbox can be used.&lt;br /&gt;
&lt;br /&gt;
Simply, to take a screenshot and add device art, shadow and glare:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #444444; padding: 8px;&quot;&gt;
&lt;span style=&quot;color: #f3f3f3; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;background-color: #444444;&quot;&gt;$ dump -f /path/to/image -ZBA auto&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
or, with the long option which are easier to remember&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #444444; padding: 8px;&quot;&gt;
&lt;span style=&quot;background-color: #444444; color: #f3f3f3;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ dump --save-screenshot=/path/to/file \&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444; color: #f3f3f3;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; --drop-shadow \&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444; color: #f3f3f3;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; --glare \&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444; color: #f3f3f3;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; --device-art=auto&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Now taking advantage of this opportunity. I would like to introduce some new device art support added in the latest version, like this &lt;b&gt;Samsung Galaxy S4 &lt;/b&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;(this screenshot has been taken with the previous command)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmDyszQzUilIbNLpGth0HLYygqObED8XL4Gvi7mHQ9lAjzB7Bv5ZzO-TyGEZENj-W0EwGqCWJlHxIwVbtGbaRiWPrpcgX8Bn4eADIrZNcU6DncvZ1W13St2UzDMhYB-tEuK4Xi/s1600/s4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmDyszQzUilIbNLpGth0HLYygqObED8XL4Gvi7mHQ9lAjzB7Bv5ZzO-TyGEZENj-W0EwGqCWJlHxIwVbtGbaRiWPrpcgX8Bn4eADIrZNcU6DncvZ1W13St2UzDMhYB-tEuK4Xi/s320/s4.png&quot; width=&quot;166&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span id=&quot;goog_2105939823&quot;&gt;&lt;/span&gt;&lt;span id=&quot;goog_2105939824&quot;&gt;&lt;/span&gt;&lt;br /&gt;</description><link>http://dtmilano.blogspot.com/2015/05/android-beautiful-screenshots-take-2.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmDyszQzUilIbNLpGth0HLYygqObED8XL4Gvi7mHQ9lAjzB7Bv5ZzO-TyGEZENj-W0EwGqCWJlHxIwVbtGbaRiWPrpcgX8Bn4eADIrZNcU6DncvZ1W13St2UzDMhYB-tEuK4Xi/s72-c/s4.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-1129745502605247203</guid><pubDate>Sun, 26 Apr 2015 23:37:00 +0000</pubDate><atom:updated>2015-04-26T19:37:20.928-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">screenshot</category><title>android: obtaining beautiful screenshots automatically</title><description>How much time have you invested obtaining screenshots for your app and then making them look nicer framing them in the corresponding device artwork?&lt;br /&gt;
&lt;br /&gt;
You have to install the app, manually do the steps needed to get to the point where you want to take the screenshot to produce the most effective communication of the idea you are trying to convey, actually taking the screenshot, saving it to a file and then probably using &lt;a href=&quot;https://developer.android.com/distribute/tools/promote/device-art.html&quot; target=&quot;_blank&quot;&gt;Device Art Generator&lt;/a&gt; to frame it using the corresponding artwork and orientation that you have to decide and finally downloading the result.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://developer.android.com/tools/studio/index.html&quot; target=&quot;_blank&quot;&gt;Android Studio&lt;/a&gt; may simplify these steps a bit, but still is annoyingly slow and time consuming to have to check the desired options every time.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOzB9sb21Q0uLhIGkGXdpG0Gl6H7FmTQpLFuXfNJ_MwKZ2Jx-w-Sfud4b9qwpRpIZUiGBQGiGcaa-i-DPpfHYLcfUEg9GD3xm1Xp0T0doXM8SKLJZsi7mBvx1-tevht1qQkJqn/s1600/Studio.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOzB9sb21Q0uLhIGkGXdpG0Gl6H7FmTQpLFuXfNJ_MwKZ2Jx-w-Sfud4b9qwpRpIZUiGBQGiGcaa-i-DPpfHYLcfUEg9GD3xm1Xp0T0doXM8SKLJZsi7mBvx1-tevht1qQkJqn/s1600/Studio.png&quot; height=&quot;194&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
The model (i.e. &lt;b&gt;Nexus 5&lt;/b&gt;) has to be selected every time as well as &lt;b&gt;Drop Shadow&lt;/b&gt; and &lt;b&gt;Screen Glare&lt;/b&gt;. The orientation is not detected and you have to &lt;b&gt;Rotate&lt;/b&gt; it manually if incorrect.&lt;br /&gt;
&lt;br /&gt;
Wouldn&#39;t it be great if you can automate all of these steps and get the screenshots without human intervention?&lt;br /&gt;
&lt;br /&gt;
I have wondered the same many times and finally support for device artwork was added to &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot; target=&quot;_blank&quot;&gt;AndroidViewClient/culebra&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Task automation using culebra&lt;/h3&gt;
As an example, just let&#39;s pretend we want to prepare some screenshots to be included in the documentation or presentation about our app, which in this case would be &lt;b&gt;Calculator&lt;/b&gt;.&lt;br /&gt;
Every time we create a new version of the app we want to reproduce the same scenario an take the beautiful screenshot. For the sake of simplicity, this scenario is the simple calculation &quot;&lt;b&gt;2+1=3&lt;/b&gt;&quot;.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s run&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #444444;&quot;&gt;
&lt;span style=&quot;background-color: #444444; color: #eeeeee; font-family: Courier New, Courier, monospace;&quot;&gt;$ culebra --gui --do-not-verify-screen-dump --scale=0.5 \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444; color: #eeeeee; font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; --device-art=auto --drop-shadow --glare \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: #444444; color: #eeeeee; font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; -o ~/tmp/calculator.py&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
This runs `culebra` GUI.&lt;br /&gt;
Once the window reproducing your device screen is shown, do:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Press &lt;b&gt;HOME&lt;/b&gt;, to start from a known state&lt;/li&gt;
&lt;li&gt;Touch on &lt;b&gt;All Apps&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Touch on &lt;b&gt;Calculator&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Click with the secondary button to open the context menu and select &lt;b&gt;&lt;i&gt;Long touch point using PX&lt;/i&gt;&lt;/b&gt; (the shortcut for this action is &lt;b&gt;^L&lt;/b&gt;)&lt;/li&gt;
&lt;li&gt;Touch on Calculator&#39;s &lt;b&gt;DEL&lt;/b&gt;, to completely clear the screen&lt;/li&gt;
&lt;li&gt;Touch 2&lt;/li&gt;
&lt;li&gt;Touch&amp;nbsp;+&lt;/li&gt;
&lt;li&gt;Touch 1&lt;/li&gt;
&lt;li&gt;Click with the secondary button to open the context menu and select&amp;nbsp;&lt;b style=&quot;font-style: italic;&quot;&gt;Take snapshot and save to file &lt;/b&gt;(the shortcut is &lt;b&gt;^F&lt;/b&gt;)&lt;/li&gt;
&lt;li&gt;Close the window&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Now we have the `calculator.py` screen generated, that every time we run it will reproduce the steps, detect the device and orientation, take the screenshot and frame it with the corresponding &lt;i&gt;device artwork&lt;/i&gt; and will add the &lt;i&gt;drop shadow&lt;/i&gt; and &lt;i&gt;glare&lt;/i&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUBDtGnPdGxxlUpvRofG_kaF0EJoPk8W9Q0T33DuKD1ybIbtON9pskHNb5GXvLyc5Z3NXin64-hOUz_JYR_5geOelPqdl-w4eSS1tB03kZssGlRpQuuFt4w-ZkGllpIaWuwxqT/s1600/0936964802203bc7-com_android_calculator2-com_android_calculator2_Calculator-2015-04-26T18:40:28.708173.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUBDtGnPdGxxlUpvRofG_kaF0EJoPk8W9Q0T33DuKD1ybIbtON9pskHNb5GXvLyc5Z3NXin64-hOUz_JYR_5geOelPqdl-w4eSS1tB03kZssGlRpQuuFt4w-ZkGllpIaWuwxqT/s1600/0936964802203bc7-com_android_calculator2-com_android_calculator2_Calculator-2015-04-26T18:40:28.708173.png&quot; height=&quot;320&quot; width=&quot;182&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Analyzing the generated script&lt;/h3&gt;
&lt;div&gt;
Let&#39;s take a closer look at the script generated by `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;culebra&lt;/span&gt;`.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: #fbfbfb; color: #333333;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 18px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: monospace;&quot;&gt;
&lt;span class=&quot;Comment&quot;&gt;#! /usr/bin/env python&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&#39;&#39;&#39;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;Copyright (C) 2013-2014  Diego Torres Milano&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;Created on 2015-04-26 by Culebra v10.3.0&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                      __    __    __    __&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                     /  \  /  \  /  \  /  \ &lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;____________________/  __\/  __\/  __\/  __\_____________________________&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;___________________/  /__/  /__/  /__/  /________________________________&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                   | / \   / \   / \   / \   \___&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                   |/   \_/   \_/   \_/   \    o \ &lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                                           \_____/--&amp;lt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;@author: Diego Torres Milano&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;@author: Jennifer E. Swofford (ascii art snake)&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&#39;&#39;&#39;&lt;/span&gt;


&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; re
&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; sys
&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; os


&lt;span class=&quot;Statement&quot;&gt;try&lt;/span&gt;:
    sys.path.insert(&lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;, os.path.join(os.environ[&lt;span class=&quot;String&quot;&gt;&#39;ANDROID_VIEW_CLIENT_HOME&#39;&lt;/span&gt;], &lt;span class=&quot;String&quot;&gt;&#39;src&#39;&lt;/span&gt;))
&lt;span class=&quot;Statement&quot;&gt;except&lt;/span&gt;:
    &lt;span class=&quot;Statement&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;PreProc&quot;&gt;from&lt;/span&gt; com.dtmilano.android.viewclient &lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; ViewClient

TAG = &lt;span class=&quot;String&quot;&gt;&#39;CULEBRA&#39;&lt;/span&gt;

_s = &lt;span class=&quot;Constant&quot;&gt;5&lt;/span&gt;
_v = &lt;span class=&quot;String&quot;&gt;&#39;--verbose&#39;&lt;/span&gt; &lt;span class=&quot;Statement&quot;&gt;in&lt;/span&gt; sys.argv


kwargs1 = {&lt;span class=&quot;String&quot;&gt;&#39;ignoreversioncheck&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;verbose&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;ignoresecuredevice&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;}
device, serialno = ViewClient.connectToDeviceOrExit(**kwargs1)
kwargs2 = {&lt;span class=&quot;String&quot;&gt;&#39;compresseddump&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;startviewserver&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;forceviewserveruse&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;autodump&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;ignoreuiautomatorkilled&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;}
vc = ViewClient(device, serialno, **kwargs2)
&lt;span class=&quot;Comment&quot;&gt;#vc.dump(window=&#39;-1&#39;) # &lt;/span&gt;&lt;span class=&quot;Todo&quot;&gt;FIXME&lt;/span&gt;&lt;span class=&quot;Comment&quot;&gt;: seems not needed&lt;/span&gt;

vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
device.press(&lt;span class=&quot;String&quot;&gt;&#39;HOME&#39;&lt;/span&gt;)
vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
vc.findViewWithContentDescriptionOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;&#39;&#39;Apps&#39;&#39;&#39;&lt;/span&gt;).touch()
vc.sleep(_s)
vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
vc.findViewWithContentDescriptionOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;&#39;&#39;Calculator&#39;&#39;&#39;&lt;/span&gt;).touch()
vc.sleep(_s)
vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
device.longTouch(&lt;span class=&quot;Constant&quot;&gt;912.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;838.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;2000&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;)
vc.sleep(&lt;span class=&quot;Constant&quot;&gt;5&lt;/span&gt;)
vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
vc.findViewWithTextOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;2&#39;&lt;/span&gt;).touch()
vc.sleep(_s)
vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
vc.findViewWithContentDescriptionOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;&#39;&#39;plus&#39;&#39;&#39;&lt;/span&gt;).touch()
vc.sleep(_s)
vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
vc.findViewWithTextOrRaise(&lt;span class=&quot;String&quot;&gt;u&#39;1&#39;&lt;/span&gt;).touch()
vc.sleep(_s)
vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
vc.writeImageToFile(&lt;span class=&quot;String&quot;&gt;&#39;/tmp/${serialno}-${focusedwindowname}-${timestamp}.png&#39;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;PNG&#39;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;auto&#39;&lt;/span&gt;, &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The first part is the same for all culebra scripts. Some global variables, like &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;TAG&lt;/span&gt;, are defined and can lately be used as parameters for some method calls like `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Log.d()`&lt;/span&gt;.&lt;br /&gt;
Then the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ViewClient&lt;/span&gt; object is created connecting to the selected device. If you don&#39;t specify any `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;serialno&lt;/span&gt;` the default device will be selected.&lt;br /&gt;
Once the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ViewClient&lt;/span&gt; object is created we see the method invocations that correspond to the action we did on the GUI, closed by the invocation to `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;vc.writeImageToFile()&lt;/span&gt;` which will be creating the screenshot. In this case, and determined by the command line arguments used when we launched `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;culebra&lt;/span&gt;`, device art will be `&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;auto&lt;/span&gt;` selected, and drop shadow (&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;True&lt;/span&gt;) and glare (&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;True&lt;/span&gt;) will be added.&lt;br /&gt;
The filename generation for the taken screenshot uses some keywords, replaced at save time, to avoid overwriting old ones if any.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Here is where the magic begins&lt;/h3&gt;
As a proof-of-concept, let&#39;s physically rotate the device and run the generated script again&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background: #444444;&quot;&gt;
&lt;span style=&quot;background-color: #444444; color: #eeeeee; font-family: Courier New, Courier, monospace;&quot;&gt;$ ~/tmp/calculator.py&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
once it runs we will obtain the correct screenshot for landscape orientation&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilHhiXk4T-MPKAGagxg-F7gUzRrAkilZmJD2qv3McJbKR7HxFlTXkh3li7by3zeUhl9yCx7uwcasO3lVKd2kcmJbrPndvG4Ree5keEn_q-fGuk5aC3RjkJBqQ5tk8vKzI3G04n/s1600/0936964802203bc7-com_android_calculator2-com_android_calculator2_Calculator-2015-04-26T19:24:01.236697.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilHhiXk4T-MPKAGagxg-F7gUzRrAkilZmJD2qv3McJbKR7HxFlTXkh3li7by3zeUhl9yCx7uwcasO3lVKd2kcmJbrPndvG4Ree5keEn_q-fGuk5aC3RjkJBqQ5tk8vKzI3G04n/s1600/0936964802203bc7-com_android_calculator2-com_android_calculator2_Calculator-2015-04-26T19:24:01.236697.png&quot; height=&quot;158&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
No human intervention!&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://dtmilano.blogspot.com/2015/04/android-obtaining-beautiful-screenshots.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOzB9sb21Q0uLhIGkGXdpG0Gl6H7FmTQpLFuXfNJ_MwKZ2Jx-w-Sfud4b9qwpRpIZUiGBQGiGcaa-i-DPpfHYLcfUEg9GD3xm1Xp0T0doXM8SKLJZsi7mBvx1-tevht1qQkJqn/s72-c/Studio.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-3067086087319571101</guid><pubDate>Tue, 27 Jan 2015 04:08:00 +0000</pubDate><atom:updated>2015-01-27T12:39:57.098-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><title>New culebra logo</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiuaGbRCrL3l6r9cZFCdeS1CM_2gvEbmpKtQsImYdLM2msqZ6jyI3C6i60WiTZqaztjYliKKvAZnrDu9pYkqpSmxhp2iY8-3xdGQRLmFXrk9BGHLQ4JevYFJb7aUWWsKJsxp_N/s1600/culebra-logo-transparent.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;culebra logo&quot; border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiuaGbRCrL3l6r9cZFCdeS1CM_2gvEbmpKtQsImYdLM2msqZ6jyI3C6i60WiTZqaztjYliKKvAZnrDu9pYkqpSmxhp2iY8-3xdGQRLmFXrk9BGHLQ4JevYFJb7aUWWsKJsxp_N/s1600/culebra-logo-transparent.png&quot; height=&quot;200&quot; title=&quot;culebra logo&quot; width=&quot;195&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;Dean Britto&lt;/b&gt; of &lt;a href=&quot;http://deanbritto.com/&quot;&gt;deanbritto.com&lt;/a&gt;&amp;nbsp;has&amp;nbsp;graciously&amp;nbsp;created this awesome &lt;b&gt;culebra&lt;/b&gt; logo and release it under a &lt;a href=&quot;http://creativecommons.org/licenses/by/4.0/&quot; rel=&quot;license&quot;&gt;Creative Commons Attribution 4.0 International License&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;
This will be incorporated in future culebra versions and documentation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks Dean for your fine work!
</description><link>http://dtmilano.blogspot.com/2015/01/new-culebra-logo.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiuaGbRCrL3l6r9cZFCdeS1CM_2gvEbmpKtQsImYdLM2msqZ6jyI3C6i60WiTZqaztjYliKKvAZnrDu9pYkqpSmxhp2iY8-3xdGQRLmFXrk9BGHLQ4JevYFJb7aUWWsKJsxp_N/s72-c/culebra-logo-transparent.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-4633425903760564809</guid><pubDate>Fri, 23 Jan 2015 03:08:00 +0000</pubDate><atom:updated>2015-01-22T22:08:08.794-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">github</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">stackoverflow</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><category domain="http://www.blogger.com/atom/ns#">test driven development</category><category domain="http://www.blogger.com/atom/ns#">tests</category><category domain="http://www.blogger.com/atom/ns#">unit test</category><category domain="http://www.blogger.com/atom/ns#">wiki</category><title>AndroidViewClient/culebra 10K/month download mark</title><description>I proudly announce that last month we achieved the &lt;b&gt;10K/month&lt;/b&gt; download.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://pypi.python.org/pypi/androidviewclient/&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC2K-cVZK-9vg43RnV3f2m1AxVeVzbH85yZe4WLml1azu2Uiqwn50JL9-Fzo9FxE_L5D8wqLyBcKBSD4PBTp2uipbdUK-EODRjMY-wBssWw8a89lmq0EXlRvhmUYCgj5glfHFB/s1600/avc-downloads-10k.png&quot; height=&quot;45&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Thank you all collaborator, contributors, testers and users that helped in the creation and evolution of one of the best and most versatile Android automated testing tool.&lt;br /&gt;
&lt;br /&gt;
Since&lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki/Culebra-GUI&quot; target=&quot;_blank&quot;&gt; &lt;b&gt;culebra&#39;s GUI&lt;/b&gt;&lt;/a&gt; inception some months ago, we closed the gap between programmers and testers. Even though the &lt;i&gt;auto-generated&lt;/i&gt; test scripts are the same as the ones that could be manually created using &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient&quot; target=&quot;_blank&quot;&gt;AndroidViewClient&lt;/a&gt; as a library &amp;nbsp;with the GUI we lowered the bar and the tool can be used even you don&#39;t know how to program in &lt;i&gt;python&lt;/i&gt; and even if you don&#39;t program at all.&lt;br /&gt;
&lt;br /&gt;
In retrospective last months we have seen several fundamental additions, like as I mentioned&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;culebra GUI&lt;/li&gt;
&lt;li&gt;multi-device test generation and run capability (more coming soon)&lt;/li&gt;
&lt;li&gt;orientation locked tests&lt;/li&gt;
&lt;li&gt;log test steps to file, screen and adb logcat&lt;/li&gt;
&lt;li&gt;screen and View snapshots with filename generated from pattern&lt;/li&gt;
&lt;li&gt;added WiFiManager to mimic Android device&#39;s&lt;/li&gt;
&lt;li&gt;calculation of distance between different View trees&lt;/li&gt;
&lt;li&gt;drag using PX or DIP&lt;/li&gt;
&lt;li&gt;and many, many more&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Stay in touch. You comments and suggestions are welcome, and&amp;nbsp;&lt;a href=&quot;http://stackoverflow.com/questions/tagged/androidviewclient&quot;&gt;http://stackoverflow.com/questions/tagged/androidviewclient&lt;/a&gt; is a great way of getting your questions answered.&lt;br /&gt;
Install from &lt;a href=&quot;https://pypi.python.org/pypi/androidviewclient/&quot; target=&quot;_blank&quot;&gt;pypi&lt;/a&gt;, clone from &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient.git&quot; target=&quot;_blank&quot;&gt;github&lt;/a&gt;&amp;nbsp;and read the documentation from the &lt;a href=&quot;https://github.com/dtmilano/AndroidViewClient/wiki&quot; target=&quot;_blank&quot;&gt;wiki&lt;/a&gt;&amp;nbsp;(yes, it&#39;s been updated and cleaned up lately, however some still needs some love, anyone?).&lt;br /&gt;
&lt;br /&gt;
See you at the &lt;b&gt;100K/month&lt;/b&gt; post ;-)</description><link>http://dtmilano.blogspot.com/2015/01/androidviewclientculebra-10kmonth.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC2K-cVZK-9vg43RnV3f2m1AxVeVzbH85yZe4WLml1azu2Uiqwn50JL9-Fzo9FxE_L5D8wqLyBcKBSD4PBTp2uipbdUK-EODRjMY-wBssWw8a89lmq0EXlRvhmUYCgj5glfHFB/s72-c/avc-downloads-10k.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-25456655.post-5697888199104549238</guid><pubDate>Sat, 08 Nov 2014 04:00:00 +0000</pubDate><atom:updated>2015-01-21T21:17:16.894-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">adb</category><category domain="http://www.blogger.com/atom/ns#">android</category><category domain="http://www.blogger.com/atom/ns#">AndroidViewClient</category><category domain="http://www.blogger.com/atom/ns#">culebra</category><category domain="http://www.blogger.com/atom/ns#">emulator</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">monkeyrunner</category><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#">uiautomator</category><category domain="http://www.blogger.com/atom/ns#">unit test</category><title>culebra: the magical drag </title><description>This time we are demonstrating how to include &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;drag()&lt;/b&gt;&lt;/span&gt; method calls in the generated test script.&lt;br /&gt;
&lt;br /&gt;
The little secret, and what adds some &quot;&lt;i&gt;magic&lt;/i&gt;&quot; is that units of the generated method call can be selected between &lt;b&gt;DIP&lt;/b&gt; (&lt;a href=&quot;http://developer.android.com/guide/practices/screens_support.html#density-independence&quot; target=&quot;_blank&quot;&gt;density-independent pixels&lt;/a&gt;, also known as dp) or &lt;b&gt;PX&lt;/b&gt; (pixels). The former, allows to give the generated test some independence of the physical screen size it is running on by applying the inverse relationship between pixels and density. That is, when a point it&#39;s touched on the screen, the actual density it used to calculate the touched points in &lt;b&gt;DIP&lt;/b&gt;s and used to provide the arguments for the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;drag()&lt;/b&gt;&lt;/span&gt; method.&lt;br /&gt;
&lt;br /&gt;
This is the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;culebra&lt;/b&gt;&lt;/span&gt; auto-generated script after the interactions showed in the screencast are performed.&lt;br /&gt;
&lt;br /&gt;
If you inspect the script you will notice that now the &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;drag()&lt;/b&gt;&lt;/span&gt; method includes another argument, which is &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;/span&gt; in this case and indicates the orientation of the device, but we will be covering this in a future post.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;background-color: #fbfbfb; color: #333333;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 18px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: monospace;&quot;&gt;&lt;span class=&quot;Comment&quot;&gt;#! /usr/bin/env python&lt;/span&gt;
&lt;span class=&quot;Comment&quot;&gt;# -*- coding: utf-8 -*-&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&#39;&#39;&#39;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;Copyright (C) 2013-2014  Diego Torres Milano&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;Created on 2014-11-07 by Culebra v8.14.3&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                      __    __    __    __&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                     /  \  /  \  /  \  /  \ &lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;____________________/  __\/  __\/  __\/  __\_____________________________&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;___________________/  /__/  /__/  /__/  /________________________________&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                   | / \   / \   / \   / \   \___&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                   |/   \_/   \_/   \_/   \    o \ &lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;                                           \_____/--&amp;lt;&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;@author: Diego Torres Milano&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;@author: Jennifer E. Swofford (ascii art snake)&lt;/span&gt;
&lt;span class=&quot;String&quot;&gt;&#39;&#39;&#39;&lt;/span&gt;


&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; re
&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; sys
&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; os


&lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; unittest

&lt;span class=&quot;PreProc&quot;&gt;from&lt;/span&gt; com.dtmilano.android.viewclient &lt;span class=&quot;PreProc&quot;&gt;import&lt;/span&gt; ViewClient, CulebraTestCase


&lt;span class=&quot;Statement&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;CulebraTests&lt;/span&gt;(CulebraTestCase):

    &lt;span class=&quot;PreProc&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;Identifier&quot;&gt;classmethod&lt;/span&gt;
    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;setUpClass&lt;/span&gt;(cls):
        cls.kwargs1 = {&lt;span class=&quot;String&quot;&gt;&#39;ignoreversioncheck&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;verbose&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;ignoresecuredevice&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;}
        cls.kwargs2 = {&lt;span class=&quot;String&quot;&gt;&#39;startviewserver&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;forceviewserveruse&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;autodump&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;ignoreuiautomatorkilled&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;}
        cls.options = {&lt;span class=&quot;String&quot;&gt;&#39;start-activity&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;unit-test-class&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;save-screenshot&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;use-dictionary&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;dictionary-keys-from&#39;&lt;/span&gt;: &lt;span class=&quot;String&quot;&gt;&#39;id&#39;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;scale&#39;&lt;/span&gt;: &lt;span class=&quot;Constant&quot;&gt;0.5&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;find-views-with-content-description&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;window&#39;&lt;/span&gt;: -&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;orientation-locked&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;save-view-screenshots&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;find-views-by-id&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;do-not-verify-initial-screen-dump&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;use-regexps&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;auto-regexps&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;use-jar&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;verbose-comments&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;gui&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;find-views-with-text&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;output&#39;&lt;/span&gt;: &lt;span class=&quot;String&quot;&gt;&#39;/home/user/tmp/grab-1.py&#39;&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;unit-test-method&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;None&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;append-to-sys-path&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;, &lt;span class=&quot;String&quot;&gt;&#39;interactive&#39;&lt;/span&gt;: &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;}
        cls.sleep = &lt;span class=&quot;Constant&quot;&gt;5&lt;/span&gt;

    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;setUp&lt;/span&gt;(self):
        &lt;span class=&quot;Identifier&quot;&gt;super&lt;/span&gt;(CulebraTests, self).setUp()

    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;tearDown&lt;/span&gt;(self):
        &lt;span class=&quot;Identifier&quot;&gt;super&lt;/span&gt;(CulebraTests, self).tearDown()

    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;preconditions&lt;/span&gt;(self):
        &lt;span class=&quot;Statement&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;Statement&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;super&lt;/span&gt;(CulebraTests, self).preconditions():
            &lt;span class=&quot;Statement&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;False&lt;/span&gt;
        &lt;span class=&quot;Statement&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;True&lt;/span&gt;

    &lt;span class=&quot;Statement&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;Identifier&quot;&gt;testSomething&lt;/span&gt;(self):
        &lt;span class=&quot;Statement&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;Statement&quot;&gt;not&lt;/span&gt; self.preconditions():
            self.fail(&lt;span class=&quot;String&quot;&gt;&#39;Preconditions failed&#39;&lt;/span&gt;)

        self.vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
        self.vc.device.dragDip((&lt;span class=&quot;Constant&quot;&gt;289.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;485.0&lt;/span&gt;), (&lt;span class=&quot;Constant&quot;&gt;46.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;484.0&lt;/span&gt;), &lt;span class=&quot;Constant&quot;&gt;1000&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;)
        self.vc.sleep(&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
        self.vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
        self.vc.device.dragDip((&lt;span class=&quot;Constant&quot;&gt;44.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;468.0&lt;/span&gt;), (&lt;span class=&quot;Constant&quot;&gt;339.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;473.0&lt;/span&gt;), &lt;span class=&quot;Constant&quot;&gt;1000&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;)
        self.vc.sleep(&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
        self.vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
        self.vc.device.dragDip((&lt;span class=&quot;Constant&quot;&gt;69.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;478.0&lt;/span&gt;), (&lt;span class=&quot;Constant&quot;&gt;335.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;485.0&lt;/span&gt;), &lt;span class=&quot;Constant&quot;&gt;1000&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;)
        self.vc.sleep(&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
        self.vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
        self.vc.device.dragDip((&lt;span class=&quot;Constant&quot;&gt;345.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;491.0&lt;/span&gt;), (&lt;span class=&quot;Constant&quot;&gt;31.0&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;485.0&lt;/span&gt;), &lt;span class=&quot;Constant&quot;&gt;1000&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;20&lt;/span&gt;, &lt;span class=&quot;Constant&quot;&gt;0&lt;/span&gt;)
        self.vc.sleep(&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)
        self.vc.dump(window=-&lt;span class=&quot;Constant&quot;&gt;1&lt;/span&gt;)


&lt;span class=&quot;Statement&quot;&gt;if&lt;/span&gt; __name__ == &lt;span class=&quot;String&quot;&gt;&#39;__main__&#39;&lt;/span&gt;:
    CulebraTests.main()

&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
And this is the screencast showing the emulator window (I used an emulator to easily capture the content but you can use any device), a terminal window where I run &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;culebra&lt;/b&gt;&lt;/span&gt; and the culebra window where the interaction takes place.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;iframe allowfullscreen=&#39;allowfullscreen&#39; webkitallowfullscreen=&#39;webkitallowfullscreen&#39; mozallowfullscreen=&#39;mozallowfullscreen&#39; width=&#39;320&#39; height=&#39;266&#39; src=&#39;https://www.youtube.com/embed/Ntc2Zp9NGas?feature=player_embedded&#39; frameborder=&#39;0&#39;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://dtmilano.blogspot.com/2014/11/culebra-magical-drag.html</link><author>noreply@blogger.com (Diego Torres Milano)</author><thr:total>0</thr:total></item></channel></rss>