how to run external program inside a monkeyrunner code? - android

I have a monkeyrunner code (file extension is .py) which is working fine. I am using CentOS. Now, I need to run a an external program and I need to insert that code in the monkeyrunner code. how do I do it? What do I need to import and what is the command?

You should use the subprocess module.

import subprocess
# Your code ...
# Call the external program/ script:
subprocess.call('your script', shell = True)

Related

Running Py4A script from external SD card?

I need to run the Python script from external SD card, which in the target device is mounted as /mnt/sdcard/_ExternalSD.
I've succeeded to accomplish that in a quick&dirty way by preparing the "proxy" script ExtSDRun.py in the standard SL4A scripts directory, which in case of my target device is /mnt/sdcard/sl4a/scripts
import android
droid = android.Android()
import os
import sys
# Add directory with the scripts to the Python path
sys.path.append("/mnt/sdcard/_ExternalSD/scripts")
# Start the script located in the external SD card
# in the script_to_run.py file
import script_to_run
# You can also do:
# from script_to_run import *
Is there any better and more elegant way to achieve this goal?
I'm pretty sure you can run a script from an external SD card. Try this. It's a simple Python function that launches any script SL4A has an installed interpreter for, given an arbitrary path to the script. I don't have an external card to test it on, but see no reason for it to fail.
Short answer: you can't. A better way to do what you're doing is to put a main function is script_to_run. i.e. if script_to_run contained this:
import sys
sys.stdout.write('Hi!\n') #Technically I should use print, but I'm trying
#to make the program longer.
you'd do this:
import sys
def main():
sys.stdout.write('Hi!\n')
Then, when you import it, use:
import script_to_run
script_to_run.main() #This is what runs the script
Also, see https://stackoverflow.com/a/4463726/2097780. I wouldn't recommend doing that, but it might be an option if you can't call main the other way.
Good luck!

Can not simultaneously run monkeyrunner scripts (e.g. two monkeyrunner process) on multi device

test.py script content:
import ....
device = MonkeyRunner.waitForConnection(10,sys.argv[1])
device.startActivity(component='package/activity')
'''
some monkeyrunner events
'''
I have two device , labled device1-id and device2-id
run the monkeyrunner test.py device1-id &
run the monkeyrunner test.py device2-id &
I found some events in device2-id were sent to device1-id. I don't know why ?
I noticed some tutorials , they said , if run monkeyrunner on more devices, could write the script like below:
device1 = MonkeyRunner.waitForConnection(10,device1-id)
device2 = MonkeyRunner.waitForConnection(10,device2-id)
device1.actions
device2.actions
but this wasn't what I need. Anybody know why the monkeyrunner behaves this ?
What I need is that , I have one script , would run the same script on multi device simultaneously .
You have to specify the monkey port so you may want to use a command line argument like so
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
import sys
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection(timeOut,"emulator-"+ sys.argv[1])
MONKEYRunner Actions . . . .
NOTE: sys.arv[0] is always the test file
Call by entering the following on the command line:
monkeyrunner test.py PortNumber
I believe that Monkeyrunner is not thread safe.
To test this, create 2 scripts, hardcoding the deviceId into each.
Start each script:
In windows, use the "start script1" and then "start script2"
In Unix use "script1 &; script2 &"
Notice that script1 fails with errors after it looks like it started working just fine. and that SCript2 also fails to do what it was intended to do because it gets commands from both windows.

MonkeyRunner with Robotframework

