II. Introduction to Airtest Launcher¶
Note
This article mainly describes the contents related to the launcher and its custom parameters in the writing and recording of the script, which may be subject to changes in the future due to the iteration of Airtest.
During the process of writing test scripts, simple statements encapsulated by Airtest may be inadequate for writing complex code. This chapter mainly introduces some advanced functions in script writing.
The currently supported custom functions of Airtest scripts include:
- Set the parameters for script execution.
- Add custom methods or replace default methods.
- Execute initialization or cleanup code, and even call other test case scripts before or after running test cases.
1.Introduction to Launcher¶
When running test case scripts in Airtest, a class called AirtestCase is implemented based on unittest.TestCase
, which adds all the relevant functionalities for executing basic Airtest scripts.
Therefore, if you want to add custom functions, simply add your own code to the setup
and teardown
based on the AirtestCase
class. If these settings and feature content are relatively fixed, they can be used as a launcher to initialize the relevant custom environment before running actual test cases.
For more information on AirtestCase,
please refer to the Airtest documentation.
2.Launcher Example¶
Here is an example code for customizing custom_launcher.py:
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)
Its main function is to add some custom content on top of AirtestCase, while also serving as a launcher to run actual test case code. For example:
python custom_launcher.py test.air --device Android:///serial_num --log log_path
This command line runs the script named test.air using a custom launcher called custom_launcher.py.
3.Launcher in Airtest-IDE¶
There are two ways to run scripts in the IDE. The first is to simply write the Airtest code to be executed in the script editor window, and then the script can be run using the default method without any additional code. The second is to create a custom launcher based on the launcher introduced above, which can initialize a customized environment for the Airtest code to run later.
1) Configuration method¶
Navigate to Menu > "Options" > "Settings" > "Airtest", then click on the setting box on the right side of "Customize Launcher File Location" to open the file selection window and choose the customized launcher.py file. Click "Edit" to edit the content of the launcher.py file, then click the "OK" button in the lower right corner to apply the new configuration.
2) Code example¶
Here is a code example of launcher used in AirtestIDE. Compared to the previous launcher example
that can be directly run on the command line, this one can highlight the current running code line in color and may also support additional features in the future.
from airtest.cli.runner import run_script
from airtest.cli.parser import runner_parser
from airtest.core.settings import Settings as ST
# If you run the script in the IDE, AirtestCase will be automatically loaded by the IDE. If you want to run the script independently via the command line, you need to manually import AirtestCase.
if not global().get("AirtestCase"):
from airtest.cli.runner import AirtestCase
class CustomAirtestCase(AirtestCase):
def __init__(self):
super(CustomAirtestCase, self).__init__()
def setUp(self):
print("custom setup")
super(CustomAirtestCase, 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, CustomAirtestCase)
4.Introduction to Launcher Customization¶
After inheriting AirtestCase in the custom launcher code, you can set the environment variables for running scripts in the setUp() and tearDown() methods.
class CustomAirtestCase(AirtestCase):
def setUp(self):
# add var/function/class/.. to globals
super(CustomAirtestCase, self).setUp()
1) Add custom variables and methods¶
Add custom variables to self.scope and then use this launcher to run Airtest scripts. Then the script code can directly use these variables without redefining them.
def setUp(self):
self.scope["hunter"] = "i am hunter"
self.scope["add"] = lambda x: x+1
2) Add the execution of subscripts before and after the formal script runs¶
During test case execution, there is a common requirement to run a fixed initialization script before the formal test cases or to run a cleanup script after the test cases have been executed. In the custom Airtest launcher, you can use simple code to fulfill these requirements.
class CustomAirtestCase(AirtestCase):
PROJECT_ROOT = "Common path for storing sub-scripts" # This can place sub-scripts in a common directory.
def setUp(self):
# exec setup script
self.exec_other_script("setup.air") # Assuming the setup.air script is stored in the PROJECT_ROOT directory, you can call it using a relative path instead of an absolute path.
super(CustomAirtestCase, self).setUp()
def tearDown(self):
# exec teardown script
self.exec_other_script("teardown.air")
super(CustomAirtestCase, self).setUp()
3) Add the execution of subscripts in the formal script¶
Another common requirement is to execute a sub-script within a script. You can also store the sub-script in the PROJECT_ROOT public directory and then call the code in the test.air script.
exec_script("sub-script.air")
4) Modify Airtest default parameter values¶
During the process of running scripts and recognizing images in Airtest, the default configuration parameters may not meet actual operational needs. The following code shows how to modify the default parameter configuration:
from airtest.core.settings import Settings as ST
class CustomAirtestCase(AirtestCase):
def setUp(self):
ST.THRESHOLD = 0.75
The above code modifies the default threshold for image recognition accuracy to 0.75 (previously 0.6), resulting in a reduced error rate for image recognition.
In the Settings of airtest.core.settings
, the following configuration options can be modified:
THRESHOLD | Image recognition accuracy threshold ranges between 0 and 1, the higher the value, the higher the recognition accuracy. |
---|---|
THRESHOLD_STRICT | The strict threshold used for image recognition in assert statements is set to 0.7 by default. |
RESIZE_METHOD | Redesign the UI resolution pattern for image recognition. |
LOG_DIR | The path for storing script running logs, with the current directory of the script as the default. |
LOG_FILE | The file name for storing logs, with log.txt as the default. |
OPDELAY | The waiting time after each step before proceeding to the next step, 0.1 seconds by default. |
FIND_TIMEOUT | The timeout for image search, 20 seconds by default. |
5) Register custom devices to enable more complex operations¶
Airtest supports three types of devices by default: Android, Windows, and IOS. To specify the type of device to run the script on, use the parameter --device Android:///
in the command line.
If modifications are needed for certain operations on these devices, a new device can be implemented and registered in Airtest, which can then be called when running the script.
For example, when running Airtest scripts in Windows mode in IDE, some modifications need to be made to the Windows code of Airtest due to the size issue of snapshots. For this, IDE implements a new class named WindowsInIDE.
from airtest.core.win.win import Windows, screenshot
class WindowsInIDE(Windows):
def snapshot(self, filename="tmp.png"):
# Implemented special snapshot operations related to IDE.
pass
Then, register WindowsInIDE to Airtest in the launcher::
class AirtestIDECase(AirtestCase):
"""Special handling for Windows has been added when used solely in the IDE"""
def __init__(self):
if get_platform() == "Windows":
import WindowsInIDE
# Register a Windows mode device exclusively for the IDE with Airtest.
from airtest.core.api import G
G.register_custom_device(WindowsInIDE)
super(AirtestIDECase, self).__init__()
After registration, you can use the newly registered device name to run the script by modifying the device parameter in the execution command.
python launcher.py test.air --device WindowsInIDE:///
5.Summary: Steps to Create a Custom Launcher¶
A custom launcher can modify configuration options and achieve more complex needs. Similar to unittest, it can run Airtest scripts as test cases.
To create a custom launcher in IDE, follow these steps:
-
Create a new file named
custom_launcher.py
and implement a class that inherits from AirtestCase within it. -
Add the desired operations in
setUp()
andtearDown()
. -
In the IDE's Options > Configuration > Airtest configuration, set the
custom_launcher.py
that was just created as the launcher. -
Click to run the script or run it via the command line using the following command:
python custom_launcher.py test.air airtest
script parameters.
6.Extended Content: Practical Example of the Launcher¶
For practical examples of Airtest launcher, please refer to the articles on the official AirtestProject WeChat public account.
-
The Versatility of Airtest Launcher - Adding Custom Command Line Arguments.
-
The Versatility of Airtest Launcher - Adding Custom Variables.