├── .gitignore ├── .travis.yml ├── README.md ├── android-sample-espresso-tests ├── AndroidManifest.xml ├── build.xml ├── pom.xml ├── project.properties ├── repo │ └── com │ │ └── google │ │ └── android │ │ └── android-espresso │ │ ├── 1.0-SNAPSHOT │ │ ├── android-espresso-1.0-20131019.232110-1.jar │ │ ├── android-espresso-1.0-20131019.232110-1.jar.md5 │ │ ├── android-espresso-1.0-20131019.232110-1.jar.sha1 │ │ ├── android-espresso-1.0-20131019.232110-1.pom │ │ ├── android-espresso-1.0-20131019.232110-1.pom.md5 │ │ ├── android-espresso-1.0-20131019.232110-1.pom.sha1 │ │ ├── maven-metadata.xml │ │ ├── maven-metadata.xml.md5 │ │ └── maven-metadata.xml.sha1 │ │ ├── maven-metadata.xml │ │ ├── maven-metadata.xml.md5 │ │ └── maven-metadata.xml.sha1 └── src │ └── main │ └── java │ └── com │ └── octo │ └── android │ └── sample │ └── espresso │ └── test │ └── EspressoSampleTest.java ├── android-sample-robolectric-tests ├── README.txt ├── pom.xml ├── project.properties └── src │ └── test │ ├── java │ └── com │ │ └── octo │ │ └── android │ │ └── sample │ │ └── ui │ │ └── MyActivityTest.java │ └── resources │ ├── emulator-5554 │ └── com.octo.android.sample.test.HelloAndroidActivitySpoonTest │ │ └── testCompute │ │ └── 1365867131614_initial_state.png │ └── org.robolectric.Config.properties ├── android-sample-tests ├── AndroidManifest.xml ├── assets │ └── env.properties ├── compare-spoon-screenshots.sh ├── default.properties ├── diff.png ├── lint.xml ├── pom.xml ├── project.properties ├── res │ ├── drawable-hdpi │ │ └── ic_launcher_robospice.png │ ├── drawable-ldpi │ │ └── icon.png │ ├── drawable-mdpi │ │ └── ic_launcher_robospice.png │ ├── drawable-xhdpi │ │ └── ic_launcher_robospice.png │ ├── layout │ │ └── main.xml │ ├── raw │ │ ├── binary.png │ │ └── lorem_ipsum.txt │ └── values │ │ └── strings.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── octo │ │ └── android │ │ └── sample │ │ └── test │ │ ├── DummyComputerTest.java │ │ ├── HelloAndroidActivityBoundBoxTest.java │ │ ├── HelloAndroidActivityFestAndroidTest.java │ │ ├── HelloAndroidActivityRobotiumTest.java │ │ ├── HelloAndroidActivitySpoonTest.java │ │ └── HelloAndroidActivityTest.java │ └── test │ └── resources │ └── emulator-5554 │ └── com.octo.android.sample.test.HelloAndroidActivitySpoonTest │ └── testCompute │ └── 1365867131614_initial_state.png ├── android-sample-ui-tests ├── build.xml ├── pom.xml ├── project.properties └── src │ └── main │ └── java │ └── com │ └── octo │ └── android │ └── sample │ └── uitest │ └── UIAutomatorSampleTest.java ├── android-sample ├── AndroidManifest.xml ├── config │ └── quality │ │ └── classycle │ │ └── dependencyDefinitionFile ├── findbugs-filter.xml ├── lint.xml ├── pom.xml ├── project.properties ├── res │ ├── drawable-hdpi │ │ ├── ic_launcher_robospice.png │ │ └── ic_warning_for_lint.png │ ├── drawable-mdpi │ │ └── ic_launcher_robospice.png │ ├── drawable-xhdpi │ │ └── ic_launcher_robospice.png │ ├── layout │ │ └── main.xml │ └── values │ │ └── strings.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── octo │ │ └── android │ │ └── sample │ │ ├── model │ │ ├── Computer.java │ │ └── DummyComputer.java │ │ └── ui │ │ └── HelloAndroidActivity.java │ └── test │ └── monkeyrunner │ ├── example-test.py │ └── example-test2.py ├── build.gradle ├── config └── quality │ ├── checkstyle │ └── checkstyle.xml │ ├── findbugs │ └── findbugs-filter.xml │ └── pmd │ └── pmd-ruleset.xml ├── gfx ├── bugdroid-duke-armor.jpg ├── screenshot-sonar-emma-config.png ├── screenshot-sonar-jacoco.png ├── screenshot-sonar-monkey.png ├── screenshot-sonar-robolectric-config.png ├── screenshot-spoon.png └── screenshot-uiautomator.png ├── gradle └── classycle.gradle ├── pom.xml ├── settings.gradle └── wait_for_emulator /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | jarlist.cache 11 | 12 | #jacoco files 13 | *.exec 14 | 15 | # generated files 16 | */bin/ 17 | */gen/ 18 | */out/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | release.properties 23 | 24 | # Eclipse project files 25 | .classpath 26 | .project 27 | .settings 28 | .settings/ 29 | .DS_Store 30 | .factorypath 31 | 32 | #Intelli J project files 33 | .idea/ 34 | .iml 35 | 36 | #Maven project files 37 | target/ 38 | 39 | #Maven release files 40 | *.releaseBackup 41 | *.versionsBackup 42 | 43 | #robolectric cache 44 | tmp/ 45 | 46 | #monkey 47 | monkey.log 48 | 49 | #gradle 50 | .gradle 51 | build/ 52 | *.*~ 53 | 54 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | #Thanks to https://raw.github.com/embarkmobile/android-maven-example/master/.travis.yml 2 | 3 | branches: 4 | except: 5 | - repository 6 | 7 | language: java 8 | jdk: oraclejdk7 9 | env: 10 | matrix: 11 | # android-16 is always included 12 | - ANDROID_SDKS=android-8 ANDROID_TARGET=android-8 ANDROID_ABI=armeabi 13 | - ANDROID_SDKS=android-10 ANDROID_TARGET=android-10 ANDROID_ABI=armeabi 14 | - ANDROID_SDKS=android-16,sysimg-16 ANDROID_TARGET=android-16 ANDROID_ABI=armeabi-v7a 15 | - ANDROID_SDKS=android-17,sysimg-17 ANDROID_TARGET=android-17 ANDROID_ABI=armeabi-v7a 16 | before_install: 17 | # check the travis file 18 | - gem install travis-lint 19 | - travis-lint 20 | # Install base Android SDK 21 | - sudo apt-get update -qq 22 | - if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq -o Dpkg::Options::="--force-confold" --force-yes --yes libgd2-xpm ia32-libs ia32-libs-multiarch > /dev/null ; fi 23 | - wget http://dl.google.com/android/android-sdk_r22.0.1-linux.tgz 24 | - tar xzf android-sdk_r22.0.1-linux.tgz 25 | - export ANDROID_HOME=$PWD/android-sdk-linux 26 | - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools 27 | 28 | # Install required components. 29 | # For a full list, run `android list sdk -a --extended` 30 | # Note that sysimg-16 downloads the ARM, x86 and MIPS images (we should optimize this). 31 | # Other relevant API's: 32 | # addon-google_apis-google-16 33 | - echo "y" | android update sdk --filter platform-tools,build-tools-17.0.0,android-16,extra-android-support,$ANDROID_SDKS --no-ui --force > /dev/null 34 | 35 | #install Android SDK 17 local files to local maven repo 36 | - git clone https://github.com/mosabua/maven-android-sdk-deployer.git 37 | - cd maven-android-sdk-deployer/platforms/android-17/ 38 | - mvn install 39 | - cd ../../tools 40 | - mvn clean install 41 | - #Add V4 support library (to use FEST Android) 42 | - cd ../extras/compatibility-v4/ 43 | - mvn install 44 | - cd ../../../ 45 | # Create and start emulator 46 | # Create and start emulator 47 | - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI 48 | - mksdcard 50M /tmp/sdcard.img 49 | - emulator -avd test -no-skin -no-audio -no-window -prop persist.sys.language=en -prop persist.sys.country=US -sdcard /tmp/sdcard.img & 50 | 51 | 52 | before_script: 53 | - ./wait_for_emulator 54 | 55 | script: 56 | #run all tests 57 | - mvn clean install -P default -DignoreTestFailure=true 58 | 59 | after_script: 60 | - adb logcat -t 500 61 | - for i in android-sample-ui-tests/target/screenshots/*; do echo $i; asciiview $i; done 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Quality Tools for Android 2 | 3 | 5 | 6 | This is an Android sample app + tests that will be used to work on various project to increase the quality of the Android platform. 7 | 8 | The idea is that Android programming is still in its infancy compared to the Java world. 9 | The Android community needs more robustness in Android apps and it looks like a good idea to build on the Java world experience and use its best tools for Quality Analysis. 10 | 11 | We want to provide a full featured industrial development environment that can be used to create more 12 | robust projects on Android, by using any of the most interesting and popular technologies. 13 | 14 | Here are [some slides](https://speakerdeck.com/stephanenicolas/devoxx-2013-fr-beef-you-android-apps-using-java-tools) to present Quality Tools for Android. 15 | 16 | # Already integrated : 17 | 18 | * Standard Android testing framework and code coverage using emma, reported in Sonar. That also covers robotium, easy mock and mockito technologies. 19 | * Robolectric testing framework and code coverage using Cobertura, reported in Sonar. Now in same eclipse project / maven module as app under test [thanks to this thread](https://github.com/rgladwell/m2e-android/issues/52). 20 | * UI Automator testing through a new android maven plugin goal (to be released in android-maven-plugin-3.5.2) and result in sonar. 21 | * Espresso / Android test kit 22 | * Configuration works out of the box in eclipse 23 | * Lint integration via Maven. 24 | * PMD, findbugs, checkstyle integration via Maven, reported in Sonar. 25 | * [lint android maven lint](https://github.com/lewisd32/lint-maven-plugin) integration (pom checker) 26 | * Monkey testing is now automated and reported in Sonar. 27 | * Add [classycle](http://classycle.sourceforge.net/) support, to enforce architectural constraints, through [classycle maven plugin](https://github.com/hcoles/classycle-maven-plugin) 28 | * [Spoon from square](https://github.com/square/spoon), including screenshots during tests. 29 | * 30 | * [maven-android-sdk-deployer](https://github.com/mosabua/maven-android-sdk-deployer) to deliver android jars (including uiautomator) 31 | * [sonar android lint plugin](https://github.com/jeromevdl/sonar-android-lint-plugin) 32 | * [FEST Android](https://github.com/square/fest-android). 33 | * Jacoco [offline instrumentation](https://github.com/jacoco/jacoco/pull/64#issuecomment-12150910) for both robolectric and standard junit tests. 34 | * Testing technologies integrated : 35 | * Standard Android tests 36 | * easymock 37 | * mockito 38 | * mockwebserver 39 | * robotium 40 | * fest-android 41 | * robolectric tests 42 | * hamcrest 43 | * easymock 44 | * mockito 45 | * [Screenshot lib](https://github.com/rtyley/android-screenshot-lib) works during UIAutomator tests. 46 | * [BoundBox](https://github.com/stephanenicolas/boundbox) is used in some StandardAndroid tests and Robolectric tests. 47 | * support for [Travis CI](https://travis-ci.org/stephanenicolas/Quality-Tools-for-Android). 48 | * Build Status on Travis: [![Build Status on Travis:](https://api.travis-ci.org/stephanenicolas/Quality-Tools-for-Android.png)](https://api.travis-ci.org/stephanenicolas/Quality-Tools-for-Android) 49 | 50 | 51 | 52 | # What is missing (TODO/INTEGRATE) : 53 | 54 | 1. get aggregated tests and code coverage for all testing technologies inside a nice Sonar dashboard for Android. 55 | 2. add support for monkey runner through maven 56 | 3. add calabash support. 57 | 4. Add support for JUnit 4 on Android : http://stackoverflow.com/questions/9809180/why-is-junit-4-on-android-not-working 58 | 59 | # Usage 60 | 61 | This section describes how to build & test the project using those different testing technologies. 62 | 63 | Please note that this project is under active development. 64 | Some goals may require a snapshot version of the maven android plugin available 65 | on [sonatype snapshot repo](https://oss.sonatype.org/content/repositories/jayway-snapshots/). 66 | 67 | ## Install Android Latest SDK through Android SDK Manager 68 | 69 | This can be done graphically, or [via command line (for CI servers)](http://stackoverflow.com/q/4681697/693752). 70 | 71 | ## Install the Android SDK through maven-android-sdk-deployer 72 | 73 | As it takes time to get android jars in maven central, including android UI automator jars in maven central, 74 | we recommend to use [maven-android-sdk-deployer](https://github.com/mosabua/maven-android-sdk-deployer) to obtain android artefacts. 75 | This step can also be executed on a CI server. 76 | 77 | ```bash 78 | #install Android SDK 17 local files to local maven repo 79 | git clone git@github.com:mosabua/maven-android-sdk-deployer.git 80 | cd maven-android-sdk-deployer/ 81 | mvn install -P 4.2 82 | #Add V4 support library (to use FEST Android) 83 | cd extras/compatibility-v4/ 84 | mvn install 85 | ``` 86 | 87 | ## Standard Android testing APIs and code coverage using emma 88 | 89 | To build the sample project and run the sample app on a plugged rooted device / running emulator : 90 | 91 | ```bash 92 | # in parent folder 93 | mvn clean install -P emma 94 | mvn sonar:sonar -P emma 95 | ``` 96 | 97 | you will get tests results in : target/surefire-reports/. 98 | you will get tests coverage in : target/emma/. 99 | 100 | Here is the result in sonar : 101 | 102 | 103 | You may need to restart adb as root to be able to pull the emma coverage file. In a terminal, type : 104 | ```bash 105 | adb root 106 | ``` 107 | 108 | ## Robolectric and code coverage using cobertura 109 | 110 | ```bash 111 | # in parent folder 112 | mvn clean cobertura:cobertura -P cobertura 113 | mvn sonar:sonar -P cobertura 114 | ``` 115 | Here is the result in sonar : 116 | 117 | 118 | 119 | ## Unified code coverage for both Robolectric and standard Android Junit tests via Jacoco 120 | 121 | Using offline instrumentation of Jacoco, it is possilbe to completly replace emma by jacoco for instrumentation. 122 | This allows to get both robolectric and standard tests code coverage inside the same project dashboard with sonar. 123 | 124 | * Robolectric are considered standard unit tests. 125 | * standard Android Junit tests are considered as standard integration tests. 126 | This makes sense as Robolectric tests mock an android platform and can be considered more "unit" tests thant standard android tests because the latter needs a real android platform and relies on networking, disk, locale, etc. 127 | It would be better to be able to give names to the test suites inside the widget, and even to add more test suites, for instance to add UI testing (black box testing) or monkey testing. 128 | 129 | ```bash 130 | # in parent folder 131 | mvn clean install -P jacoco 132 | mvn sonar:sonar -P jacoco 133 | ``` 134 | Here is the result in sonar : 135 | 136 | 137 | 138 | ## UI Automator 139 | 140 | 141 | ```bash 142 | # in parent folder 143 | mvn clean install -P uiautomator 144 | mvn sonar:sonar -P uiautomator 145 | ``` 146 | Here is the result in sonar : 147 | 148 | 149 | ## Espresso 150 | 151 | To build the sample project and run the sample app on a plugged device / running emulator : 152 | 153 | ```bash 154 | # in parent folder 155 | mvn clean install -P espresso 156 | ``` 157 | 158 | ## Spoon from Squareup 159 | 160 | ```bash 161 | # in parent folder 162 | mvn clean install -P spoon 163 | 164 | #then browse to android-sample-tests/target/spoon-output/index.html 165 | ``` 166 | 167 | Here is the result in a browser : 168 | 169 | 170 | ## Monkey testing 171 | 172 | Monkey is part of Android SDK and allows to harness Application UI and test their robustness. 173 | We contributed to a new maven android plugin goal to use monkey automatically and get reports in junit format. 174 | 175 | The results can be displayed inside sonar and will appear as normal unit tests. 176 | 177 | ```bash 178 | # in parent folder 179 | mvn clean compile -P monkey 180 | mvn sonar:sonar -P monkey 181 | ``` 182 | Here is the result in sonar : 183 | 184 | 185 | 186 | ## Package cycles check via classycle 187 | 188 | You will need a JDK 1.7 for this profile to work correctly. 189 | 190 | ```bash 191 | # in parent folder 192 | mvn clean compile -P cycle 193 | ``` 194 | 195 | Will check package cycles (also called package tangling in Sonar) and check the build if given cycles are detected. 196 | [Classycle](http://classycle.sourceforge.net/) lets you define architectural constraints that can be checked automatically. 197 | 198 | Depedency definition files are very simple to edit. Here is an example : 199 | ```` 200 | show allResults 201 | 202 | ###define packages / groups of packages of interest 203 | 204 | ## layers 205 | [ui] = com.octo.android.sample.ui.* 206 | [other] = com.octo.android.sample.* excluding [ui] 207 | 208 | ###check layers integrity 209 | check [other] independentOf [ui] 210 | ```` 211 | ## Robolectric development in eclipse 212 | 213 | RoboElectric tests are separated from the sample project, as all testing technologies. 214 | 215 | To make this configuration work in eclipse, do the following : 216 | 217 | //TODO update this 218 | * after each "maven update" of your project, remember to configure the build path of your project, go to the last tab and *uncheck* maven dependencies so that they are not included into the final apk. 219 | * in your eclipse junit configuration for your project, add both "bin/classes" to the classpath, and set the environment variable ANDROID_HOME to the android home folder on your computer. 220 | * add the android jars from your maven repository to your junit run configuration in eclipse. 221 | 222 | TODO : POST a SNAPSHOT of the JUnit run config in eclipse 223 | 224 | Now, simply execute your project as a JUnit project and all robolectric tests will get executed. 225 | 226 | ## Using Gradle 227 | 228 | All gradle-related file are stored in folder `gradle`. 229 | 230 | With Gradle 1.8+ and android gradle plugin 0.6.+ : 231 | 232 | ### build the app under tests 233 | 234 | ```bash 235 | # in parent folder 236 | gradle clean assemble 237 | ``` 238 | 239 | ### launch the app under tests 240 | 241 | ```bash 242 | # in parent folder 243 | gradle :android-sample:installDebug 244 | ``` 245 | 246 | ### play standard android tests (without emma coverage): 247 | 248 | ```bash 249 | # in parent folder 250 | gradle clean assembleDebug connectedInstrumentTest 251 | #export to sonar 252 | gradle :android-sample:sonarRunner 253 | ``` 254 | 255 | ### play espresso tests (without emma coverage): 256 | 257 | ```bash 258 | # in parent folder 259 | gradle clean assembleDebug :android-sample-espresso-tests:connectedInstrumentTest 260 | ``` 261 | 262 | ### play robolectric tests : 263 | 264 | ```bash 265 | # in parent folder 266 | gradle clean assembleDebug robolectric 267 | #export to sonar 268 | gradle :android-sample-robolectric-tests:sonarRunner 269 | ``` 270 | 271 | ### Findbugs + Checkstyle + PMD + classycle : 272 | 273 | ```bash 274 | # in parent folder 275 | gradle check 276 | ``` 277 | 278 | or independently : 279 | ```bash 280 | # in parent folder 281 | #you need to run assemble before most of those 282 | #gradle assembleDebug 283 | gradle checkstyle 284 | gradle findbugs 285 | gradle pmd 286 | gradle classycle 287 | ``` 288 | 289 | ### Running lint : 290 | ```bash 291 | # in parent folder 292 | gradle :android-sample:lint 293 | ``` 294 | 295 | ### Aggregate reports : 296 | ```bash 297 | # in parent folder 298 | gradle buildDashboard 299 | ``` 300 | 301 | ### TODO run test coverage using emma (standard tests): 302 | 303 | ### TODO run test coverage using cobertura (robolectric tests): 304 | 305 | ### TODO run test coverage using jacoco (both tests): 306 | 307 | ### TODO play uiautomator tests 308 | 309 | ### TODO play monkey tests 310 | 311 | ### TODO play monkey runner tests 312 | 313 | ### TODO shoot more stuff to sonar 314 | 315 | 316 | 317 | # Thanks to 318 | * [OCTO Technology](http://www.octo.com/en) to provide us with free time to work on that project. 319 | * Henri Treblay from [OCTO Technology](http://www.octo.com/en) for having ported [EasyMock](http://www.easymock.org/) to Android. 320 | * Thanks to [Jayway](http://www.jayway.com/blog) for their [Android Maven Plugin](http://code.google.com/p/maven-android-plugin/). 321 | * Thanks to [Sonar Source](http://www.sonarsource.org/) for supporting this effort, especially for this [project's configuration](https://github.com/SonarSource/sonar-examples/tree/master/projects/android). 322 | * Thanks to Jake Wharton and Pierre-Yves Ricaud for mentionning FEST-Android. 323 | * Thanks to [Novoda](http://novoda.com) for their [Gradle Robolectric plugin](https://github.com/novoda/robolectric-plugin). 324 | * Thanks to [Seth Rylan Gainey](https://github.com/sethrylan) for his [Gradle settings](https://github.com/sethrylan/rosette). 325 | 326 | 327 | 328 | ## Quality Tools for Android in the news !! 329 | * [Android Weekly issue #55 !] (http://androidweekly.net/#latest-issue) 330 | * [Android Dev Weekly, issue #49 !] (http://androiddevweekly.com/2013/03/11/Issue-49.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+AndroidDevWeekly+%28%23AndroidDev+Weekly%29) 331 | * Our presentation at [Devoxx France 2013](https://speakerdeck.com/stephanenicolas/devoxx-2013-fr-beef-you-android-apps-using-java-tools). 332 | 333 | 334 | License 335 | ------- 336 | 337 | Copyright (C) 2013 Stéphane Nicolas & Jérôme Van Der Linden 338 | 339 | Licensed under the Apache License, Version 2.0 (the "License"); 340 | you may not use this file except in compliance with the License. 341 | You may obtain a copy of the License at 342 | 343 | http://www.apache.org/licenses/LICENSE-2.0 344 | 345 | Unless required by applicable law or agreed to in writing, software 346 | distributed under the License is distributed on an "AS IS" BASIS, 347 | -------------------------------------------------------------------------------- /android-sample-espresso-tests/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /android-sample-espresso-tests/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | 51 | 52 | 56 | 57 | 69 | 70 | 71 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /android-sample-espresso-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.octo.android 8 | android-sample-parent 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | android-sample-espresso-tests 13 | apk 14 | android-sample-espresso-tests 15 | 16 | 17 | 1.8 18 | 19 | 20 | 21 | 22 | 23 | project.local 24 | project 25 | file:${project.basedir}/repo 26 | 27 | 28 | 29 | 30 | 31 | android 32 | android 33 | 34 | 35 | android.support 36 | compatibility-v4 37 | provided 38 | 39 | 40 | com.octo.android 41 | android-sample 42 | ${project.version} 43 | jar 44 | provided 45 | 46 | 47 | com.octo.android 48 | android-sample 49 | ${project.version} 50 | apk 51 | provided 52 | 53 | 54 | 55 | com.google.android 56 | android-espresso 57 | 1.0-SNAPSHOT 58 | 59 | 60 | 61 | 62 | 63 | 64 | true 65 | com.jayway.maven.plugins.android.generation2 66 | android-maven-plugin 67 | 68 | 69 | 70 | maven-compiler-plugin 71 | 72 | 73 | org.codehaus.mojo 74 | build-helper-maven-plugin 75 | 76 | 77 | add-source 78 | generate-sources 79 | 80 | add-source 81 | 82 | 83 | 84 | ${project.build.directory}/generated-sources/annotations/ 85 | 86 | 87 | 88 | 89 | 90 | 91 | maven-compiler-plugin 92 | 93 | ${java.version} 94 | ${java.version} 95 | 96 | 97 | 98 | maven-pmd-plugin 99 | 100 | true 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | emma 110 | 111 | 112 | emma 113 | emma 114 | 115 | 116 | 117 | 118 | 119 | com.jayway.maven.plugins.android.generation2 120 | android-maven-plugin 121 | 122 | 123 | true 124 | true 125 | 126 | 127 | true 128 | 129 | 130 | pull-coverage 131 | post-integration-test 132 | 133 | pull 134 | 135 | 136 | /data/data/com.octo.android.sample/files/coverage.ec 137 | ${project.basedir}/../android-sample/target/emma/coverage.ec 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | spoon 147 | 148 | 149 | 150 | com.jayway.maven.plugins.android.generation2 151 | android-maven-plugin 152 | true 153 | 154 | true 155 | 156 | 157 | 158 | 159 | com.squareup.spoon 160 | spoon-maven-plugin 161 | ${spoon.version} 162 | 163 | Spoon Sample App 164 | true 165 | 166 | 167 | 168 | integration-test 169 | 170 | run 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | jacoco 180 | 181 | 182 | 183 | com.jayway.maven.plugins.android.generation2 184 | android-maven-plugin 185 | 186 | 187 | 188 | true 189 | 190 | 191 | true 192 | true 193 | 194 | 195 | 196 | 197 | pull-coverage 198 | post-integration-test 199 | 200 | pull 201 | 202 | 203 | /data/data/com.octo.android.sample/files/coverage.ec 204 | ${project.basedir}/../android-sample/target/jacoco-it.exec 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /android-sample-espresso-tests/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/android-espresso-1.0-20131019.232110-1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/android-espresso-1.0-20131019.232110-1.jar -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/android-espresso-1.0-20131019.232110-1.jar.md5: -------------------------------------------------------------------------------- 1 | 44ad9229c39418a729fe5adfe2511e7b -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/android-espresso-1.0-20131019.232110-1.jar.sha1: -------------------------------------------------------------------------------- 1 | 2566c88b5eba4fa5c3d8577aefd3306913f38bf5 -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/android-espresso-1.0-20131019.232110-1.pom: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.google.android 6 | android-espresso 7 | 1.0-SNAPSHOT 8 | 9 | -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/android-espresso-1.0-20131019.232110-1.pom.md5: -------------------------------------------------------------------------------- 1 | 3cd9200bc6ded975ef56948ccbe82ce5 -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/android-espresso-1.0-20131019.232110-1.pom.sha1: -------------------------------------------------------------------------------- 1 | ab2afc662e38c62be46082f94e86fd0b6d3b7a95 -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/maven-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.google.android 4 | android-espresso 5 | 1.0-SNAPSHOT 6 | 7 | 8 | 20131019.232110 9 | 1 10 | 11 | 20131019232110 12 | 13 | 14 | jar 15 | 1.0-20131019.232110-1 16 | 20131019232110 17 | 18 | 19 | pom 20 | 1.0-20131019.232110-1 21 | 20131019232110 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/maven-metadata.xml.md5: -------------------------------------------------------------------------------- 1 | 76352da1adaa1c1ad81e7819ec9193d8 -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/1.0-SNAPSHOT/maven-metadata.xml.sha1: -------------------------------------------------------------------------------- 1 | f5537b45afacd274c96de06d4ebf7634ed190ed5 -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/maven-metadata.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.google.android 4 | android-espresso 5 | 6 | 7 | 1.0-SNAPSHOT 8 | 9 | 20131019232110 10 | 11 | 12 | -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/maven-metadata.xml.md5: -------------------------------------------------------------------------------- 1 | 959e5a9e225f28380ceb1318244cc180 -------------------------------------------------------------------------------- /android-sample-espresso-tests/repo/com/google/android/android-espresso/maven-metadata.xml.sha1: -------------------------------------------------------------------------------- 1 | bc65a7fb4ba92351c17475733cdb45b95d8cc4e2 -------------------------------------------------------------------------------- /android-sample-espresso-tests/src/main/java/com/octo/android/sample/espresso/test/EspressoSampleTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.espresso.test; 2 | 3 | import static com.google.android.apps.common.testing.ui.espresso.Espresso.onView; 4 | import static com.google.android.apps.common.testing.ui.espresso.action.ViewActions.click; 5 | import static com.google.android.apps.common.testing.ui.espresso.assertion.ViewAssertions.matches; 6 | import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withId; 7 | import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.withText; 8 | import android.test.ActivityInstrumentationTestCase2; 9 | 10 | import com.octo.android.sample.R; 11 | import com.octo.android.sample.ui.HelloAndroidActivity; 12 | 13 | /** 14 | * A working example of an espresso test. 15 | * @author SNI 16 | */ 17 | public class EspressoSampleTest extends ActivityInstrumentationTestCase2 { 18 | 19 | public EspressoSampleTest() { 20 | super(HelloAndroidActivity.class); 21 | } 22 | 23 | 24 | @Override 25 | protected void setUp() throws Exception { 26 | super.setUp(); 27 | getActivity(); 28 | } 29 | 30 | @Override 31 | protected void tearDown() throws Exception { 32 | super.tearDown(); 33 | } 34 | 35 | public void testClick() { 36 | onView(withId(R.id.button_main)) 37 | .check(matches(withText("Click !"))); 38 | 39 | onView(withId(R.id.button_main)) 40 | .perform(click()); 41 | 42 | onView(withId(R.id.textview_hello)) 43 | .check(matches(withText("42"))); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /android-sample-robolectric-tests/README.txt: -------------------------------------------------------------------------------- 1 | To setup such a project: 2 | 3 | * robolectric: add src/test/resources/org.robolectric.Config.properties 4 | 5 | manifest:../android-sample/AndroidManifest.xml 6 | 7 | * maven: add pom with config pointing to project under test manifest, assets and res 8 | 9 | * eclipse: add res, assets and AndroidManifest LINKS to project under tests 10 | -------------------------------------------------------------------------------- /android-sample-robolectric-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.octo.android 8 | android-sample-parent 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | android-sample-robolectric-tests 13 | apk 14 | android-sample-robolectric-tests 15 | 16 | 17 | 18 | android 19 | android 20 | 21 | 22 | android.support 23 | compatibility-v4 24 | 25 | 26 | 27 | com.octo.android 28 | android-sample 29 | ${project.version} 30 | jar 31 | provided 32 | 33 | 34 | com.octo.android 35 | android-sample 36 | ${project.version} 37 | apk 38 | provided 39 | 40 | 41 | 42 | 43 | org.mockito 44 | mockito-core 45 | test 46 | 47 | 48 | org.hamcrest 49 | hamcrest-core 50 | 51 | 52 | 53 | 54 | org.easymock 55 | easymock 56 | test 57 | 58 | 59 | org.robolectric 60 | robolectric 61 | test 62 | 63 | 64 | com.google.android 65 | support-v4 66 | 67 | 68 | 69 | 70 | junit 71 | junit 72 | test 73 | 74 | 75 | org.jacoco 76 | org.jacoco.agent 77 | runtime 78 | test 79 | 80 | 81 | org.boundbox 82 | boundbox-library 83 | 84 | 85 | 86 | 87 | 88 | org.codehaus.mojo 89 | cobertura-maven-plugin 90 | ${cobertura.version} 91 | 92 | 93 | 94 | 95 | 96 | 97 | true 98 | com.jayway.maven.plugins.android.generation2 99 | android-maven-plugin 100 | 101 | ${project.basedir}/../android-sample/AndroidManifest.xml 102 | ${project.basedir}/../android-sample/assets 103 | ${project.basedir}/../android-sample/res 104 | 105 | 106 | 16 107 | 108 | true 109 | 110 | true 111 | 112 | 113 | 114 | 115 | org.codehaus.mojo 116 | build-helper-maven-plugin 117 | 118 | 119 | add-source 120 | generate-sources 121 | 122 | add-source 123 | 124 | 125 | 126 | ${project.build.directory}/generated-sources/annotations/ 127 | 128 | 129 | 130 | 131 | 132 | 133 | maven-compiler-plugin 134 | 135 | ${java.version} 136 | ${java.version} 137 | 138 | org.boundbox.processor.BoundBoxProcessor 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | cobertura 149 | 150 | 151 | 152 | com.github.goldin 153 | copy-maven-plugin 154 | 0.2.5 155 | 156 | 157 | copy-cobertura-data-from-project-under-test 158 | compile 159 | 160 | copy 161 | 162 | 163 | 164 | 165 | ${project.basedir}/../android-sample/target/cobertura 166 | ${project.basedir}/target/cobertura 167 | 168 | *.ser 169 | 170 | 171 | 172 | ${project.basedir}/../android-sample/target/generated-classes/cobertura/ 173 | ${project.basedir}/target/generated-classes/cobertura 174 | true 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | org.codehaus.mojo 183 | cobertura-maven-plugin 184 | 185 | xml 186 | 187 | 188 | 189 | 190 | clean 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | jacoco 200 | 201 | 202 | 203 | com.jayway.maven.plugins.android.generation2 204 | android-maven-plugin 205 | 206 | 207 | 208 | true 209 | 210 | 211 | true 212 | true 213 | 214 | 215 | 216 | 217 | pull-coverage 218 | post-integration-test 219 | 220 | pull 221 | 222 | 223 | /data/data/com.octo.android.sample/files/coverage.ec 224 | ${project.basedir}/../android-sample/target/jacoco-it.exec 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /android-sample-robolectric-tests/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | 16 | -------------------------------------------------------------------------------- /android-sample-robolectric-tests/src/test/java/com/octo/android/sample/ui/MyActivityTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.ui; 2 | 3 | import static org.hamcrest.CoreMatchers.equalTo; 4 | import static org.junit.Assert.assertThat; 5 | 6 | import org.boundbox.BoundBox; 7 | import org.easymock.EasyMock; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.mockito.Mockito; 11 | import org.robolectric.Robolectric; 12 | import org.robolectric.RobolectricTestRunner; 13 | 14 | import android.support.v4.app.FragmentActivity; 15 | import android.widget.Button; 16 | import android.widget.TextView; 17 | 18 | import com.octo.android.sample.R; 19 | import com.octo.android.sample.model.Computer; 20 | 21 | @RunWith(RobolectricTestRunner.class) 22 | public class MyActivityTest { 23 | 24 | @Test 25 | public void shouldHaveApplicationName() throws Exception { 26 | // given 27 | HelloAndroidActivity activityUnderTest = Robolectric.buildActivity(HelloAndroidActivity.class).create().get(); 28 | 29 | // when 30 | 31 | // then 32 | String appName = activityUnderTest.getResources().getString(R.string.app_name); 33 | assertThat(appName, equalTo("sonar-android-sample")); 34 | } 35 | 36 | @Test 37 | public void shouldNotUseNullComputer() throws Exception { 38 | // given 39 | HelloAndroidActivity activityUnderTest = Robolectric.buildActivity(HelloAndroidActivity.class).create().get(); 40 | 41 | activityUnderTest.setComputer(null); 42 | 43 | // when 44 | Button button = (Button) activityUnderTest.findViewById(R.id.button_main); 45 | button.performClick(); 46 | 47 | // then 48 | TextView textViewHello = (TextView) activityUnderTest.findViewById(R.id.textview_hello); 49 | String textViewHelloString = textViewHello.getText().toString(); 50 | assertThat(textViewHelloString, equalTo("-")); 51 | } 52 | 53 | @Test 54 | public void shouldUseDummyComputer() throws Exception { 55 | final int EXPECTED_RESULT = 42; 56 | // given 57 | HelloAndroidActivity activityUnderTest = Robolectric.buildActivity(HelloAndroidActivity.class).create().get(); 58 | 59 | // when 60 | Button button = (Button) activityUnderTest.findViewById(R.id.button_main); 61 | button.performClick(); 62 | 63 | // then 64 | TextView textViewHello = (TextView) activityUnderTest.findViewById(R.id.textview_hello); 65 | String textViewHelloString = textViewHello.getText().toString(); 66 | assertThat(textViewHelloString, equalTo(String.valueOf(EXPECTED_RESULT))); 67 | } 68 | 69 | @Test 70 | public void shouldUseCustomComputerUsingEasyMock() throws Exception { 71 | final int EXPECTED_RESULT = 1; 72 | // given 73 | HelloAndroidActivity activityUnderTest = Robolectric.buildActivity(HelloAndroidActivity.class).create().get(); 74 | Computer mockComputer = EasyMock.createMock(Computer.class); 75 | EasyMock.expect(mockComputer.getResult()).andReturn(EXPECTED_RESULT); 76 | 77 | activityUnderTest.setComputer(mockComputer); 78 | EasyMock.replay(mockComputer); 79 | 80 | // when 81 | Button button = (Button) activityUnderTest.findViewById(R.id.button_main); 82 | button.performClick(); 83 | 84 | // then 85 | EasyMock.verify(mockComputer); 86 | TextView textViewHello = (TextView) activityUnderTest.findViewById(R.id.textview_hello); 87 | String textViewHelloString = textViewHello.getText().toString(); 88 | assertThat(textViewHelloString, equalTo(String.valueOf(EXPECTED_RESULT))); 89 | } 90 | 91 | @Test 92 | public void shouldUseCustomComputerUsingMockito() throws Exception { 93 | final int EXPECTED_RESULT = 1; 94 | // given 95 | HelloAndroidActivity activityUnderTest = Robolectric.buildActivity(HelloAndroidActivity.class).create().get(); 96 | 97 | Computer mockComputer = Mockito.mock(Computer.class); 98 | Mockito.when(mockComputer.getResult()).thenReturn(EXPECTED_RESULT); 99 | 100 | activityUnderTest.setComputer(mockComputer); 101 | 102 | // when 103 | Button button = (Button) activityUnderTest.findViewById(R.id.button_main); 104 | button.performClick(); 105 | 106 | // then 107 | Mockito.verify(mockComputer, Mockito.times(1)).getResult(); 108 | TextView textViewHello = (TextView) activityUnderTest.findViewById(R.id.textview_hello); 109 | String textViewHelloString = textViewHello.getText().toString(); 110 | assertThat(textViewHelloString, equalTo(String.valueOf(EXPECTED_RESULT))); 111 | } 112 | 113 | @BoundBox(boundClass=HelloAndroidActivity.class, maxSuperClass=FragmentActivity.class) 114 | @Test 115 | public void shouldUseCustomComputerUsingMockitoAndBoundBox() throws Exception { 116 | final int EXPECTED_RESULT = 1; 117 | // given 118 | HelloAndroidActivity activityUnderTest = Robolectric.buildActivity(HelloAndroidActivity.class).create().get(); 119 | BoundBoxOfHelloAndroidActivity boundBoxOfHelloAndroidActivity = new BoundBoxOfHelloAndroidActivity(activityUnderTest); 120 | 121 | Computer mockComputer = Mockito.mock(Computer.class); 122 | Mockito.when(mockComputer.getResult()).thenReturn(EXPECTED_RESULT); 123 | 124 | boundBoxOfHelloAndroidActivity.setComputer(mockComputer); 125 | 126 | // when 127 | boundBoxOfHelloAndroidActivity.boundBox_getButton().performClick(); 128 | 129 | // then 130 | Mockito.verify(mockComputer, Mockito.times(1)).getResult(); 131 | String textViewHelloString = boundBoxOfHelloAndroidActivity.boundBox_getTextView().getText().toString(); 132 | assertThat(textViewHelloString, equalTo(String.valueOf(EXPECTED_RESULT))); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /android-sample-robolectric-tests/src/test/resources/emulator-5554/com.octo.android.sample.test.HelloAndroidActivitySpoonTest/testCompute/1365867131614_initial_state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-robolectric-tests/src/test/resources/emulator-5554/com.octo.android.sample.test.HelloAndroidActivitySpoonTest/testCompute/1365867131614_initial_state.png -------------------------------------------------------------------------------- /android-sample-robolectric-tests/src/test/resources/org.robolectric.Config.properties: -------------------------------------------------------------------------------- 1 | manifest:../android-sample/AndroidManifest.xml 2 | -------------------------------------------------------------------------------- /android-sample-tests/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /android-sample-tests/assets/env.properties: -------------------------------------------------------------------------------- 1 | # Environment (DEV / PROD) 2 | env=DEV 3 | 4 | # Web Service Url 5 | ws.url=http://projets.octo.com/frMobileWsHBK/ws/ 6 | 7 | # Customer web url 8 | web.url=http://bkrender-cetelem.dev.bkt.mobi/home.do?hybrid=android 9 | 10 | # TODO : remove this when deliver release 11 | ws.url.other=https://homol-mobile.neuges.org/frmobilehbkws/ws/ 12 | web.url.other=https://homol-mobile.neuges.org/bkrfrmobilehbk/authentification.do?hybrid=android -------------------------------------------------------------------------------- /android-sample-tests/compare-spoon-screenshots.sh: -------------------------------------------------------------------------------- 1 | SPOON_DIR="target/spoon-output/image" 2 | REFERENCE_DIR="src/test/resources/" 3 | 4 | #if reference dir doesn't exist, create it 5 | if [ ! -d "$REFERENCE_DIR" ]; then 6 | mkdir -p $REFERENCE_DIR 7 | fi 8 | 9 | ############################# 10 | #loop through all screenshots 11 | ############################# 12 | 13 | for SCREENSHOT in `find $SPOON_DIR/* | grep png | grep -v diff` 14 | do 15 | #echo "screenshot is at $SCREENSHOT" 16 | REFERENCE="$REFERENCE_DIR`echo $SCREENSHOT| cut -c 27-`" 17 | #echo "reference is at $REFERENCE" 18 | SCREENSHOT_NAME=`echo $SCREENSHOT | tr "/" "_"` 19 | 20 | #if there is no reference, copy screenshot as reference 21 | if [ ! -f "$REFERENCE" ]; then 22 | mkdir -p `dirname $REFERENCE` 23 | #cp $SCREENSHOT $REFERENCE 24 | NO_REFERENCE="1" 25 | fi 26 | 27 | #create a diff 28 | compare $SCREENSHOT $REFERENCE -compose src $SPOON_DIR/diff-$SCREENSHOT_NAME 2>/dev/null 29 | 30 | #automate answer 31 | compare -metric AE -fuzz '10%' $SCREENSHOT $REFERENCE $SPOON_DIR/success-$SCREENSHOT_NAME 2>/dev/null 32 | SUCCESS=$? 33 | rm -f $SPOON_DIR/success-$SCREENSHOT_NAME 34 | 35 | echo -n "`basename $SCREENSHOT`" 36 | if [ "$NO_REFERENCE" = "1" ] 37 | then 38 | echo " NO_REF" 39 | else 40 | if [ "$SUCCESS" = "0" ] 41 | then 42 | echo " OK" 43 | rm -f $SPOON_DIR/diff-$SCREENSHOT_NAME 44 | else 45 | echo " NOK" 46 | fi 47 | fi 48 | 49 | done 50 | -------------------------------------------------------------------------------- /android-sample-tests/default.properties: -------------------------------------------------------------------------------- 1 | # Project target. 2 | target=android-10 3 | -------------------------------------------------------------------------------- /android-sample-tests/diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-tests/diff.png -------------------------------------------------------------------------------- /android-sample-tests/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android-sample-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.octo.android 8 | android-sample-parent 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | android-sample-tests 13 | apk 14 | android-sample-tests 15 | 16 | 17 | 1.8 18 | 19 | 20 | 21 | 22 | android 23 | android 24 | 25 | 26 | android.support 27 | compatibility-v4 28 | provided 29 | 30 | 31 | com.octo.android 32 | android-sample 33 | ${project.version} 34 | jar 35 | provided 36 | 37 | 38 | com.octo.android 39 | android-sample 40 | ${project.version} 41 | apk 42 | provided 43 | 44 | 45 | 46 | 47 | org.easymock 48 | easymock 49 | 50 | 51 | org.mockito 52 | mockito-core 53 | 54 | 55 | com.google.dexmaker 56 | dexmaker 57 | 58 | 59 | com.google.dexmaker 60 | dexmaker-mockito 61 | 62 | 63 | com.google.mockwebserver 64 | mockwebserver 65 | 66 | 67 | com.jayway.android.robotium 68 | robotium-solo 69 | 70 | 71 | com.squareup.spoon 72 | spoon-client 73 | 74 | 75 | com.squareup 76 | fest-android 77 | 78 | 79 | org.boundbox 80 | boundbox-library 81 | 82 | 83 | 84 | 85 | 86 | 87 | true 88 | com.jayway.maven.plugins.android.generation2 89 | android-maven-plugin 90 | 91 | 92 | 93 | maven-compiler-plugin 94 | 95 | 96 | org.codehaus.mojo 97 | build-helper-maven-plugin 98 | 99 | 100 | add-source 101 | generate-sources 102 | 103 | add-source 104 | 105 | 106 | 107 | ${project.build.directory}/generated-sources/annotations/ 108 | 109 | 110 | 111 | 112 | 113 | 114 | maven-compiler-plugin 115 | 116 | ${java.version} 117 | ${java.version} 118 | 119 | org.boundbox.processor.BoundBoxProcessor 120 | 121 | 122 | 123 | 124 | maven-pmd-plugin 125 | 126 | true 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | emma 136 | 137 | 138 | emma 139 | emma 140 | 141 | 142 | 143 | 144 | 145 | com.jayway.maven.plugins.android.generation2 146 | android-maven-plugin 147 | 148 | 149 | true 150 | true 151 | 152 | 153 | true 154 | 155 | 156 | pull-coverage 157 | post-integration-test 158 | 159 | pull 160 | 161 | 162 | /data/data/com.octo.android.sample/files/coverage.ec 163 | ${project.basedir}/../android-sample/target/emma/coverage.ec 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | spoon 173 | 174 | 175 | 176 | com.jayway.maven.plugins.android.generation2 177 | android-maven-plugin 178 | true 179 | 180 | true 181 | 182 | 183 | 184 | 185 | com.squareup.spoon 186 | spoon-maven-plugin 187 | ${spoon.version} 188 | 189 | Spoon Sample App 190 | true 191 | 192 | 193 | 194 | integration-test 195 | 196 | run 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | jacoco 206 | 207 | 208 | 209 | com.jayway.maven.plugins.android.generation2 210 | android-maven-plugin 211 | 212 | 213 | 214 | true 215 | 216 | 217 | true 218 | true 219 | 220 | 221 | 222 | 223 | pull-coverage 224 | post-integration-test 225 | 226 | pull 227 | 228 | 229 | /data/data/com.octo.android.sample/files/coverage.ec 230 | ${project.basedir}/../android-sample/target/jacoco-it.exec 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | -------------------------------------------------------------------------------- /android-sample-tests/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | -------------------------------------------------------------------------------- /android-sample-tests/res/drawable-hdpi/ic_launcher_robospice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-tests/res/drawable-hdpi/ic_launcher_robospice.png -------------------------------------------------------------------------------- /android-sample-tests/res/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-tests/res/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /android-sample-tests/res/drawable-mdpi/ic_launcher_robospice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-tests/res/drawable-mdpi/ic_launcher_robospice.png -------------------------------------------------------------------------------- /android-sample-tests/res/drawable-xhdpi/ic_launcher_robospice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-tests/res/drawable-xhdpi/ic_launcher_robospice.png -------------------------------------------------------------------------------- /android-sample-tests/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 19 | 20 | 25 | 26 | 32 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /android-sample-tests/res/raw/binary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-tests/res/raw/binary.png -------------------------------------------------------------------------------- /android-sample-tests/res/raw/lorem_ipsum.txt: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. 2 | Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. 3 | Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 4 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 5 | Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. 6 | At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. 7 | Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. -------------------------------------------------------------------------------- /android-sample-tests/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello RoboSpice! 4 | RoboSpice sample 5 | Text: 6 | Json: 7 | Xml: 8 | Image: 9 | 10 | -------------------------------------------------------------------------------- /android-sample-tests/src/main/java/com/octo/android/sample/test/DummyComputerTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.test; 2 | 3 | public class DummyComputerTest { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /android-sample-tests/src/main/java/com/octo/android/sample/test/HelloAndroidActivityBoundBoxTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.test; 2 | 3 | import org.boundbox.BoundBox; 4 | 5 | import android.support.v4.app.FragmentActivity; 6 | import android.test.ActivityInstrumentationTestCase2; 7 | import android.test.UiThreadTest; 8 | 9 | import com.octo.android.sample.ui.BoundBoxOfHelloAndroidActivity; 10 | import com.octo.android.sample.ui.HelloAndroidActivity; 11 | 12 | public class HelloAndroidActivityBoundBoxTest extends ActivityInstrumentationTestCase2 { 13 | 14 | @BoundBox(boundClass=HelloAndroidActivity.class, maxSuperClass=FragmentActivity.class) 15 | private BoundBoxOfHelloAndroidActivity boundBoxOfHelloAndroidActivity; 16 | 17 | public HelloAndroidActivityBoundBoxTest() { 18 | super(HelloAndroidActivity.class); 19 | } 20 | 21 | @Override 22 | public void setUp() throws Exception { 23 | boundBoxOfHelloAndroidActivity = new BoundBoxOfHelloAndroidActivity(getActivity()); 24 | } 25 | 26 | @UiThreadTest 27 | public void testCompute() throws Exception { 28 | boundBoxOfHelloAndroidActivity.boundBox_getButton().performClick(); 29 | assertTrue(boundBoxOfHelloAndroidActivity.boundBox_getTextView().getText().equals("42")); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /android-sample-tests/src/main/java/com/octo/android/sample/test/HelloAndroidActivityFestAndroidTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.test; 2 | 3 | import android.test.ActivityInstrumentationTestCase2; 4 | import android.widget.TextView; 5 | 6 | import com.jayway.android.robotium.solo.Solo; 7 | import com.octo.android.sample.R; 8 | import com.octo.android.sample.ui.HelloAndroidActivity; 9 | 10 | public class HelloAndroidActivityFestAndroidTest extends ActivityInstrumentationTestCase2 { 11 | private Solo solo; 12 | private TextView textView; 13 | 14 | public HelloAndroidActivityFestAndroidTest() { 15 | super(HelloAndroidActivity.class); 16 | } 17 | 18 | @Override 19 | public void setUp() throws Exception { 20 | solo = new Solo(getInstrumentation(), getActivity()); 21 | textView = (TextView) getActivity().findViewById(R.id.textview_hello); 22 | } 23 | 24 | public void testCompute() throws Exception { 25 | solo.clickOnButton("Click !"); 26 | org.fest.assertions.api.ANDROID.assertThat(textView).containsText("42"); 27 | } 28 | 29 | @Override 30 | public void tearDown() throws Exception { 31 | solo.finishOpenedActivities(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /android-sample-tests/src/main/java/com/octo/android/sample/test/HelloAndroidActivityRobotiumTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.test; 2 | 3 | import junit.framework.Assert; 4 | import android.test.ActivityInstrumentationTestCase2; 5 | 6 | import com.jayway.android.robotium.solo.Solo; 7 | import com.octo.android.sample.ui.HelloAndroidActivity; 8 | 9 | public class HelloAndroidActivityRobotiumTest extends ActivityInstrumentationTestCase2 { 10 | private Solo solo; 11 | 12 | public HelloAndroidActivityRobotiumTest() { 13 | super(HelloAndroidActivity.class); 14 | } 15 | 16 | @Override 17 | public void setUp() throws Exception { 18 | solo = new Solo(getInstrumentation(), getActivity()); 19 | } 20 | 21 | public void testCompute() throws Exception { 22 | solo.clickOnButton("Click !"); 23 | Assert.assertTrue(solo.searchText("42")); 24 | } 25 | 26 | @Override 27 | public void tearDown() throws Exception { 28 | solo.finishOpenedActivities(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /android-sample-tests/src/main/java/com/octo/android/sample/test/HelloAndroidActivitySpoonTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.test; 2 | 3 | import android.test.ActivityInstrumentationTestCase2; 4 | import android.widget.TextView; 5 | 6 | import com.jayway.android.robotium.solo.Solo; 7 | import com.octo.android.sample.R; 8 | import com.octo.android.sample.ui.HelloAndroidActivity; 9 | import com.squareup.spoon.Spoon; 10 | 11 | public class HelloAndroidActivitySpoonTest extends ActivityInstrumentationTestCase2 { 12 | private Solo solo; 13 | private TextView textView; 14 | 15 | public HelloAndroidActivitySpoonTest() { 16 | super(HelloAndroidActivity.class); 17 | } 18 | 19 | @Override 20 | public void setUp() throws Exception { 21 | solo = new Solo(getInstrumentation(), getActivity()); 22 | textView = (TextView) getActivity().findViewById(R.id.textview_hello); 23 | } 24 | 25 | public void testCompute() throws Exception { 26 | // given 27 | Spoon.screenshot(getActivity(), "initial_state"); 28 | 29 | // when 30 | solo.clickOnButton("Click !"); 31 | 32 | // then 33 | Spoon.screenshot(getActivity(), "button_clicked"); 34 | assertEquals("42", textView.getText().toString()); 35 | } 36 | 37 | @Override 38 | public void tearDown() throws Exception { 39 | solo.finishOpenedActivities(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /android-sample-tests/src/main/java/com/octo/android/sample/test/HelloAndroidActivityTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.test; 2 | 3 | import org.easymock.EasyMock; 4 | import org.mockito.Mockito; 5 | 6 | import android.test.ActivityInstrumentationTestCase2; 7 | import android.test.UiThreadTest; 8 | import android.widget.Button; 9 | import android.widget.TextView; 10 | 11 | import com.octo.android.sample.R; 12 | import com.octo.android.sample.model.Computer; 13 | import com.octo.android.sample.model.DummyComputer; 14 | import com.octo.android.sample.ui.HelloAndroidActivity; 15 | 16 | public class HelloAndroidActivityTest extends ActivityInstrumentationTestCase2 { 17 | 18 | public HelloAndroidActivityTest() { 19 | super(HelloAndroidActivity.class); 20 | } 21 | 22 | public void testActivity_not_null() { 23 | assertNotNull(getActivity()); 24 | } 25 | 26 | @UiThreadTest 27 | public void testActivity_shouldUseCustomComputerUsingEasyMock() throws Exception { 28 | final int EXPECTED_RESULT = 1; 29 | // given 30 | HelloAndroidActivity activityUnderTest = getActivity(); 31 | Computer mockComputer = EasyMock.createMock(DummyComputer.class); 32 | EasyMock.expect(mockComputer.getResult()).andReturn(EXPECTED_RESULT); 33 | activityUnderTest.setComputer(mockComputer); 34 | EasyMock.replay(mockComputer); 35 | 36 | // when 37 | Button button = (Button) activityUnderTest.findViewById(R.id.button_main); 38 | button.performClick(); 39 | 40 | // then 41 | EasyMock.verify(mockComputer); 42 | TextView textViewHello = (TextView) activityUnderTest.findViewById(R.id.textview_hello); 43 | String textViewHelloString = textViewHello.getText().toString(); 44 | assertEquals(textViewHelloString, String.valueOf(EXPECTED_RESULT)); 45 | } 46 | 47 | @UiThreadTest 48 | public void testActivity_shouldUseCustomComputerUsingMockito() throws Exception { 49 | final int EXPECTED_RESULT = 1; 50 | // given 51 | HelloAndroidActivity activityUnderTest = getActivity(); 52 | 53 | Computer mockComputer = Mockito.mock(Computer.class); 54 | Mockito.when(mockComputer.getResult()).thenReturn(EXPECTED_RESULT); 55 | activityUnderTest.setComputer(mockComputer); 56 | 57 | // when 58 | Button button = (Button) activityUnderTest.findViewById(R.id.button_main); 59 | button.performClick(); 60 | 61 | // then 62 | Mockito.verify(mockComputer, Mockito.times(1)).getResult(); 63 | TextView textViewHello = (TextView) activityUnderTest.findViewById(R.id.textview_hello); 64 | String textViewHelloString = textViewHello.getText().toString(); 65 | assertEquals(textViewHelloString, String.valueOf(EXPECTED_RESULT)); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /android-sample-tests/src/test/resources/emulator-5554/com.octo.android.sample.test.HelloAndroidActivitySpoonTest/testCompute/1365867131614_initial_state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample-tests/src/test/resources/emulator-5554/com.octo.android.sample.test.HelloAndroidActivitySpoonTest/testCompute/1365867131614_initial_state.png -------------------------------------------------------------------------------- /android-sample-ui-tests/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | 51 | 52 | 56 | 57 | 69 | 70 | 71 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /android-sample-ui-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.octo.android 8 | android-sample-parent 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | android-sample-ui-tests 13 | jar 14 | android-sample-ui-tests 15 | 16 | 17 | true 18 | 19 | 20 | 21 | 22 | android 23 | android 24 | provided 25 | 26 | 27 | android.test.uiautomator 28 | uiautomator 29 | provided 30 | 31 | 32 | junit 33 | junit 34 | provided 35 | 36 | 37 | com.github.rtyley 38 | android-screenshot-celebrity 39 | 40 | 41 | 42 | 43 | ${test.directory} 44 | 45 | 46 | com.jayway.maven.plugins.android.generation2 47 | android-maven-plugin 48 | 49 | 50 | true 51 | 52 | 53 | ${project.build.directory}/${project.artifactId}-${project.version}.jar 54 | /data/local/tmp/ 55 | 56 | 57 | /sdcard/uiautomator-screenshots/ 58 | ${project.build.directory}/screenshots 59 | 60 | false 61 | 62 | 63 | 64 | true 65 | 66 | 67 | true 68 | 69 | 70 | false 71 | 72 | com.octo.android.sample.uitest.UIAutomatorSampleTest#testSettingsApp 73 | com.octo.android.sample.uitest.UIAutomatorSampleTest#testCalculatorApp 74 | 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | install-jar-to-device 82 | install 83 | 84 | push 85 | 86 | 87 | 88 | dex-classes 89 | prepare-package 90 | 91 | dex 92 | 93 | 94 | 95 | ui-test 96 | install 97 | 98 | uiautomator 99 | 100 | 101 | 102 | get-screenshots-from-device 103 | install 104 | 105 | pull 106 | 107 | 108 | 109 | 110 | 111 | 112 | maven-compiler-plugin 113 | 114 | 115 | 116 | maven-jar-plugin 117 | 118 | ${project.build.directory}/ 119 | 120 | classes.dex 121 | 122 | 123 | 124 | 125 | 126 | 127 | org.apache.maven.plugins 128 | maven-checkstyle-plugin 129 | 130 | 131 | org.codehaus.mojo 132 | findbugs-maven-plugin 133 | 134 | 135 | org.apache.maven.plugins 136 | maven-pmd-plugin 137 | 138 | 139 | 140 | 141 | 142 | 143 | spoon 144 | 145 | 146 | true 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /android-sample-ui-tests/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | -------------------------------------------------------------------------------- /android-sample-ui-tests/src/main/java/com/octo/android/sample/uitest/UIAutomatorSampleTest.java: -------------------------------------------------------------------------------- 1 | package com.octo.android.sample.uitest; 2 | 3 | import android.test.FlakyTest; 4 | import android.test.suitebuilder.annotation.LargeTest; 5 | import android.view.KeyEvent; 6 | 7 | import com.android.uiautomator.core.UiObject; 8 | import com.android.uiautomator.core.UiObjectNotFoundException; 9 | import com.android.uiautomator.core.UiScrollable; 10 | import com.android.uiautomator.core.UiSelector; 11 | import com.android.uiautomator.testrunner.UiAutomatorTestCase; 12 | import com.github.rtyley.android.screenshot.celebrity.Screenshots; 13 | 14 | /** 15 | * A working example of a ui automator test. 16 | * @author SNI 17 | */ 18 | public class UIAutomatorSampleTest extends UiAutomatorTestCase { 19 | 20 | private static final int TIMEOUT_DURING_APP_SEARCH = 10000; 21 | private static final int TEST_TOLERANCE = 3; 22 | private static final int MAX_SEARCH_SWIPES_IN_APP_MENU = 15; 23 | private static final long CALCULATOR_UPDATE_TIMEOUT = 500; 24 | 25 | private String currentTestName; 26 | private int currentScreenshotIndex; 27 | 28 | private void takeScreenshot(String name) { 29 | getUiDevice().waitForIdle(); 30 | Screenshots.poseForScreenshotNamed(currentTestName + "_" + currentScreenshotIndex++ + "_" 31 | + name); 32 | } 33 | 34 | private void setCurrentTestName(String testName) { 35 | this.currentScreenshotIndex = 0; 36 | this.currentTestName = testName; 37 | takeScreenshot("start"); 38 | } 39 | 40 | @Override 41 | protected void setUp() throws Exception { 42 | super.setUp(); 43 | unlockEmulator(); 44 | } 45 | 46 | @Override 47 | protected void tearDown() throws Exception { 48 | takeScreenshot("end"); 49 | // Simulate a short press on the HOME button. 50 | getUiDevice().pressHome(); 51 | super.tearDown(); 52 | } 53 | 54 | @LargeTest 55 | @FlakyTest(tolerance = TEST_TOLERANCE) 56 | public void testSettingsApp() throws UiObjectNotFoundException { 57 | setCurrentTestName("testSettingsApp"); 58 | startAppOnEmulator("Settings"); 59 | 60 | takeScreenshot("open"); 61 | 62 | // Validate that the package name is the expected one 63 | UiObject settingsValidation = new UiObject( 64 | new UiSelector().packageName("com.android.settings")); 65 | assertTrue("Unable to detect Settings", settingsValidation.exists()); 66 | } 67 | 68 | @LargeTest 69 | @FlakyTest(tolerance = TEST_TOLERANCE) 70 | public void testCalculatorApp() throws UiObjectNotFoundException { 71 | setCurrentTestName("testCalculatorApp"); 72 | 73 | startAppOnEmulator("Calculator"); 74 | 75 | takeScreenshot("open"); 76 | 77 | UiObject deleteButton; 78 | 79 | deleteButton = new UiObject(new UiSelector().text("DELETE")); 80 | deleteButton.waitForExists(CALCULATOR_UPDATE_TIMEOUT); 81 | if (!deleteButton.exists()) { 82 | deleteButton = new UiObject(new UiSelector().text("CLR")); 83 | } 84 | deleteButton.waitForExists(CALCULATOR_UPDATE_TIMEOUT); 85 | deleteButton.click(); 86 | 87 | takeScreenshot("after_clear"); 88 | 89 | new UiObject(new UiSelector().text("7")).click(); 90 | takeScreenshot("after_7"); 91 | new UiObject(new UiSelector().text("+")).click(); 92 | takeScreenshot("after_plus"); 93 | new UiObject(new UiSelector().text("5")).click(); 94 | takeScreenshot("after_5"); 95 | new UiObject(new UiSelector().text("=")).click(); 96 | takeScreenshot("after_equal"); 97 | assertTrue(new UiObject(new UiSelector().text("12")) 98 | .waitForExists(CALCULATOR_UPDATE_TIMEOUT)); 99 | } 100 | 101 | private void startAppOnEmulator(String appName) throws UiObjectNotFoundException { 102 | // Simulate a short press on the HOME button. 103 | getUiDevice().pressHome(); 104 | 105 | new UiObject(new UiSelector().description("Apps")); 106 | 107 | // We?re now in the home screen. Next, we want to simulate 108 | // a user bringing up the All Apps screen. 109 | // If you use the uiautomatorviewer tool to capture a snapshot 110 | // of the Home screen, notice that the All Apps button?s 111 | // content-description property has the value ?Apps?. We can 112 | // use this property to create a UiSelector to find the button. 113 | UiObject allAppsButton = new UiObject(new UiSelector().description("Apps")); 114 | 115 | // Simulate a click to bring up the All Apps screen. 116 | allAppsButton.clickAndWaitForNewWindow(); 117 | 118 | // In the All Apps screen, the Settings app is located in 119 | // the Apps tab. To simulate the user bringing up the Apps tab, 120 | // we create a UiSelector to find a tab with the text 121 | // label ?Apps?. 122 | UiObject appsTab = new UiObject(new UiSelector().text("Apps")); 123 | 124 | // Simulate a click to enter the Apps tab. 125 | appsTab.click(); 126 | 127 | // Next, in the apps tabs, we can simulate a user swiping until 128 | // they come to the Settings app icon. Since the container view 129 | // is scrollable, we can use a UiScrollable object. 130 | UiScrollable appViews = new UiScrollable(new UiSelector().scrollable(true)); 131 | 132 | // Set the swiping mode to horizontal (the default is vertical) 133 | appViews.setAsHorizontalList(); 134 | appViews.setMaxSearchSwipes(MAX_SEARCH_SWIPES_IN_APP_MENU); 135 | 136 | // Create a UiSelector to find the Settings app and simulate 137 | // a user click to launch the app. 138 | UiObject settingsApp = appViews.getChildByText( 139 | new UiSelector().className(android.widget.TextView.class.getName()), appName); 140 | settingsApp.waitForExists(TIMEOUT_DURING_APP_SEARCH); 141 | settingsApp.clickAndWaitForNewWindow(); 142 | } 143 | 144 | private void unlockEmulator() { 145 | getUiDevice().pressKeyCode(KeyEvent.KEYCODE_SOFT_LEFT); 146 | getUiDevice().pressKeyCode(KeyEvent.KEYCODE_SOFT_RIGHT); 147 | getUiDevice().pressKeyCode(KeyEvent.KEYCODE_MENU); 148 | getUiDevice().pressKeyCode(KeyEvent.KEYCODE_MENU); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /android-sample/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | -------------------------------------------------------------------------------- /android-sample/config/quality/classycle/dependencyDefinitionFile: -------------------------------------------------------------------------------- 1 | show allResults 2 | 3 | ###define packages / groups of packages of interest 4 | 5 | ## layers 6 | [ui] = com.octo.android.sample.ui.* 7 | [test] = com.octo.android.sample.test.* 8 | [other] = com.octo.android.sample.* excluding [ui] [test] 9 | 10 | ###check layers integrity 11 | check [other] independentOf [ui] 12 | -------------------------------------------------------------------------------- /android-sample/findbugs-filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android-sample/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android-sample/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.octo.android 8 | android-sample-parent 9 | 0.0.1-SNAPSHOT 10 | 11 | 12 | android-sample 13 | apk 14 | android-sample 15 | 16 | 17 | 4.8.2 18 | 19 | 20 | 21 | 22 | android 23 | android 24 | provided 25 | 26 | 27 | android.support 28 | compatibility-v4 29 | 30 | 31 | 32 | 33 | joda-time 34 | joda-time 35 | 36 | 37 | 38 | 39 | ${test.directory} 40 | 41 | 42 | com.jayway.maven.plugins.android.generation2 43 | android-maven-plugin 44 | 45 | 46 | 47 | maven-compiler-plugin 48 | 49 | 50 | 51 | 52 | org.apache.maven.plugins 53 | maven-checkstyle-plugin 54 | 55 | 56 | org.codehaus.mojo 57 | findbugs-maven-plugin 58 | 59 | 60 | org.apache.maven.plugins 61 | maven-pmd-plugin 62 | 63 | 64 | 65 | 66 | 67 | 68 | default 69 | 70 | true 71 | 72 | 73 | src/test/java 74 | 75 | 76 | 77 | emma 78 | 79 | 80 | true 81 | 82 | 83 | 84 | 85 | com.jayway.maven.plugins.android.generation2 86 | android-maven-plugin 87 | 88 | 89 | true 90 | ${project.basedir}/target/classes/ 91 | ${project.basedir}/target/emma/coverage.em 92 | 93 | 94 | 95 | true 96 | 97 | 98 | true 99 | 100 | 101 | 102 | 103 | 104 | emma 105 | emma 106 | ${emma.version} 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | cobertura 115 | 116 | src/test/java 117 | 118 | 119 | 120 | 121 | org.codehaus.mojo 122 | cobertura-maven-plugin 123 | 124 | xml 125 | 126 | 127 | 128 | 129 | clean 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | uiautomator 139 | 140 | 141 | true 142 | 143 | 144 | 145 | 146 | spoon 147 | 148 | 149 | true 150 | 151 | 152 | 153 | jacoco 154 | 155 | src/test/java 156 | 157 | 158 | 159 | org.jacoco 160 | org.jacoco.agent 161 | runtime 162 | compile 163 | 164 | 165 | 166 | 167 | 168 | org.jacoco 169 | jacoco-maven-plugin 170 | 171 | 172 | instrument-classes 173 | 174 | instrument 175 | 176 | 177 | 178 | *test* 179 | */test/* 180 | 181 | 182 | 183 | 184 | restore-instrumented-classes 185 | package 186 | 187 | restore-instrumented-classes 188 | 189 | 190 | 191 | 192 | 193 | com.jayway.maven.plugins.android.generation2 194 | android-maven-plugin 195 | 196 | 197 | true 198 | true 199 | 200 | 201 | true 202 | 203 | 204 | 205 | 206 | 207 | monkey 208 | 209 | 210 | 211 | com.jayway.maven.plugins.android.generation2 212 | android-maven-plugin 213 | 214 | 215 | ${android.sdk.version} 216 | 217 | 218 | false 219 | 220 | com.octo.android.sample 221 | 222 | 1000 223 | true 224 | true 225 | 226 | true 227 | 228 | 229 | 230 | install-app 231 | install 232 | 233 | deploy 234 | 235 | 236 | 237 | run-monkey-exerciser 238 | install 239 | 240 | monkey 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | cycle 250 | 251 | 252 | 253 | org.pitest 254 | classycle 255 | 0.1 256 | 257 | ${project.basedir}/config/quality/classycle/dependencyDefinitionFile 258 | 259 | com.octo.android.sample.* 260 | 261 | 262 | 263 | 264 | classycle-check 265 | 266 | check 267 | 268 | compile 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | monkeyrunner 277 | 278 | 279 | 280 | com.jayway.maven.plugins.android.generation2 281 | android-maven-plugin 282 | 283 | 284 | true 285 | 286 | 287 | false 288 | true 289 | true 290 | 291 | 292 | src/test/monkeyrunner/example-test.py 293 | 294 | 295 | src/test/monkeyrunner/example-test2.py 296 | 297 | 298 | 299 | 300 | 301 | 302 | install-app 303 | install 304 | 305 | deploy 306 | 307 | 308 | 309 | run-monkey-runner 310 | install 311 | 312 | monkeyrunner 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | -------------------------------------------------------------------------------- /android-sample/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | 16 | -------------------------------------------------------------------------------- /android-sample/res/drawable-hdpi/ic_launcher_robospice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample/res/drawable-hdpi/ic_launcher_robospice.png -------------------------------------------------------------------------------- /android-sample/res/drawable-hdpi/ic_warning_for_lint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample/res/drawable-hdpi/ic_warning_for_lint.png -------------------------------------------------------------------------------- /android-sample/res/drawable-mdpi/ic_launcher_robospice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample/res/drawable-mdpi/ic_launcher_robospice.png -------------------------------------------------------------------------------- /android-sample/res/drawable-xhdpi/ic_launcher_robospice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanenicolas/Quality-Tools-for-Android/1ec3bada6ae37a254db8ef1b0d8db2e10275056f/android-sample/res/drawable-xhdpi/ic_launcher_robospice.png -------------------------------------------------------------------------------- /android-sample/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |