Mastering Scripts Recording - Advanced Features

When you write the test scripts, simple airtest APIs may not fulfill your needs. This chapter gives you an overview of advanced features of script recording.

What can I do more?
  • set own custom parameters used in scripts execution
  • add own custom functions, or replace the default ones
  • execute initialization/cleaning code, or even execute the other test scripts before, within or after script runs themselves

Airtest Launcher

Airtest implements its own class object AirtestCase by inheriting unittest.TestCase which adds all functionality required to execute the underlying Airtest scripts.

If there is a need to add own custom functions, then create your own class and inherit the AirtestCase object and add your own code into setup() and tearDown() functions.

If the settings and functionality is fixed, use the content as a launcher to initialize your custom environment before running the actual test cases.

More details about Airtest Launcher can be found here: Airtest Launcher

Following code demonstrates the custom launcher (custom_launcher.py) that adds some custom contents and runs the test code as a launcher.

from airtest.cli.runner import AirtestCase, run_script
from airtest.cli.parser import runner_parser

class CustomAirtestCase(AirtestCase):

    def setUp(self):
        print("custom setup")
        # add var/function/class/.. to globals
        # self.scope["hunter"] = "i am hunter"
        # self.scope["add"] = lambda x: x+1

        # exec setup script
        # self.exec_other_script("setup.owl")
        super(CustomAirtestCase, self).setUp()

    def tearDown(self):
        print("custom tearDown")
        # exec teardown script
        # self.exec_other_script("teardown.owl")
        super(CustomAirtestCase, self).setUp()

if __name__ == '__main__':
    ap = runner_parser()
    args = ap.parse_args()
    run_script(args, CustomAirtestCase)

Next, use the custom_launcher.py to run the test script named test.air

python custom_launcher.py test.air --device Android:///serial_num --log log_path

Using launcher with AirtestIDE

There are two ways to to run a custom script in AirtestIDE:

  1. write your Airtest code in script editor, and then press Run button
  2. implement the custom launcher based on the Airtest-Launcher introduced above, then initialize custom execution environment for the test scripts as shown below:
from airtest.cli.runner import run_script
from airtest.cli.parser import runner_parser
from airtest.core.settings import Settings as ST

# if scripts are executed in IDE, IDE will load 'AirtestCase' automatically
# if the scripts are run in the console, 'AirtestCase' must be imported manually
if not global().get("AirtestCase"):
    from airtest.cli.runner import AirtestCase

class CustomCase(AirtestCase):
    def __init__(self):
        super(CustomCase, self).__init__()

    def setUp(self):
        print("custom setup")
        super(CustomCase, self).setUp()

    def tearDown(self):
        print("custom tearDown")
        super(CustomAirtestCase, self).tearDown()

if __name__ == '__main__':
    ap = runner_parser()
    args = ap.parse_args()
    run_script(args, CustomCase)

The next step is to configure to use your own launcher in AirtestIDE:

Windows:
In drop-down menu Settings-Options-Airtest, click Custom Launcher and select your launcher.py. Press Edit button to edit the contents of launcher.py in the pop-up script window.
macOS:
From main menu, select Preferences, click Custom Launcher and select your launcher.py. Press Edit button to edit the contents of launcher.py in the pop-up script window.
../_images/settings_menu.png

Add sys.path path

We can enhance the functionality of the script by adding a local path to sys.path itself. For example, adding a local Python path into the IDE settings allows us to use locally installed Python third-party libraries and make the script even more powerful.

Assuming, we want to add the path C:\Python2.7\Lib\site-packages, click the AirtestIDE’s Options - Settings - Airtest and fill the corresponding field with desired path in Python syntax as shown on screenshot below.

../_images/airtest_settings.png

Delete Extra Images

When selected, unused screenshot in the script folder will be deleted.

Init/clean-up custom test scripts

AirtestIDE also allows to execute the initialization scripts to be run before the test script itself or to execute the cleaning code after the test script finishes.

It can be done in following way:

class CustomAirtestCase(AirtestCase):
    SCRIPTHOME = "directory that contains other scripts needed to be executed"

    def setUp(self):
        # exec setup script
        # if script is placed in self.SCRIPTHOME directory,
        # there is no need to provide absolute path to it
        self.exec_other_script("setup.air")
        super(CustomAirtestCase, self).setUp()

    def tearDown(self):
        # exec teardown script
        self.exec_other_script("teardown.air")
        super(CustomAirtestCase, self).setUp()

Run other scripts within the test script itself

To execute other scripts withing the test script itself, put these scripts into SCRIPTHOME directory as described above and call the script by using following statement in your test script:

exec_script("other_script_to_call.air")

Change the Airtest default settings:

When Airtest executes the test script and performs the image recognition, the default parameters might not be suitable in some cases. The settings can be customized as needed, for instance we need to change the recognition threshold to 0.75 (from default 0.6) to make the image recognition more strict and reduce the recognition error rate.

from airtest.core.settings import Settings as ST

class CustomAirtestCase(AirtestCase):
    def setUp(self):
        ST.THRESHOLD = 0.75

Following Airtest setting parameters can be modified customized as described above.

THRESHOLD Image recognition threshold, within (0, 1), bigger value means higher accuracy needed, default 0.6
THRESHOLD_STRICT Image recognition threshold for assertion, default 0.7
RESIZE_METHOD Redefine the screen zoom laws in devices with different resolution
LOG_DIR Path where to save the log files, the default path is the script directory
LOG_FILE Log file name, the default name is log.txt
OPDELAY How long to wait for next operation after current operation, the default delay is 0.1s
FIND_TIMEOUT Timeout for image matching, default 20s

Register custom device for more complex operations:

By default, AirtestIDE supports following devices: Android, Windows, and iOS, however, in some cases there is a need to run the script on specific device only. This can be done using the command line option --device Android: ///.

Furthermore, if there is need to modify some operations on the specific type of device, a new device can be implemented and registered with AirtestIDE. Then, you can execute your scripts with this device same way as described above.

Likewise, when Airtest scripts in AirtestIDE run in ‘Windows-Mode’, there might be few screen-capture issues and it is needed to modify the Windows-mode code itself. To solve this, you can implement a new class object that inherits Windows class:

from airtest.core.win.win import Windows, screenshot
class WindowsInIDE(Windows):
    def snapshot(self, filename="tmp.png"):
        # implement the special screen capture logic of IDE
        pass

Following code snippet shows how to register the new device with AirtestIDE.

class AirtestIDECase(AirtestCase):
"""Just for IDE use, there's some special logic of Windows."""
    def __init__(self):
        if get_platform() == "Windows":
            import WindowsInIDE
            # regist a special Windows of IDE-use into Airtest
            from airtest.core.api import G
            G.register_custom_device(WindowsInIDE)
        super(AirtestIDECase, self).__init__()

After the device registration, you can modify the device arguments in a command-line to run your scripts on the new device:

python launcher.py test.air --device WindowsInIDE:///

Summary

All sections above describes how to change and tweak the default AirtestIDE settings to meet more complex needs. Let’s summarize all:

How to implement a custom launcher in AirtestIDE:

  1. create custom_launcher.py by implementing a new class inherited from AirtestCase
  2. add your custom logic in setUp() and tearDown() methods
  3. select custom_launcher.py as launcher in drop-down menu Setting-Options-Airtest
  4. click Run button to execute your scripts, or use a command-line as python custom_launcher.py test.air airtest-script-params