Category Archives: Android Testing

Monkeyrunner links & Other automation info

Some links for Monkeyrunner

From the Android site (though it took tweaking to make this work for me)

monkeyrunner | Android Developers – http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html

 

Additional Documentation from Android

Monkey Device – other program options, like reboot – http://developer.android.com/guide/developing/tools/MonkeyDevice.html
Monkey Image – Pixel and Image stuff –  http://developer.android.com/guide/developing/tools/MonkeyImage.html
Monkey Runner – has some static utility methods. – http://developer.android.com/guide/developing/tools/MonkeyRunner.html

 

Some Other UI Automation Ideas

Android UI Automation Basics – http://goravsingal.hubpages.com/hub/Android-UI-Automation-Basics

 

Python

Python/Jython Downloads – http://www.python.org/download/

Alternatives to Eclipse (which isn’t my favorite beast)

I have been using Notepad++ to write my early learning scripts (though this isn’t an IDE)

Netbeans another IDE

 

Other tools

Robotium – (I felt this needed a lot of developer support in order to me to work with it and I am not a Java person) – http://code.google.com/p/robotium/ – and it integrates with Cucumber but that requires Ruby

 

Paid tools (e.g not free)

TestDroid – http://testdroid.com/

Android Monkey Scripting Language

Monkey:  The Monkey is a program that runs on your emulator or device and generates pseudo-random streams of user events such as clicks, touches, or gestures, as well as a number of system-level events. You can use the Monkey to stress-test applications that you are developing, in a random yet repeatable manner.

The code behind Monkey – as in the source code that runs these commands:

http://www.java2s.com/Open-Source/Android/android-core/platform-development/com/android/commands/monkey/MonkeySourceScript.java.htm

The Commands:

count= number of events

speed= in ms

start data >>

DispatchPointer(long downTime,  long eventTime, int action,

float x, float y, float pressure, float size, int metaState,

float xPrecision, float yPrecision, int device, int edgeFlags)

DispatchTrackball same as DispatchPointer

DispatchKey(long downTime, long eventTime, int action, int code,

int repeat, int metaState, int device, int scancode)

DispatchFlip(boolean keyboardOpen)

DispatchPress(int keyCode)

Tap()

LaunchActivity(String pkg_name, String cl_name)

UserWait(long sleeptime)

LongPress()

Android – My test run

with some more digging and using the source code as a guide, and the log messages from logcat, I was able to create a working monkey script.  Per the Monkey source code, “tap” should work, but I haven’t tried it yet.

