Loading repository data…
Loading repository data…
oloed / repository
RoboRemote is a remote control framework for Robotium. The goal of RoboRemote is to allow for more complex test scenarios by letting the automator write their tests using standard desktop Java/JUnit. All of the Robotium Solo commands are available. RoboRemote also provides some convencience classes to assist in common tasks such as interacting with list views.
RoboRemote is a remote control framework for Robotium. The goal of RoboRemote is to allow for more complex test scenarios by letting the automator write their tests using standard desktop Java/JUnit(other frameworks to be supported in the future). All of the Robotium Solo commands are available. RoboRemote also provides some convencience classes to assist in common tasks such as interacting with list views.
RoboRemote is loosely modeled after Frank for iOS.
RoboRemote consists of two components - RoboRemoteServer and RoboRemoteClient. The entire project is managed by Maven and both components are provided as artifacts.
RoboRemoteServer acts as a HTTP interface to Robotium. It accepts requests and provides responses in JSON format. The input JSON describes the class, method and method parameters for the function that is being called.
Example request
Traditional Robotium Syntax: View tView = solo.getView(android.widget.EditText.class, 0); RoboRemote map request(POST to http://<device ip>:8080/map):
RoboRemote map response
How did that work?
RoboRemote uses Java reflection along with some additional logic to turn the JSON based requests into function calls. All return values from functions are returned as a JSONArray of values. If a function results in a List or an Array then the JSONArray will contain all of the data from the functions return value.
RoboRemoteServer contains a resource file(<root>/RoboRemoteServer/res/values/types.xml) that maps parameter types to equivalent parameter types. This is used to determine if the value that was passed in through JSON(ex: Integer) can be used as an argument to a function that takes a different numerical type. If you are trying to call a function and it is not working properly then a missing mapping in this file is the likely culprit.
What do I do with the String version of the View I requested?
The textual versions of views or class names can be passed back is an argument to a function that requires a class or a view. An example will be shown in the RoboRemoteClient section of this README.
RoboRemoteClient is a java library(jar) that can be utilized in a JUnit 4.11 test project. It provides the following functionality:
RoboRemoteClient provides com.groupon.roboremote.RoboRemoteClient.Solo which maps all Solo commands that were available as of Robotium 3.1.
Example Robotium Solo request
Traditional Robotium Syntax:
RoboRemote client request(using com.groupon.roboremote.RoboRemoteClient.Solo):
RoboRemoteClient also provides a method(in com.groupon.roboremote.RoboRemoteClient.Client) to call any function in a static/non-static class. The map method is defined as map(String className, String method_name, Object … parameters). If the call is successful then it returns a JSONArray of the results. If the method only has a single return value then it will be in the first element of the JSONArray. Elements in lists/arrays are returned in the same position in the JSONArray as they would be for the normal function call.
Example function call
Traditional method call in Robotium test:
RoboRemote client request:
Note about function calls: You can call methods in static/non-static classes, but cannot call methods in already instantiated classes. In order to use already instantiated classes you will have to add hook methods in your test runner(explained in the Getting Started section of this README). The only exception to this is the Robotium Solo class. This class is pre-instantiated and can be referenced as "solo" in a map call.
You may have a neeed to retrieve content from fields in a class. This can be done using the mapField(String className, String) function instead of the map(…) function.
Example field accessor
Traditional field access in Robotium test:
RoboRemote client request:
RoboRemoteClient also allows you to call functions on the return value of a previous function via the com.groupon.roboremote.RoboRemoteClient.QueryBuilder class. You can chain together as many method calls as you would like. The drawback to this class is that you have to map Solo calls instead of using the pre-defined Solo class.
Traditional method call:
RoboRemote QueryBuilder method call:
Traditional method call with a Field:
RoboRemote QueryBuilder call:
You need two things to get started with RoboRemote.
A test runner. This is very similar to a Robotium test class except that it extends com.groupon.roboremote.roboremoteserver.RemoteTest instead of ActivityInstrumentationTestCase2. You can actually take the example below and simply change the namespace and target test class. The provided examples(described below) also contain Maven pom files to show how to compile this.
import com.groupon.roboremote.example.helloworld.HelloWorld; import com.groupon.roboremote.roboremoteserver.*; public class Runner extends RemoteTest { public Runner() throws ClassNotFoundException { super(HelloWorld.class); } public void testRCRunner() throws Exception { startServer(); } }
Tests! These are JUnit 4.10 test classes that extend com.groupon.roboremote.roboremoteclient.TestBase. Example tests are provided in the source repository. These can also be compiled with Maven and a sample pom is provided with the example.
The test executor requires a few environment variables to be set:
These can be alternatively defined if your tests have a @BeforeClass method that overrides the setUpApp() method from TestBase
Once you have these two items along with your app then you can install the app under test and the test runner to your device and then begin executing tests against an attached device/emulator using desktop JUnit either from maven or the IDE of your choice.
These are the maven dependencies you need to declare in your test runner pom:
These are the maven dependencies you need to declare in your tests pom:
You may find that you want to do more complicated function calls that make more sense to do in Android code rather than through function mapping. Fortunately this is very easy since RoboRemote can call any arbitrary function. The easiest way to do this is to add an additional class(Ex: TestHook) along side your Runner class.
Example testhook class:
Invocation of testhook function:
An example project is provided in the examples/HelloWorld directory. The directory structure is as follows:
Running "mvn clean install" from the "examples" directory will build the examples. Be sure to run "mvn clean install" from the root first to compile the latest library versions
Execute the following from your repository root:
Execute the following from examples/HelloWorld/Tests
Robotium - http://code.google.com/p/robotium/
JUnit - http://www.junit.org/
Frank - https://github.com/moredip/Frank