Emulator Integrated Tests

You can use the runner to adjust emulator settings like battery life, or to synchronize actions between emulators, like sending an SMS from one emulator and checking that it had been received on the other emulator.

Run the Emulator for a Test

To have the test runner start emulator, make sure you've built the emulator. Then run the following out of the B2G directory:

./test.sh [/path/to/test/directory/or/file]

Talk to the Emulator

Once you have an emulator running, you can check its status or manipulate its battery using the supported emulator functions. As an example, check out the webAPI Battery test example.

Right now, we have support for controlling the emulator's battery by using android's emulator console. If you'd like to use other functions from the emulator console, please file a bug with us and we'll make it happen!

Manage Multiple Emulators

So that handles the case of interacting with a single emulator, but what about communication across emulators? Well, you can spawn a new emulator process in your tests! By using the get_new_emulator call, Marionette will spin up another emulator instance and return and you're ready to go. This call will create the emulator and return an Marionette object that you can use to communicate with it.

Now that you know the basics, have a working example! Here's how you can spin up a secondary emulator, give it a call from an emulator, and then verify it actually got the call from the recipient emulator. Notice how we use the "sender" and "receiver" Marionette objects to send commands to each respective emulator.


NOTE: Please focus on the structure of the test, and follow along with the comments. You don't need to understand all the execute_script code.

from marionette_test import *


class MultiEmulatorDialTest(MarionetteTestCase):
    """A simple test which verifies the ability of one emulator to dial
       another and to detect an incoming call.
    """

    def test_dial_between_emulators(self):
        # All tests run on an emulator have an instance of Marionette connected to that
        # emulator available as 'self.marionette'.  We'll use this instance as
        # the receiver of the call we're attempting to make.
        receiver = self.marionette
        
        # Create a new emulator to be the sender; after this call succeeds there will
        # be two emulators running concurrently.
        sender = self.get_new_emulator()
        
        # Setup the event listener on the receiver:
        
        # We need to execute the script in chrome to get around the url restrictions
        # for the mozTelephony object, so set our execution context to "chrome";
        # by default, we're in content space.
        receiver.set_context("chrome")
        
        # Execute the script to set up the listener.  This listener just sets
        # window.wrappedJSObject.incoming to the number of an incoming call,
        # when the "incoming" event on mozTelephony is fired.
        self.assertTrue(receiver.execute_script("""
return window.navigator.mozTelephony != undefined && window.navigator.mozTelephony != null;
"""))
        receiver.execute_script("""
window.wrappedJSObject.incoming = "none";
window.navigator.mozTelephony.addEventListener("incoming", function(e) {
    window.wrappedJSObject.incoming = e.call.number;
});
""")

        # Set our phone numbers
        toPhoneNumber = "1555521%d" % receiver.emulator.port
        fromPhoneNumber = "1555521%d" % sender.emulator.port
        
        # Now, we dial the receiver from our sender:
        sender.set_context("chrome")
        sender.execute_script("""
window.navigator.mozTelephony.dial("%s");
""" % toPhoneNumber)

        # Now back to the receiver, let's see if we get the call!
        
        # On the receiver, wait up to 30s for an incoming call to be 
        # detected.
        receiver.set_script_timeout(30000)
        
        # Check if window.wrappedJSObject.incoming has been set by the
        # event listener we created above.  This repeatedly performs that
        # check, and returns with the value of that variable when it
        # is set, or generates a timeout exception if it doesn't return
        # within 30s.
        received = receiver.execute_async_script("""
        let start = new Date().valueOf();
        function check_incoming() {
            if (window.wrappedJSObject.incoming != "none") {
                marionetteScriptFinished(window.wrappedJSObject.incoming);
            }
            else {
                setTimeout(check_incoming, 500);
            }
        }
        setTimeout(check_incoming, 0);
    """)
    
        # Verify the phone number of the incoming call.
        self.assertEqual(received, fromPhoneNumber)

 

Document Tags and Contributors

Contributors to this page: jgriffin, philikon, mdas, fscholz, Sheppy
Last updated by: fscholz,