in Python
Python script in PC
Communicate with monkey daemon on device via adb
Control Android device
Multiple device control
Functional testing
Extensible automation
# Import monkeyrunner
from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice
# Get the android device
device = MonkeyRunner.waitForConnection()
# Install apk to device
device.installPackage('myproject/bin/MyApp.apk')
# Start a new activity
device.startActivity(component='com.myapp/.MainActivity')
# Press down/up menu key
device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)
# Take snapshot and save it to file
result = device.takeSnapshot()
result.writeToFile('myproject/shot1.png','png')
Using unittest to manage monkeyrunner tests
# Import TestCase
from unittest import TestCase
class MyTest(TestCase):
def setUp(self):
# setup code here
pass
def test_LoopLaunch(self):
# testing code here
# ......
device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)
Recording snapshot & OCR firstly.
Comparing snapshot & OCR while testing.
ONE test script for both recording and testing.
# assert current screen with recorded one
assertCheckImage(...)
# wait for recorded screen or timeout
assertWaitForScreen(...)
# assert OCR text
assertCheckString(...)
# wait for recorded OCR text
assertWaitForString(...)
def test_example(self):
# some test steps
device.press(...)
sleep(...) # sleep until phone gets response
# and then assert/recording
self.assertCheckImage(...)
# other steps like above
# ......
That’s what we have done before.
How about next ?
User input serial is likely to be method invocation chain.
def test_example(self):
# some test steps
device.shell(...) \
.startActivity(...) \
.press(...) \
.tap(...) \
.expectImage(...) \
.press(...) \
.expectImageUntilTimeout(...)
# file: package/__init__.py
__all__=["BaseClass", ...]
import impl.BaseClassImpl1 as BaseClass
# We may have other impl of BaseClass, but here we only
# export impl.BaseClassImpl1 as BaseClass.
# file: package/impl.py
__all__ = ["BaseClassImpl1", "BaseClassImpl2"]
class BaseClassImpl1(Base, AssertImpl1, DevImpl):
pass
class BaseClassImpl2(Base, AssertImpl2, DevImpl, ReportImpl):
pass
# Here AssertImpl1/AssertImpl2, DeviceImpl, ReportImpl are
# mixins. We can using mixin to add new feature to the class
# or replace old mixin with new one.
Cross module communication:
Send message cross Test, TestRunner, DataUploader, DeviceMonitor, etc.
# module a.py
from pubsub import pub
def listener1(arg1, arg2=None):
print 'received: arg1="%s" arg2="%s"' % (arg1, arg2)
pub.subscribe(listener1, 'rootTopic')
# module b.py
from pubsub import pub
pub.sendMessage('rootTopic', arg1=123, arg2={'a':'abc'})
from com.android.monkeyrunner import MonkeyRunner,MonkeyDevice
from com.android.monkeyrunner.easy import EasyMonkeyDevice
from com.android.monkeyrunner.easy import By
device = MonkeyRunner.waitForConnection()
# Use the EasyMonkey API, all methods on device are available
# in easy_device.
easy_device = EasyMonkeyDevice(device)
if not easy_device.visible(By.id('id/all_apps_button')):
raise Error('Could not find the "all apps" button')
print "Location of element:",
print easy_device.locate(By.id('id/all_apps_button'))
easy_device.touch(By.id('id/all_apps_button'), 'DOWN_AND_UP')
Upload all test data to server.
Use a spacebar or arrow keys to navigate