I am planning to use monkeyrunner scripts to do automated test cases and I want to use robotframework(I am not interested in robotium).
I saw an excellent tutorial for automating sikuli scripts with robotframework at
http://blog.mykhailo.com/2011/02/how-to-sikuli-and-robot-framework.html
Is there any way to do similar thing, with robotframework and monkeyrunner?
Here is my sample monkeyrunner script,this executes correctly when invoked with monkeyrunner.
from __future__ import with_statement
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
def testCase() :
device = MonkeyRunner.waitForConnection()
result2 = device.takeSnapshot()
# Writes the screenshot to a file
result2.writeToFile("scr.png","png")
def my_keyword():
print 'Hello, world!'
if __name__ == '__main__':
testCase()
I want to invoke the same with roboframework. and I am trying the following. I am not sure whether the following invocation is correct or not, I simply copied from sikuli automation example and modified it.
monkey_jar=/home/user/android-sdks/tools/lib/monkeyrunner.jar
guava_jar=/home/user/android-sdks/tools/lib/guavalib.jar
java -cp "robotframework-2.7.4.jar:$monkey_jar:$guava_jar" -Dpython.path="/home/user/android-sdks/tools/lib/" \
org.robotframework.RobotFramework --pythonpath=./ --outputdir=results --loglevel=TRACE $1
When I do this, I am getting the following error.
Importing test library 'MyLibrary' failed: NoClassDefFoundError: Could not initialize class com.android.monkeyrunner.MonkeyDevice
java.lang.NoClassDefFoundError:
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at MyLibrary$py.f$0(/home/user/automation/DemoScripts/MyLibrary.py:9)
at MyLibrary$py.call_function(/home/user/automation/DemoScripts/MyLibrary.py)
at robot.utils.importer$py._import$13(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/importer.py:154)
at robot.utils.importer$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/importer.py)
at robot.utils.importer$py.import_$28(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/importer.py:241)
at robot.utils.importer$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/importer.py)
at robot.utils.importer$py._import_class_or_module$4(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/importer.py:67)
at robot.utils.importer$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/importer.py)
at robot.utils.importer$py.import_class_or_module$3(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/importer.py:64)
at robot.utils.importer$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/importer.py)
at robot.run$py.main$3(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/run.py:367)
at robot.run$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/run.py)
at robot.utils.application$py._execute$10(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/application.py:87)
at robot.utils.application$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/application.py)
at robot.utils.application$py.execute_cli$5(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/application.py:45)
at robot.utils.application$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/utils/application.py)
at robot.run$py.run_cli$6(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/run.py:396)
at robot.run$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/run.py)
at robot.jarrunner$py._run$3(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/jarrunner.py:60)
at robot.jarrunner$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/jarrunner.py)
at robot.jarrunner$py.run$2(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/jarrunner.py:53)
at robot.jarrunner$py.call_function(/Users/jmalinen/Documents/workspace/robot/tmp-jar-dir/Lib/robot/jarrunner.py)
at org.robotframework.RobotFramework.run(RobotFramework.java:62)
at org.robotframework.RobotFramework.main(RobotFramework.java:37)
PYTHONPATH:
/home/user/automation/DemoScripts
/home/user/automation/DemoScripts/robotframework-2.7.4.jar/Lib/robot/libraries
/home/user/automation/DemoScripts/robotframework-2.7.4.jar/Lib
/home/user/android-sdks/tools/lib/
/home/user/automation/DemoScripts/Lib
__classpath__
__pyclasspath__/
.
/home/user/automation/DemoScripts
CLASSPATH:
robotframework-2.7.4.jar
/home/user/android-sdks/tools/lib/monkeyrunner.jar
/home/user/android-sdks/tools/lib/guavalib.jar
==============================================================================
I believe that executing monkeyrunner test cases along with roboframework is quite possible.
Any inputs?
Well, after trying for few days, I found that it is possible to use MonkeyRunner scripts with Robotframework.
In short, you can use the folllowing to launch robotframework along with monkeyrunner.
export cpath=$(echo libs/*.jar | tr ' ' ':')
java -Dpython.path=$cpath -jar robotframework-2.7.4.jar robo-tests.txt
But only problem was, monkeyrunner's main was not called, thus not initializing the ChimpChat object, which results in a null pointer exception. I fixed that in MonkeyRunner.java, and created a new monkeyrunner.jar. With this, I am able to run monkeyrunner scripts from roboframework. I will try to create a step by step tutorial and post it.
#jollychang do this way
add this to file MonkeyRunner.java
if(chimpchat == null) {
Map<String, String> chimp_options = new TreeMap<String, String>();
chimp_options.put("backend", "adb");
chimpchat = ChimpChat.getInstance(chimp_options);
MonkeyRunner.setChimpChat(chimpchat);
}
before:
JythonUtils.convertDocAnnotationsForClass(MonkeyRunner.class, dict);
then make a new monkeyrunner.jar;
need some others jar like this:
use the new monkeyrunner.jar instead of the old one.
at last: run robot with the command:
in my computer use this:
java -cp /Users/komejun/Documents/devtool/android/android-sdk-mac_x86/tools/lib/chimpchat.jar:/Users/komejun/Documents/devtool/android/android-sdk-mac_x86/tools/lib/ddmlib.jar:/Users/komejun/Documents/devtool/android/android-sdk-mac_x86/tools/lib/guavalib.jar:/Users/komejun/Documents/devtool/android/android-sdk-mac_x86/tools/lib/monkeyrunner.jar:/Users/komejun/Documents/devtool/android/android-sdk-mac_x86/tools/lib/sdklib.jar:/Users/komejun/Downloads/robotframework-2.7.5.jar -Dcom.android.monkeyrunner.bindir="/Users/komejun/Documents/devtool/android/android-sdk-mac_x86/tools" -Djava.library.path="/Users/komejun/Documents/devtool/android/android-sdk-mac_x86/tools/lib" org.robotframework.RobotFramework a.txt

How to import a py file function in monkeyrunner test file

I want to create test cases for my Android application in Monkeyrunner.
I am thinking to create a sub tests case file to do before actual test case. like a install , uninstall functions in a separate py file. How can i call these install/uninstall apk or any other function in my monkeyrunner test case?
I have a successful experiment of calling a function from other imported py file in my py file in PYTHON. but same function cannot called while running through monkeyrunner.
import new
print new.foo()
this is working while running through python but not working in monkeyrunner.
Any solution?
monkeyrunner (jython) and python should import modules exactly the same way, the only difference might be the content of the module search path.
To verify it try:
import sys
print sys.path
in both python and monkeyrunner and see if there are any differences.
If you want to include some path, do
sys.path.append("/path/to/my/new/module")
import new
print new.foo()
and should work.

Monkey Runner import giving error

i created an empty file an named it something.py, and then i just copied the lines of code from the android developer website. However, if i try to run it, i get an
ImportError: No module named com.android.monkeyrunner
Is there something i am missing? There doesn't seem to be anything at the android developer website that addresses this issue. Here are the lines of code
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
device = MonkeyRunner.waitForConnection()
device.installPackage('myproject/bin/Stamp_Client.apk')
package = 'com.example.main'
activity = 'com.example.Stamp_Client'
runComponent = package + '/' + activity
device.startActivity(component=runComponent)
device.press('KEYCODE_BUTTON_SELECT','DOWN_AND_UP')
device.press('KEYCODE_U','DOWN_AND_UP')
device.press('KEYCODE_S','DOWN_AND_UP')
device.press('KEYCODE_E','DOWN_AND_UP')
device.press('KEYCODE_R','DOWN_AND_UP')
device.press('KEYCODE_ENTER','DOWN_AND_UP')
device.press('KEYCODE_P','DOWN_AND_UP')
device.press('KEYCODE_A','DOWN_AND_UP')
device.press('KEYCODE_S','DOWN_AND_UP')
device.press('KEYCODE_S','DOWN_AND_UP')
device.press('KEYCODE_ENTER','DOWN_AND_UP')
device.press('KEYCODE_ENTER','DOWN_AND_UP')
Make sure you run:
$ monkeyrunner yourfile.py
instead of:
$ python yourfile.py
I guess you are missing the shebang:
#! /usr/bin/env monkeyrunner
that is if you are using Linux or OSX, for Windows you probably have to create a batch file.

Categories

Resources