For my test this is what I did:

  1. I run just the emulator (without launching eclipse)
    emulator
    -wipe-data -avd target_android
    (This wipes the data so it is a clean run)
  2. I run:
    adb
    logcat
    In its own window, so I can watch the results of my actions
  3. Install my app via the apk file
    adb
    install coin-android-0.0.1-SNAPSHOT.apk“coin-android-0.0.1-SNAPSHOT.apk” was given to me by development

    If the emulator is running and everything goes fine, you get back a success

    C:\android\adb install coin-android-0.0.1-SNAPSHOT.apk
    115 KB/s (1230606 bytes in 10.406s)
    pkg: /data/local/tmp/coin-android-0.0.1-SNAPSHOT.apk
    Success
      ß apk file was installed fine

  4. If you don’t know the exact name of the app (as the emulator would see) you can launch it while watching the logcat window and you will see the name:
    There will be a lot of stuff scrolling, the key thing to look for is the process start:
    Start proc

    Next will be the name of the process and mostly your app:  com.mpowerlabs.coin.android
    And then the name of the 1st activity (the 1st thing that happens when you launch the app:
    com.mpowerlabs.coin.android/.LoginActivity
    Sample logcat output:
    I/ActivityManager(   71): Start proc com.mpowerlabs.coin.android for activity com.mpowerlabs.coin.android/.LoginActivity: pid=317 uid=10036 gids={3003}V//ContextScope.java:112(  317): 15:47:29.481 main Contexts in the main scope map after inserting com.mpowerlabs.coin.android.CoinApplication@44ee89e8: com.mpowerlabs.coin.android.CoinApplication@44ee89e8
  5. Now you know the name of the app and the first activity, you can get a list of activities from the android-manifest.xml (if development shares it with you) or by clicking on the activity and looking for it in the logs, look for keyword “activity”
  6. Now I have the basics of what I need to launch the app and go to the 1st activity and I will use DispatchPress to press the keys I want.  (My test script follows)
  7.  Once you write the script you need to put it on the device to run it (my 1st script is called login.txt)
    adb
    push login.txt /sdcard/login.txt
    This pushes login.txt to the /sdcard and uses the same name login.txt (it is a virtual SD Card since this is on the emulator)
  8. Now run the script:
    adb
    shell monkey -p com.mpowerlabs.coin.android -v -v -v -f /sdcard/login.txt 1-p is the process (app) name

    -v is verbose logging, having 3 of them will get you a bunch of details from running the script, if you have enough information and/or know the script is fine, then you can remove them

    -f is the location of my script file (same place the push command put it /sdcard/login.txt

    Sample run of my script
    First the copy
    C:\android>adb push login.txt /sdcard/login.txt
    6 KB/s (926 bytes in 0.140s)

    Now the run (Probably not perfect but works for my needs)
    C:\android>
    adb
    shell monkey -p com.mpowerlabs.coin.android -v -v -v -f /sdcard/login.txt 1
    :Monkey: seed=0 count=1:AllowPackage: com.mpowerlabs.coin.android
    :IncludeCategory: android.intent.category.LAUNCHER
    :IncludeCategory: android.intent.category.MONKEY
    // Selecting main activities from category android.intent.category.LAUNCHER
    //   – NOT USING main activity com.android.cardock.CarDockActivity (from package com.android.cardock)
    //   – NOT USING main activity com.android.camera.Camera (from package om.android.camera)
    //   – NOT USING main activity com.android.alarmclock.AlarmClock (from package com.android.alarmclock)
    //   – NOT USING main activity com.android.settings.Settings (from package com.android.settings)
    //   – NOT USING main activity com.android.spare_parts.SpareParts (from package com.android.spare_parts)
    //   – NOT USING main activity com.android.mms.ui.ConversationList (from package com.android.mms)
    //   – NOT USING main activity com.android.camera.GalleryPicker (from package com.android.gallery)
    //   – NOT USING main activity com.android.contacts.DialtactsActivity (from package com.android.contacts)
    //   – NOT USING main activity com.android.contacts.DialtactsContactsEntryActivity (from package com.android.contacts)
    //   – NOT USING main activity com.android.browser.BrowserActivity (from package com.android.browser)
    //   – NOT USING main activity com.android.music.MusicBrowserActivity (from package com.android.music)
    //   – NOT USING main activity com.android.email.activity.Welcome (from package com.android.email)
    //   – NOT USING main activity com.example.android.apis.ApiDemos (from package com.example.android.apis)
    //   – NOT USING main activity com.android.gesture.builder.GestureBuilderActivity (from package com.android.gesture.builder)
    //   – NOT USING main activity com.android.speechrecorder.SpeechRecorderActivity (from package com.android.speechrecorder)
    //   – NOT USING main activity com.android.customlocale.CustomLocaleActivity (from package com.android.customlocale)
    //   – NOT USING main activity com.android.development.Development (from package com.android.development)
    //   – NOT USING main activity com.android.calculator2.Calculator (from package com.android.calculator2)
    //   + Using main activity com.mpowerlabs.coin.android.LoginActivity (from package com.mpowerlabs.coin.android)
    //   + Using main activity com.mpowerlabs.coin.android.enroll.BusinessInfoActivity (from package com.mpowerlabs.coin.android)
    //   + Using main activity com.mpowerlabs.coin.android.enroll.EnterAddressActivity (from package com.mpowerlabs.coin.android)
    //   + Using main activity com.mpowerlabs.coin.android.enroll.ReviewFeesAndSubmitActivity (from package com.mpowerlabs.coin.android)
    //   + Using main activity com.mpowerlabs.coin.android.CalculateAmountActivity (from package com.mpowerlabs.coin.android)
    //   + Using main activity com.mpowerlabs.coin.android.SignatureActivity (from package com.mpowerlabs.coin.android)
    // Selecting main activities from category android.intent.category.MONKEY
    //   – NOT USING main activity com.android.settings.ManageApplications (from package com.android.settings)
    //   – NOT USING main activity com.android.settings.RunningServices (from package com.android.settings)
    //   – NOT USING main activity com.android.launcher2.Launcher (from package com.android.launcher)
    //   – NOT USING main activity com.android.quicksearchbox.google.GoogleSearch (from package com.android.quicksearchbox)

    Replaying 49 events with speed 1.0

    :Switch: #Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10000000;component=com.mpowerlabs.coin.android/.LoginActivity;end

    // Allowing start of Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.mpowerlabs.coin.android/.LoginActivity } in package com.mpowerlabs.coin.android
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 10    // KEYCODE_3
    :SendKey (ACTION_UP): 10    // KEYCODE_3
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 8    // KEYCODE_1
    :SendKey (ACTION_UP): 8    // KEYCODE_1
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 10    // KEYCODE_3
    :SendKey (ACTION_UP): 10    // KEYCODE_3
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    SendKey (ACTION_DOWN): 12    // KEYCODE_5
    :SendKey (ACTION_UP): 12    // KEYCODE_5
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 7    // KEYCODE_0
    :SendKey (ACTION_UP): 7    // KEYCODE_0
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 9    // KEYCODE_2
    :SendKey (ACTION_UP): 9    // KEYCODE_2
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 8    // KEYCODE_1
    :SendKey (ACTION_UP): 8    // KEYCODE_1
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 9    // KEYCODE_2
    :SendKey (ACTION_UP): 9    // KEYCODE_2
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 12    // KEYCODE_5
    :SendKey (ACTION_UP): 12    // KEYCODE_5
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 15    // KEYCODE_8
    :SendKey (ACTION_UP): 15    // KEYCODE_8
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 20    // KEYCODE_DPAD_DOWN
    :SendKey (ACTION_UP): 20    // KEYCODE_DPAD_DOWN
    Sleeping for 0 milliseconds
    Wait Event for 250 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 8    // KEYCODE_1
    :SendKey (ACTION_UP): 8    // KEYCODE_1
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 9    // KEYCODE_2
    :SendKey (ACTION_UP): 9    // KEYCODE_2
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 10    // KEYCODE_3
    :SendKey (ACTION_UP): 10    // KEYCODE_3
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 11    // KEYCODE_4
    :SendKey (ACTION_UP): 11    // KEYCODE_4
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 12    // KEYCODE_5
    :SendKey (ACTION_UP): 12    // KEYCODE_5
    Sleeping for 0 milliseconds
    Wait Event for 200 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 20    // KEYCODE_DPAD_DOWN
    :SendKey (ACTION_UP): 20    // KEYCODE_DPAD_DOWN
    Sleeping for 0 milliseconds
    Wait Event for 250 milliseconds
    Sleeping for 0 milliseconds
    :SendKey (ACTION_DOWN): 66    // KEYCODE_ENTER
    :SendKey (ACTION_UP): 66    // KEYCODE_ENTER
    // activityResuming(com.mpowerlabs.coin.android)
    Sleeping for 0 milliseconds
    Events injected: 54
    :Dropped: keys=0 pointers=0 trackballs=0 flips=0
    ## Network stats: elapsed time=6828ms (6828ms mobile, 0ms wifi, 0ms not connected)
    // Monkey finished