# Technical Documentation: AirtestProject/Airtest

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/AirtestProject/Airtest)

### Overview (README.md)

# Airtest &middot; [](https://travis-ci.org/AirtestProject/Airtest)

**Cross-Platform UI Automation Framework for Games and Apps**

**跨平台的UI自动化框架，适用于游戏和App** （[中文版点这里](./README_zh.md)）





## Features

*   **Write Once, Run Anywhere:** Airtest provides cross-platform APIs, including app installation, simulated input, assertion and so forth. Airtest uses image recognition technology to locate UI elements so that you can automate games and apps without injecting any code. 

*   **Fully Scalable:** Airtest cases can be easily run on large device farms, using commandline or python API. HTML reports with detailed info and screen recording allow you to quickly locate failure points. NetEase builds [Airlab](https://airlab.163.com/) on top of the Airtest Project.

*   **AirtestIDE:** AirtestIDE is an out of the box GUI tool that helps to create and run cases in a user-friendly way. AirtestIDE supports a complete automation workflow: ``create -> run -> report``.

*   **Poco:** [Poco](https://github.com/AirtestProject/Poco) adds the ability to directly access object(UI widget) hierarchy across the major platforms and game engines. It allows writing instructions in Python, to achieve more advanced automation.

Get started from [airtest homepage](http://airtest.netease.com/)

#### [Supported Platforms](./docs/wiki/device/platforms.md)


## Installation

Use `pip` to install the Airtest python library. 

```Shell
pip install -U airtest
```

On MacOS/Linux platform, you need to grant adb execute permission.

```Shell
# for mac
cd {your_python_path}/site-packages/airtest/core/android/static/adb/mac
# for linux
# cd {your_python_path}/site-packages/airtest/core/android/static/adb/linux
chmod +x adb
```

Download AirtestIDE from our [homepage](http://airtest.netease.com/) if you need to use the GUI tool.


## Documentation

You can find the complete Airtest documentation on [readthedocs](http://airtest.readthedocs.io/).


## Examples

Airtest aims at providing platform-independent API so that you can write automated cases once and run it on multiple devices and platforms.

1. Using [connect_device](http://airtest.readthedocs.io/en/latest/README_MORE.html#connect-device) API you can connect to any android/iOS device or windows application.
1. Then perform [simulated input](http://airtest.readthedocs.io/en/latest/README_MORE.html#simulate-input) to automate your game or app.
1. **DO NOT** forget to [make assertions](http://airtest.readthedocs.io/en/latest/README_MORE.html#make-assertion) of the expected result. 

```Python
from airtest.core.api import *

# connect an android phone with adb
init_device("Android")
# or use connect_device api
# connect_device("Android:///")

install("path/to/your/apk")
start_app("package_name_of_your_apk")
touch(Template("image_of_a_button.png"))
swipe(Template("slide_start.png"), Template("slide_end.png"))
assert_exists(Template("success.png"))
keyevent("BACK")
home()
uninstall("package_name_of_your_apk")
```

For more detailed info, please refer to [Airtest Python API reference](http://airtest.readthedocs.io/en/latest/all_module/airtest.core.api.html) or take a look at [API code](./airtest/core/api.py)


## Running ``.air`` cases from CLI

Using AirtestIDE, you can easily create automated cases as ``.air`` directories.
Airtest CLI provides the possibility to execute cases on different host machines and target device platforms without using AirtestIDE itself.

```Shell
# run cases targeting on Android phone connected to your host machine via ADB
airtest run "path to your .air dir" --device Android:///

# run cases targeting on Windows application whose title matches Unity.*
airtest run "path to your .air dir" --device "Windows:///?title_re=Unity.*"

# generate HTML report after running cases
airtest report "path to your .air dir"

# or use as a python module
python -m airtest run "path to your .air dir" --device Android:///
```

Try running provided example case: [``airtest/playground/test_blackjack.air``](./playground/test_blackjack.air) and see [Usage of CLI](http://airtest.readthedocs.io/en/latest/README_MORE.html#running-air-from-cli). Here is a [multi-device runner sample](https://github.com/AirtestProject/multi-device-runner).


## Contribution

Pull requests are very welcome. 


## Thanks

Thanks for all these great works that make this project better.

- [stf](https://github.com/openstf)
- [atx](https://github.com/NetEaseGame/ATX)
- [pywinauto](https://github.com/pywinauto/pywinauto)

---

### README MORE (`docs/README_MORE.rst`)

Airtest
=======

**Cross-Platform UI Automation Framework for Games and Apps**


.. raw:: html

    <div style=" overflow: hidden; max-width: 100%; height: auto;">
        <div align="center" class="embed-responsive embed-responsive-16by9">
            <video class="embed-responsive-item device-record" autoplay loop controls="none" style="top: 0;bottom: 0;left: 0;width: 100%;height: 100%;border: 0;">
                <source src="./demo.mp4" type="video/mp4">
            </video>
        </div>
        <br/>
    </div>


Getting Started
---------------

*   **Cross-Platform:** Airtest automates games and apps on almost all platforms.

*   **Write Once, Run Anywhere:** Airtest provides cross-platform APIs, including app installation, simulated input, assertion and so forth. Airtest uses image recognition technology to locate UI elements, so that you can automate games and apps without injecting any code. 

*   **Fully Scalable:** Airtest cases can be easily run on large device farms, using commandline or python API. HTML reports with detailed info and screen recording allow you to quickly locate failure points. NetEase builds [Airlab](https://airlab.163.com/) on top of Airtest Project.

*   **AirtestIDE:** AirtestIDE is an out of the box GUI tool that helps to create and run cases in a user-friendly way. AirtestIDE supports a complete automation workflow: ``create -> run -> report``.

`Get Started from Airtest Project Homepage`_


Supported Platforms
...................

-  Android
-  iOS
-  Windows
-  Unity
-  Cocos2dx
-  Egret
-  WeChat

`Read more <wiki/device/platforms.html>`_

Installation
------------

This section describes how to install Airtest python library.
Download AirtestIDE from our `homepage`_ if you need to use the GUI tool.


System Requirements
...................

-  Operating System:

   -  Windows
   -  MacOS X
   -  Linux

-  Python2.7 & Python3.3+


Installing the python package
..............................

Airtest package can be installed directly from Pypi. Use
``pip`` to manage installation of all python dependencies and package
itself.

.. code:: shell

    pip install -U airtest


You can also install it from Git repository.

.. code:: shell

    git clone https://github.com/AirtestProject/Airtest.git
    pip install -e airtest


Use ``-e`` here to install airtest in develop mode since this repo is in
rapid development. Then you can upgrade the repo with ``git pull``
later.


Documentation
-------------

You can find the complete Airtest documentation on `readthedocs`_.


Example
------------

Airtest provides simple APIs that are platform independent. This section
describes how to create an automated case which does the following:

1. connects to local android device with ``adb``
2. installs the ``apk`` application
3. runs application and takes the screenshot
4. performs several user operations (touch, swipe, keyevent)
5. uninstalls application

.. code:: python

    from airtest.core.api import *

    # connect an android phone with adb
    init_device("Android")
    # or use connect_device api
    # connect_device("Android:///")

    install("path/to/your/apk")
    start_app("package_name_of_your_apk")
    touch(Template("image_of_a_button.png"))
    swipe(Template("slide_start.png"), Template("slide_end.png"))
    assert_exists(Template("success.png"))
    keyevent("BACK")
    home()
    uninstall("package_name_of_your_apk")


For more detailed info, please refer to `Airtest Python API reference`_ or take a look at `API code`_


Basic Usage
------------

Airtest aims at providing platform independent API, so that you can write automated cases once and run it on multiple devices and platforms.

1. Using `connect_device`_ API you can connect to any android/iOS device or windows application. 

2. Then perform `simulated input`_ to automate your game or app. 

3. **DO NOT** forget to `make assertions`_ of the expected result. 


Connect Device
...............

Using ``connect_device`` API you can connect to any android/iOS device or windows application.

.. code:: python

    connect_device("platform://host:port/uuid?param=value&param2=value2")

- platform: Android/iOS/Windows...

- host: adb host for android, iproxy host for iOS, empty for other platforms

- port: adb port for android, iproxy port for iOS, empty for other platforms

- uuid: uuid for target device, e.g. serialno for Android, handle for Windows, uuid for iOS

- param: device initialization configuration fields. e.g. cap_method/ori_method/...

- value: device initialization configuration field values.


see also `connect_device`_.

Connect android device
***********************

1. Connect your android phone to your PC with usb
2. Use ``adb devices`` to make sure the state is ``device``
3. Connect device in Airtest
4. If you have multiple devices or even remote devices, use more params to specify the device

.. code:: python

    # connect an android phone with adb
    init_device("Android")

    # or use connect_device api with default params
    connect_device("android:///")

    # connect a remote device using custom params
    connect_device("android://adbhost:adbport/1234566?cap_method=javacap&touch_method=adb")

Connect iOS device
******************

Follow the instruction of `iOS-Tagent`_ to setup the environment.

.. code:: python

    # connect a local ios device
    connect_device("ios:///")

Connect windows application
****************************

.. code:: python

    # connect local windows desktop
    connect_device("Windows:///")

    # connect local windows application
    connect_device("Windows:///?title_re=unity.*")


Airtest uses `pywinauto` as Windows backend. For more window searching params, please see `pywinauto documentation`_.


Simulate Input
...............

Following APIs are fully supported:

- touch
- swipe
- text
- keyevent
- snapshot
- wait

More APIs are available, some of which may be platform specific, please see `API reference`_ for more information.

When using these general APIs, Airtest will automatically call the corresponding operations according to the current platform, such as the following code example:

.. code:: python

    from airtest.core.api import *  # import the general APIs such as touch/swipe/...

    connect_device("Android:///")
    touch((100, 100))

    connect_device("Windows:///")
    touch((100, 100))


Airtest also provides some platform-specific APIs for each platform, which can be queried in the module API of each platform:

- general APIs: `API reference`_
- Android: `airtest.core.android.Android class`_
- Windows: `airtest.core.win.Windows class`_
- iOS: `airtest.core.ios.IOS class`_


.. code:: python

    >>> from airtest.core.api import *
    >>> connect_device("Android:///")
    >>> dev = device()  # get current device, which is an Android object
    >>> print(type(dev))
    <class 'airtest.core.android.android.Android'>
    >>> dev.get_top_activity()  # use Android ADB to get the top activity
    ('com.google.android.apps.nexuslauncher', '.NexusLauncherActivity', '2720')


Make Assertion
...............

Airtest provide some assert functions, including:

- assert_exists
- assert_not_exists
- assert_equal
- assert_not_equal
- ...

When assertion fails, it will raise ``AssertsionError``. And you will see all assertions in the html report.

All assert statements can be found here: `airtest.core.assertions`_

Running ``.air`` from CLI
-----------------------------------

Using AirtestIDE, you can easily create and author automated cases as ``.air`` directories.
Airtest CLI provides the possibility to execute cases on different host machine and target device platforms without using AirtestIDE itself.

Connections to devices are specified by command line arguments, i.e. the code is platform independent and one automated case can be used for Android, iOS or Windows apps as well. 

Following examples demonstrate the basic usage of airtest framework running from CLI. For a deeper understanding, try running provided automated cases: ``airtest/playground/test_blackjack.air``


run automated case
..................
.. code:: shell

    # run automated cases and scenarios on various devices
    > airtest run "path to your .air dir" --device Android:///
    > airtest run "path to your .air dir" --device Android://adbhost:adbport/serialno
    > airtest run "path to your .air dir" --device Windows:///?title_re=Unity.*
    > airtest run "path to your .air dir" --device iOS:///
    ...
    # show help
    > airtest run -h
    usage: airtest run [-h] [--device [DEVICE]] [--log [LOG]]
                       [--recording [RECORDING]]
                       script

    positional arguments:
      script                air path

    optional arguments:
      -h, --help            show this help message and exit
      --device [DEVICE]     connect dev by uri string, e.g. Android:///
      --log [LOG]           set log dir, default to be script dir
      --recording [RECORDING]
                          record screen when running
      --compress
                          set snapshot quality, 1-99
      --no-image [NO_IMAGE]
                          Do not save screenshots


generate html report
.....................
.. code:: shell

    > airtest report "path to your .air dir"
    log.html
    > airtest report -h
    usage: airtest report [-h] [--outfile OUTFILE] [--static_root STATIC_ROOT]
                          [--log_root LOG_ROOT] [--record RECORD [RECORD ...]]
                          [--export EXPORT] [--lang LANG]
                          script

    positional arguments:
      script                script filepath

    optional arguments:
      -h, --help            show this help message and exit
      --outfile OUTFILE     output html filepath, default to be log.html
      --static_root STATIC_ROOT
                            static files root dir
      --log_root LOG_ROOT   log & screen data root dir, logfile should be
                            log_root/log.txt
      --record RECORD [RECORD ...]
                            custom screen record file path
      --export EXPORT       export a portable report dir containing all resources
      --lang LANG           report language


get case info
...................
.. code:: shell

    # print case info in json if defined, including: author, title, desc
    > python -m airtest info "path to your .air dir"
    {"author": ..., "title": ..., "desc": ...}


Import from other ``.air``
--------------------------
You can write some common used function in one ``.air`` script and import it from other scripts. Airtest provide ``using`` API to manage the context change including ``sys.path`` and ``Template`` search path.

.. code:: python

    from airtest.core.api import using
    using("common.air")

    from common import common_function

    common_function()


.. _Get Started from Airtest Project Homepage: http://airtest.netease.com/
.. _homepage: http://airtest.netease.com/
.. _readthedocs: http://airtest.readthedocs.io/
.. _pywinauto documentation: https://pywinauto.readthedocs.io/en/latest/code/pywinauto.findwindows.html#pywinauto.findwindows.find_elements
.. _simulated input: http://airtest.readthedocs.io/en/latest/README_MORE.html#simulate-input
.. _iOS-Tagent: https://github.com/AirtestProject/iOS-Tagent
.. _make assertions: http://airtest.readthedocs.io/en/latest/README_MORE.html#make-assertion
.. _Airtest Python API reference: http://airtest.readthedocs.io/en/latest/all_module/airtest.core.api.html
.. _API reference: http://airtest.readthedocs.io/en/latest/all_module/airtest.core.api.html
.. _API code: ./airtest/core/api.py
.. _connect_device: https://airtest.readthedocs.io/en/latest/all_module/airtest.core.api.html#airtest.core.api.connect_device
.. _AirLab: https://airlab.163.com
.. _airtest.core.android.Android class: ./all_module/airtest.core.android.android.html
.. _airtest.core.win.Windows class: ./all_module/airtest.core.win.win.html#airtest.core.win.win.Windows
.. _airtest.core.ios.IOS class: ./all_module/airtest.core.ios.ios.html#airtest.core.ios.ios.IOS
.. _airtest.core.assertions: ./all_module/airtest.core.assertions.html

---

### Index (`docs/index.rst`)

.. airtest documentation master file, created by
   sphinx-quickstart on Wed May 24 16:03:13 2017.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.


.. raw:: html

    <a href="https://github.com/AirtestProject/Airtest" class="github-corner" aria-label="View source on Github">
        <svg width="120" height="120" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: fixed; top: 0; border: 0; right: 0;" aria-hidden="true">
            <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
            <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
            <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
        </svg>
    </a>
    <style>
        .github-corner:hover .octo-arm {
            animation:octocat-wave 560ms ease-in-out
        }

        @keyframes octocat-wave {
            0%,100% {
                transform:rotate(0)
            }
            20%,60% {
                transform:rotate(-25deg)
            }
            40%,80% {
                transform:rotate(10deg)
            }
        }

        @media (max-width:500px) {
            .github-corner:hover .octo-arm {
                animation:none
            }
            .github-corner .octo-arm {
                animation:octocat-wave 560ms ease-in-out
            }
        }
    </style>


Welcome to Airtest documentation!
==================================

Airtest
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


**UI Automation Framework for Games and Apps**


.. raw:: html

    <div style=" overflow: hidden; max-width: 100%; height: auto;">
        <div align="center" class="embed-responsive embed-responsive-16by9">
            <video class="embed-responsive-item device-record" autoplay loop controls="none" style="top: 0;bottom: 0;left: 0;width: 100%;height: 100%;border: 0;">
                <source src="./demo.mp4" type="video/mp4">
            </video>
        </div>
        <br/>
    </div>


Airtest is a cross-platform UI automation framework for games and apps.

If you are new to Airtest, `Airtest Project Homepage`_ is a good place to get started.

The following documentation will guide you through main ideas of Airtest,
as well as providing a API reference documentation.



.. toctree::
   :maxdepth: 4
   :caption: Quickstart 

   ../README_MORE.rst



.. toctree::
   :maxdepth: 1
   :caption: Cross Platform API

   all_module/airtest.core.api



.. toctree::
   :maxdepth: 1
   :caption: Platform Specific API

   all_module/airtest.core.android
   all_module/airtest.core.ios
   all_module/airtest.core.win



.. toctree::
   :maxdepth: 1
   :caption: Modules Content 

   all_module/modules


.. toctree::
   :maxdepth: 1
   :caption: Wiki

   wiki/device/device.rst
   wiki/code/code.rst




.. _Airtest Project Homepage: http://airtest.netease.com/

---

### All Module Airtest.Aircv.Aircv (`docs/all_module/airtest.aircv.aircv.rst`)

airtest.aircv.aircv module
==========================

.. automodule:: airtest.aircv.aircv
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Cal Confidence (`docs/all_module/airtest.aircv.cal_confidence.rst`)

airtest.aircv.cal\_confidence module
====================================

.. automodule:: airtest.aircv.cal_confidence
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Error (`docs/all_module/airtest.aircv.error.rst`)

airtest.aircv.error module
==========================

.. automodule:: airtest.aircv.error
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Keypoint Base (`docs/all_module/airtest.aircv.keypoint_base.rst`)

airtest.aircv.keypoint\_base module
===================================

.. automodule:: airtest.aircv.keypoint_base
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Keypoint Matching (`docs/all_module/airtest.aircv.keypoint_matching.rst`)

airtest.aircv.keypoint\_matching module
=======================================

.. automodule:: airtest.aircv.keypoint_matching
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Keypoint Matching Contrib (`docs/all_module/airtest.aircv.keypoint_matching_contrib.rst`)

airtest.aircv.keypoint\_matching\_contrib module
================================================

.. automodule:: airtest.aircv.keypoint_matching_contrib
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Multiscale Template Matching (`docs/all_module/airtest.aircv.multiscale_template_matching.rst`)

airtest.aircv.multiscale\_template\_matching module
===================================================

.. automodule:: airtest.aircv.multiscale_template_matching
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv (`docs/all_module/airtest.aircv.rst`)

airtest.aircv package
=====================

.. automodule:: airtest.aircv
    :members:
    :undoc-members:
    :show-inheritance:

Submodules
----------

.. toctree::

   airtest.aircv.aircv
   airtest.aircv.cal_confidence
   airtest.aircv.error
   airtest.aircv.keypoint_base
   airtest.aircv.keypoint_matching
   airtest.aircv.keypoint_matching_contrib
   airtest.aircv.sift
   airtest.aircv.template
   airtest.aircv.template_matching
   airtest.aircv.utils

---

### All Module Airtest.Aircv.Screen Recorder (`docs/all_module/airtest.aircv.screen_recorder.rst`)

airtest.aircv.screen\_recorder module
=====================================

.. automodule:: airtest.aircv.screen_recorder
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Sift (`docs/all_module/airtest.aircv.sift.rst`)

airtest.aircv.sift module
=========================

.. automodule:: airtest.aircv.sift
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Template (`docs/all_module/airtest.aircv.template.rst`)

airtest.aircv.template module
=============================

.. automodule:: airtest.aircv.template
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Template Matching (`docs/all_module/airtest.aircv.template_matching.rst`)

airtest.aircv.template\_matching module
=======================================

.. automodule:: airtest.aircv.template_matching
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Aircv.Utils (`docs/all_module/airtest.aircv.utils.rst`)

airtest.aircv.utils module
==========================

.. automodule:: airtest.aircv.utils
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Cli.Info (`docs/all_module/airtest.cli.info.rst`)

airtest.cli.info module
=======================

.. automodule:: airtest.cli.info
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Cli.Parser (`docs/all_module/airtest.cli.parser.rst`)

airtest.cli.parser module
=========================

.. automodule:: airtest.cli.parser
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Cli (`docs/all_module/airtest.cli.rst`)

airtest.cli package
===================

.. automodule:: airtest.cli
    :members:
    :undoc-members:
    :show-inheritance:

Submodules
----------

.. toctree::

   airtest.cli.info
   airtest.cli.parser
   airtest.cli.runner

---

### All Module Airtest.Cli.Runner (`docs/all_module/airtest.cli.runner.rst`)

airtest.cli.runner module
=========================

.. automodule:: airtest.cli.runner
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Adb (`docs/all_module/airtest.core.android.adb.rst`)

airtest.core.android.adb module
===============================

.. automodule:: airtest.core.android.adb
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Android (`docs/all_module/airtest.core.android.android.rst`)

airtest.core.android.android module
===================================

.. automodule:: airtest.core.android.android
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Cap Methods.Adbcap (`docs/all_module/airtest.core.android.cap_methods.adbcap.rst`)

airtest.core.android.cap\_methods.adbcap module
===============================================

.. automodule:: airtest.core.android.cap_methods.adbcap
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Cap Methods.Base Cap (`docs/all_module/airtest.core.android.cap_methods.base_cap.rst`)

airtest.core.android.cap\_methods.base\_cap module
==================================================

.. automodule:: airtest.core.android.cap_methods.base_cap
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Cap Methods.Javacap (`docs/all_module/airtest.core.android.cap_methods.javacap.rst`)

airtest.core.android.cap\_methods.javacap module
================================================

.. automodule:: airtest.core.android.cap_methods.javacap
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Cap Methods.Minicap (`docs/all_module/airtest.core.android.cap_methods.minicap.rst`)

airtest.core.android.cap\_methods.minicap module
================================================

.. automodule:: airtest.core.android.cap_methods.minicap
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Cap Methods (`docs/all_module/airtest.core.android.cap_methods.rst`)

airtest.core.android.cap\_methods package
=========================================

.. automodule:: airtest.core.android.cap_methods
    :members:
    :undoc-members:
    :show-inheritance:

Submodules
----------

.. toctree::

   airtest.core.android.cap_methods.adbcap
   airtest.core.android.cap_methods.base_cap
   airtest.core.android.cap_methods.javacap
   airtest.core.android.cap_methods.minicap
   airtest.core.android.cap_methods.screen_proxy

---

### All Module Airtest.Core.Android.Cap Methods.Screen Proxy (`docs/all_module/airtest.core.android.cap_methods.screen_proxy.rst`)

airtest.core.android.cap\_methods.screen\_proxy module
======================================================

.. automodule:: airtest.core.android.cap_methods.screen_proxy
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Constant (`docs/all_module/airtest.core.android.constant.rst`)

airtest.core.android.constant module
====================================

.. automodule:: airtest.core.android.constant
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Ime (`docs/all_module/airtest.core.android.ime.rst`)

airtest.core.android.ime module
===============================

.. automodule:: airtest.core.android.ime
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Recorder (`docs/all_module/airtest.core.android.recorder.rst`)

airtest.core.android.recorder module
====================================

.. automodule:: airtest.core.android.recorder
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Rotation (`docs/all_module/airtest.core.android.rotation.rst`)

airtest.core.android.rotation module
====================================

.. automodule:: airtest.core.android.rotation
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android (`docs/all_module/airtest.core.android.rst`)

airtest.core.android package
============================

.. automodule:: airtest.core.android
    :members:
    :undoc-members:
    :show-inheritance:

For the interface provided for the Android platform, please refer to: `airtest.core.android.Android class <airtest.core.android.android.html>`_

Subpackages
-----------

.. toctree::

    airtest.core.android.touch_methods
    airtest.core.android.cap_methods

Submodules
----------

.. toctree::

   airtest.core.android.android
   airtest.core.android.adb
   airtest.core.android.constant
   airtest.core.android.ime
   airtest.core.android.cap_methods.javacap
   airtest.core.android.cap_methods.minicap
   airtest.core.android.recorder
   airtest.core.android.rotation
   airtest.core.android.yosemite

---

### All Module Airtest.Core.Android.Touch Methods.Base Touch (`docs/all_module/airtest.core.android.touch_methods.base_touch.rst`)

airtest.core.android.touch\_methods.base\_touch module
======================================================

.. automodule:: airtest.core.android.touch_methods.base_touch
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Touch Methods.Maxtouch (`docs/all_module/airtest.core.android.touch_methods.maxtouch.rst`)

airtest.core.android.touch\_methods.maxtouch module
===================================================

.. automodule:: airtest.core.android.touch_methods.maxtouch
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Touch Methods.Minitouch (`docs/all_module/airtest.core.android.touch_methods.minitouch.rst`)

airtest.core.android.touch\_methods.minitouch module
====================================================

.. automodule:: airtest.core.android.touch_methods.minitouch
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Touch Methods (`docs/all_module/airtest.core.android.touch_methods.rst`)

airtest.core.android.touch\_methods package
===========================================

.. automodule:: airtest.core.android.touch_methods
    :members:
    :undoc-members:
    :show-inheritance:

Submodules
----------

.. toctree::

   airtest.core.android.touch_methods.base_touch
   airtest.core.android.touch_methods.maxtouch
   airtest.core.android.touch_methods.minitouch
   airtest.core.android.touch_methods.touch_proxy

---

### All Module Airtest.Core.Android.Touch Methods.Touch Proxy (`docs/all_module/airtest.core.android.touch_methods.touch_proxy.rst`)

airtest.core.android.touch\_methods.touch\_proxy module
=======================================================

.. automodule:: airtest.core.android.touch_methods.touch_proxy
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Yosemite (`docs/all_module/airtest.core.android.yosemite.rst`)

airtest.core.android.yosemite module
====================================

.. automodule:: airtest.core.android.yosemite
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Android.Yosemite Ext (`docs/all_module/airtest.core.android.yosemite_ext.rst`)

airtest.core.android.yosemite\_ext module
=========================================

.. automodule:: airtest.core.android.yosemite_ext
   :members:
   :undoc-members:
   :show-inheritance:

---

### All Module Airtest.Core.Api (`docs/all_module/airtest.core.api.rst`)

airtest.core.api module
=======================

.. automodule:: airtest.core.api
    :members:
    :undoc-members:
    :show-inheritance:

Some useful functions
=====================

.. autofunction:: airtest.core.helper.using

.. autofunction:: airtest.core.helper.log

.. autofunction:: airtest.core.helper.logwrap


Assertions in airtest
======================

All assert statements can be found here: `airtest.core.assertions <airtest.core.assertions.html>`_

---

### All Module Airtest.Core.Assertions (`docs/all_module/airtest.core.assertions.rst`)

airtest.core.assertions module
==============================

.. automodule:: airtest.core.assertions
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Cv (`docs/all_module/airtest.core.cv.rst`)

airtest.core.cv module
======================

.. automodule:: airtest.core.cv
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Device (`docs/all_module/airtest.core.device.rst`)

airtest.core.device module
==========================

.. automodule:: airtest.core.device
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Error (`docs/all_module/airtest.core.error.rst`)

airtest.core.error module
=========================

.. automodule:: airtest.core.error
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Helper (`docs/all_module/airtest.core.helper.rst`)

airtest.core.helper module
==========================

.. automodule:: airtest.core.helper
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Constant (`docs/all_module/airtest.core.ios.constant.rst`)

airtest.core.ios.constant module
================================

.. automodule:: airtest.core.ios.constant
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Elements Type (`docs/all_module/airtest.core.ios.elements_type.rst`)

airtest.core.ios.elements\_type module
======================================

.. automodule:: airtest.core.ios.elements_type
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Fake Minitouch (`docs/all_module/airtest.core.ios.fake_minitouch.rst`)

airtest.core.ios.fake\_minitouch module
=======================================

.. automodule:: airtest.core.ios.fake_minitouch
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Instruct Cmd (`docs/all_module/airtest.core.ios.instruct_cmd.rst`)

airtest.core.ios.instruct\_cmd module
=====================================

.. automodule:: airtest.core.ios.instruct_cmd
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Ios (`docs/all_module/airtest.core.ios.ios.rst`)

airtest.core.ios.ios module
===========================

.. automodule:: airtest.core.ios.ios
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Minicap (`docs/all_module/airtest.core.ios.minicap.rst`)

airtest.core.ios.minicap module
===============================

.. automodule:: airtest.core.ios.minicap
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Mjpeg Cap (`docs/all_module/airtest.core.ios.mjpeg_cap.rst`)

airtest.core.ios.mjpeg\_cap module
==================================

.. automodule:: airtest.core.ios.mjpeg_cap
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Relay (`docs/all_module/airtest.core.ios.relay.rst`)

airtest.core.ios.relay module
=============================

.. automodule:: airtest.core.ios.relay
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios.Rotation (`docs/all_module/airtest.core.ios.rotation.rst`)

airtest.core.ios.rotation module
================================

.. automodule:: airtest.core.ios.rotation
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Ios (`docs/all_module/airtest.core.ios.rst`)

airtest.core.ios package
========================

.. automodule:: airtest.core.ios
    :members:
    :undoc-members:
    :show-inheritance:

For the interface provided for the iOS platform, please refer to: `airtest.core.ios.IOS class <airtest.core.ios.ios.html#airtest.core.ios.ios.IOS>`_

Submodules
----------

.. toctree::

   airtest.core.ios.ios
   airtest.core.ios.constant
   airtest.core.ios.elements_type
   airtest.core.ios.instruct_cmd
   airtest.core.ios.rotation

---

### All Module Airtest.Core.Linux.Linux (`docs/all_module/airtest.core.linux.linux.rst`)

airtest.core.linux.linux module
===============================

.. automodule:: airtest.core.linux.linux
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Linux (`docs/all_module/airtest.core.linux.rst`)

airtest.core.linux package
==========================

.. automodule:: airtest.core.linux
    :members:
    :undoc-members:
    :show-inheritance:

Submodules
----------

.. toctree::

   airtest.core.linux.linux

---

### All Module Airtest.Core (`docs/all_module/airtest.core.rst`)

airtest.core package
====================

.. automodule:: airtest.core
    :members:
    :undoc-members:
    :show-inheritance:

Subpackages
-----------

.. toctree::

    airtest.core.android
    airtest.core.ios
    airtest.core.linux
    airtest.core.win

Submodules
----------

.. toctree::

   airtest.core.api
   airtest.core.assertions
   airtest.core.cv
   airtest.core.device
   airtest.core.error
   airtest.core.helper
   airtest.core.settings

---

### All Module Airtest.Core.Settings (`docs/all_module/airtest.core.settings.rst`)

airtest.core.settings module
============================

.. automodule:: airtest.core.settings
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Win.Ctypesinput (`docs/all_module/airtest.core.win.ctypesinput.rst`)

airtest.core.win.ctypesinput module
===================================

.. automodule:: airtest.core.win.ctypesinput
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Win (`docs/all_module/airtest.core.win.rst`)

airtest.core.win package
========================

For the interface provided for the Windows platform, please refer to: `airtest.core.win.Windows class <airtest.core.win.win.html>`_

.. automodule:: airtest.core.win
    :members:
    :undoc-members:
    :show-inheritance:

Submodules
----------

.. toctree::

   airtest.core.win.win
   airtest.core.win.ctypesinput

---

### All Module Airtest.Core.Win.Screen (`docs/all_module/airtest.core.win.screen.rst`)

airtest.core.win.screen module
==============================

.. automodule:: airtest.core.win.screen
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Core.Win.Win (`docs/all_module/airtest.core.win.win.rst`)

airtest.core.win.win module
===========================

.. automodule:: airtest.core.win.win
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Report.Report (`docs/all_module/airtest.report.report.rst`)

airtest.report.report module
============================

.. automodule:: airtest.report.report
    :members:
    :undoc-members:
    :show-inheritance:

---

### All Module Airtest.Report (`docs/all_module/airtest.report.rst`)

airtest.report package
======================

.. automodule:: airtest.report
    :members:
    :undoc-members:
    :show-inheritance:

Submodules
----------

.. toctree::

   airtest.report.report

---

### All Module Airtest (`docs/all_module/airtest.rst`)

airtest package
===============

.. automodule:: airtest
    :members:
    :undoc-members:
    :show-inheritance:

Subpackages
-----------

.. toctree::

    airtest.aircv
    airtest.cli
    airtest.core
    airtest.report

---

### Wiki Code Code (`docs/wiki/code/code.rst`)

Code Example
============================

.. toctree::

    code_example.md
    code_example_zh.md

---

### Wiki Code Code Example (`docs/wiki/code/code_example.md`)

# Common problems and code examples

[中文版](code_example_zh.md)

## How to initialize the script

### air script: auto_setup()

Automatically configure the interface of the running environment, you can configure the path where the current script is located, the device used, the storage path of the log content, the project root directory, and the screenshot compression accuracy:

```
auto_setup(basedir=None, devices=None, logdir=None, project_root=None, compress=None)
```

Interface example:

```python
auto_setup(__file__)

auto_setup(__file__, devices=["android://127.0.0.1:5037/emulator-5554?cap_method=JAVACAP&&ori_method=MINICAPORI&&touch_method=MINITOUCH"],
           logdir=True, project_root=r"D:\test", compress=90)
```



## How to connect/use the device

> **Please note:** For more device related information, please refer to [Document](../device/device)



### Connect the device: connect_device(URI)

The interface to connect to the device requires the URI string used to initialize the device. Example:

```python
# Connect Android device
connect_device("Android://127.0.0.1:5037/SJE5T17B17")

# Connect iOS device
connect_device("iOS:///127.0.0.1:8100")

# Connect Windows window
connect_device("Windows:///123456")

# Connect the simulator
connect_device("Android://127.0.0.1:5037/127.0.0.1:62001?cap_method=JAVACAP&&ori_method=ADBORI")
```



### Connect the device: init_device()

To initialize the interface of the device, you need to pass in the device platform, the uuid and optional parameters of the device, where uuid is the serial number of Android, the window handle of Windows, or the uuid of iOS:

```python
init_device(platform='Android', uuid=None, **kwargs)
```

Example of interface usage:

```python
# Connect Android device
init_device(platform="Android",uuid="SJE5T17B17",cap_method="JAVACAP")

# Connect Windows window
init_device(platform="Windows",uuid="123456")
```

### Get the current device: device()

Return the device instance currently in use, the usage example is as follows:

```python
dev = device()
dev.swipe_along([[959, 418],[1157, 564],[1044, 824],[751, 638],[945, 415]])
```

### Set the current device: set_current()

Set the current device used, which can be used to switch between multiple devices. Examples are as follows:

```python
# The first type: Incoming numbers 0, 1, 2, etc., switch the currently operating mobile phone to the first and second mobile phone connected to Airtest
set_current(0)
set_current(1)

# Second: Switch the current mobile phone to the serial number serialno1, serialno2
set_current("serialno1")
set_current("serialno2")
```

## How to perform coordinate click/coordinate sliding

### Coordinate click

When you click on the device, you can pass in parameters such as the click location and the number of clicks. The optional parameters under different platforms are slightly different. Examples are as follows:

```python
# Pass in absolute coordinates as the click position
touch([100,100])

# Pass in the template picture instance, click the center of the screenshot
touch(Template(r"tpl1606730579419.png", target_pos=5, record_pos=(-0.119, -0.042), resolution=(1080, 1920)))

# Click 2 times
touch([100,100],times=2)

# Under Android and Windows platforms, you can set the click duration
touch([100,100],duration=2)
```

### Coordinate sliding

For sliding operations on the device, there are two ways to pass parameters, one is to pass in the starting point and end of the sliding, and the other is to pass in the starting point and sliding direction vector. Examples are as follows:

```python
# Pass in absolute coordinates as the start and end of the sliding
swipe([378, 1460],[408, 892])

# Incoming image as a starting point, slide along a certain direction
swipe(Template(r"tpl1606814865574.png", record_pos=(-0.322, 0.412), resolution=(1080, 1920)), vector=[-0.0316, -0.3311])

# Commonly, you can also set the duration of sliding
swipe([378, 1460],[408, 892],duration=1)
```



## How to install/start/uninstall apps

### Start the application: start_app()

To start the target application on the device, you need to pass in the package name of the application, which supports Android and iOS platforms. Examples:

```python
start_app("com.netease.cloudmusic")
```

### Terminate application operation: stop_app()

To terminate the operation of the target application on the device, the package name of the application needs to be passed in. It supports Android and iOS platforms. Examples:

```python
stop_app("com.netease.cloudmusic")
```

### Clear application data: clear_app()

To clean up the target application data on the device, the package name of the application needs to be passed in. **Only supports the Android platform**, example:

```
clear_app("com.netease.cloudmusic")
```

### Install the application: install()

To install the application on the device, you need to pass in the complete apk installation path, **only supports the Android platform**, example:

```python
install(r"D:\demo\tutorial-blackjack-release-signed.apk")
```

### Uninstall the application: uninstall()

To uninstall the application on the device, you need to pass in the package name of the uninstalled application. **Only supports the Android platform**, example:

```python
uninstall("com.netease.cloudmusic")
```



## Key event: keyevent

### Android keyevent

It is equivalent to executing `adb shell input keyevent KEYNAME`, an example is as follows:

```python
keyevent("HOME")
# The constant corresponding to the home key is 3
keyevent("3") # same as keyevent("HOME")
keyevent("BACK")
keyevent("KEYCODE_DEL")
```

### Windows keyevent

Unlike Android, the Windows platform uses the `pywinauto.keyboard module` module for key input. Example:

```
keyevent("{DEL}")

# Use Alt+F4 to close the Windows window
keyevent("%{F4}")
```

### iOS keyevent

Currently only supports HOME key:

```
keyevent("HOME")
```

## How to enter text

To enter text on the device, the text box needs to be activated (that is, click the text box first, and then use the `text()` interface to enter). Examples are as follows:

```
touch (Template instance of text box)
text("input text")

# By default, text is with carriage return, you can pass False if you don’t need it
text("123",enter=False)

# Under the Android platform, you can also click the search button on the soft keyboard after typing
text("123",enter=False,search=True)
```

## How to delete text

Delete a single character through the `keyevent` interface:

```
keyevent("KEYCODE_DEL")
keyevent("67") # 67 is the delete key, please note that the input is a string
```

Simulate clearing the input box operation:

```
for i in range(10):
    keyevent("67")
```

Delete poco (leave the input box blank):

 `poco("xxx").set_text("")`.



## Log

### How to log into the report

The `log()` interface is convenient to insert some user-defined log information, which will be displayed in the Airtest report. In Airtest version 1.1.6, the log interface supports 4 parameters:

- `args`, which can be a string, a non-string or a `traceback` object;

- `timestamp`, used to customize the timestamp of the current log;

- `desc`, used to customize the title of the log;
- `snapshot`, indicating whether it is necessary to take a screenshot of the current screen image and display it in the report:

Examples are as follows:

```python
# Incoming string
log("123",desc="this is title 01")

# Pass in non-string
data = {"test": 123, "time": 123456}
log(data,desc="this is title 02")

# Incoming traceback
try:
    1/0
except Exception as e:
    log(e, desc="This is title 03")
    
# Record timestamp and take a screenshot of the current screen
log("123", timestamp=time.time(), desc="This is title 04", snapshot=True)
```

### How to set the log save path

Airtest provides some global settings, in which `LOGFILE` is used to customize the name of the txt file that records the log content; `LOGDIR` is used to customize the save path of the log content, examples are as follows:

```python
from airtest.core.settings import Settings as ST
from airtest.core.helper import set_logdir

ST.LOG_FILE = "log123.txt"
set_logdir(r'D:\test\1234.air\logs')

auto_setup(__file__)

```



### How to filter unnecessary log information

Add **settings for log information level** at the beginning of the script code:

```
__author__ = "Airtest"

import logging
logger = logging.getLogger("airtest")
logger.setLevel(logging.ERROR)
```

After changing the level of output log information to `[ERROR]`, only a small amount of initialization information is output during the entire script running process, which makes it easier to view error messages.



## Report

### Report generation: simple_report()

Simple interface for generating reports:

```python
simple_report(filepath, logpath=True, logfile='log.txt', output='log.html')
```

The 4 parameters that can be passed in represent:

- `filepath`, the path of the script file, you can directly pass in the variable `__file__``
- `logpath`, the path where the log content is located, if it is `True`, it will default to the path where the current script is located to find the log content
- `logfile`, the file path of log.txt
- `output`, the path to the report, must end with `.html`

Examples are as follows:

```python
from airtest.report.report import simple_report
auto_setup(__file__, logdir=True)

# N use case scripts are omitted here

simple_report(__file__,logpath=True,logfile=r"D:\test\1234.air\log\log.txt",output=r"D:\test\1234.air\log\log1234.html")
```



### Report generation: LogToHtml()

Base class of report:

```python
class LogToHtml(script_root, log_root=``, static_root='', export_dir=None, script_name='', logfile='log.txt', lang='en', plugins=None)
```

 The `logtohtml` class can pass in many parameters:

- `script_root`, script path
- `log_root`, the path of the log file
- `static_root`, the server path where static resources are deployed
- `export_dir`, the storage path of the export report
- `script_name`, the script name
- `logfile`, the path of the log file log.txt
- `lang`, the language of the report (Chinese: zh; English: en)
- `plugins`, plug-ins, will be used if poco or airtest-selenium is used

When using `logtohtml` to generate a test report, we generally first instantiate a `logtohtml` object, and then use this object to call the class method `report()` to generate the report. An example is as follows:

```python
from airtest.report.report import LogToHtml

# N use case scripts are omitted here

h1 = LogToHtml(script_root=r'D:\test\1234.air', log_root=r"D:\test\1234.air\log", export_dir=r"D:\test\1234.air" ,logfile= r'D:\test\1234.air\log\log.txt', lang='en', plugins=["poco.utils.airtest.report"])
h1.report()
```

## Screenshot

### How to take a screenshot with script

Take a screenshot of the target device and save it to a file. You can pass in the file name of the screenshot, a short description of the screenshot, the compression accuracy of the screenshot, and the maximum size of the screenshot. Examples are as follows:

```python
snapshot(filename="123.jpg",msg="Homepage screenshot",quality=90,max_size=800)
```

### How to take a partial screenshot

Partial screenshots or screenshots by coordinates are a frequently asked question. Airtest provides the `crop_image(img, rect)` method to help us achieve partial screenshots:

```python
# -*- encoding=utf8 -*-
__author__ = "AirtestProject"

from airtest.core.api import *
# crop_image() method is in airtest.aircv and needs to be introduced
from airtest.aircv import *

auto_setup(__file__)
screen = G.DEVICE.snapshot()

# Partial screenshot
screen = aircv.crop_image(screen,(0,160,1067,551))
# Save partial screenshots to the log folder
try_log_screen(screen)
```

### How to do partial image recognition

Steps to find a partial picture:

- Take a partial screenshot
- Define the target screenshot object to find
- Use the `match_in` method to find the specified screenshot object in the partial screenshot

```python
from airtest.core.api import *
from airtest.aircv import *
auto_setup(__file__)

screen = G.DEVICE.snapshot()
# Partial screenshot
local_screen = aircv.crop_image(screen,(0,949,1067,1500))

# Set our target screenshot as a Template object
tempalte = Template(r"png_code/settings.png")
# Find the specified image object in the partial screenshot
pos = tempalte.match_in(local_screen)

# Return the coordinates of the image object found (the coordinates are relative to the coordinates of the local screenshot)
print(pos)

# To return the coordinates of the target in the entire screen, both x and y need to be added with the minimum x and y set during the partial screenshot
print(pos[0]+0,pos[1]+949)
```

### How to set the report screenshot accuracy

`SNAPSHOT_QUALITY` is used to set the global screenshot compression accuracy, the default value is 10, and the value range is [1,100]. Examples are as follows:

```python
from airtest.core.settings import Settings as ST

# Set the global screenshot accuracy to 90
ST.SNAPSHOT_QUALITY = 90
```

Define the compression accuracy of a single screenshot, example:

```python
# Set the compression accuracy of a single screenshot to 90, and the remaining unset will be based on the global compression accuracy
snapshot(quality=90)
```


### How to set the maximum size of report screenshots

In Airtest1.1.6, a new setting for specifying the maximum size of screenshots is added: `ST.IMAGE_MAXSIZE`. If it is set to 1200, the length and width of the last saved screenshot will not exceed 1200. Example:

```python
from airtest.core.settings import Settings as ST

# Set the global screenshot size not to exceed 600*600, if not set, the default is the original image size
ST.IMAGE_MAXSIZE = 600

# In the case of not setting separately, the value of the global variable in ST is used by default, that is, 600*600
snapshot(msg="test12")
# Set the maximum size of a single screenshot not to exceed 1200*1200
snapshot(filename="test2.png", msg="test02", quality=90, max_size=1200)
```

### How to specify the path and name for saving screenshots

Take a screenshot of the screen of the current device and save the screenshot in a custom path. This can be achieved in the following ways:

```python
screen = G.DEVICE.snapshot()
pil_img = cv2_2_pil(screen)
pil_img.save(r"D:/test/首页.png", quality=99, optimize=True)
```

## How to make assertions

### Assert the existence: assert_exists()

There is an assertion target on the device screen, you need to pass in 1 assertion target (screenshot) and the assertion step information displayed on the report, example:

```python
assert_exists(Template(r"tpl1607324047907.png", record_pos=(-0.382, 0.359), resolution=(1080, 1920)), "Find the Tmall entrance on the homepage")
```


### Assert that does not exist: assert_not_exists()

There is no assertion target on the device screen. Like `assert_exists()`, you need to pass in an assertion target (screenshot) and the assertion step information displayed on the report, for example:

```python
assert_not_exists(Template(r"tpl1607325103087.png", record_pos=(-0.005, 0.356), resolution=(1080, 1920)), "The icon of Tmall Global does not exist on the current page")
```

### Assert equal: assert_equal()

To assert that two values are equal, you need to pass in the values of the two assertions, and a short description of the assertion that will be recorded in the report:

```
assert_equal("actual value", "predicted value", "please fill in a short description of the assertion")
```

It is often used to make an assertion together with the script that poco gets the attribute. Examples are as follows:

```python
assert_equal(poco("com.taobao.taobao:id/dx_root").get_text(), "Tmall new product", "The text attribute value of the control is Tmall new product")

assert_equal(str(poco(text="Tmall new product").attr("enabled")), "True", "The enabled attribute value of the control is True")
```

### Assert that is not equal: assert_not_equal()

Assert that two values are not equal, like `assert_equal()`, you need to pass in the values of 2 assertions, and a short description of the assertion that will be recorded in the report:

```python
assert_not_equal("actual value", "predicted value", "please fill in a short description of the assertion")

assert_not_equal("1", "2", "Assert that 1 and 2 are not equal")
```



## How to switch between absolute and relative coordinates

Use code to switch between absolute coordinates and relative coordinates:

```python
# Get device screen resolution (vertical screen)
height = G.DEVICE.display_info['height']
width = G.DEVICE.display_info['width']

# Known absolute coordinates [311,1065], converted to relative coordinates
x1 = 311/width
y1 = 1065/height
poco.click([x1,y1])

# Known relative coordinates [0.3,0.55], convert to absolute coordinates
x2 = 0.3*width
y2 = 0.55*height
touch([x2,y2])

# If it is a horizontal screen device, the resolution is as follows
height = G.DEVICE.display_info['width']
width = G.DEVICE.display_info['height']
```

Determine whether the current screen is horizontal or vertical, and get the resolution of the current screen:

```python
if G.DEVICE.display_info['orientation'] in [1,3]:
    height = G.DEVICE.display_info['width']
    width = G.DEVICE.display_info['height']
else:
    height = G.DEVICE.display_info['height']
    width = G.DEVICE.display_info['width']
```

## How to call other .air scripts

If you want to call a public function encapsulated in another `.air` script in a `.air` script, you can do this:

```python
from airtest.core.api import using
# Relative path or absolute path, make sure the code can be found
using("common.air")

from common import common_function
common_function()
```

If the paths of the sub-scripts that need to be referenced are all placed in a certain directory, you can set a default project root directory `PROJECT_ROOT`, so that when using the `using` interface, you can find other sub-scripts in the current root directory without filling in The full path makes it easier to call each other between scripts.

For example, if we create a script named `test1.air`, the actual path is `/User/test/project/test1.air`:

```python
from airtest.core.api import *

def test():
    touch("tmp.png")
```

Another `main.air` script in the same directory can refer to the `test` in it like this:

```python
from airtest.core.api import *

ST.PROJECT_ROOT = "/User/test/project"
using("test1.air")
from test1 import test
```


## How to record screen during script running

Currently only supports screen recording on Android devices, please refer to [Record the screen while running the script](../device/android.html#record-the-screen-while-running-the-script)

---

### Wiki Code Code Example Zh (`docs/wiki/code/code_example_zh.md`)

# 常见问题与代码示例

[English version](code_example.md)

## 如何进行脚本初始化
### air脚本：auto_setup()
自动配置运行环境的接口，可以配置当前脚本所在路径、使用的设备、log内容的保存路径、项目根目录和截图压缩精度：

```
auto_setup(basedir=None, devices=None, logdir=None, project_root=None, compress=None)
```
接口示例：

```
auto_setup(__file__)

auto_setup(__file__, devices=["android://127.0.0.1:5037/emulator-5554?cap_method=JAVACAP&&ori_method=MINICAPORI&&touch_method=MINITOUCH"], logdir=True, project_root=r"D\test", compress=90)
```

## 如何连接/使用设备

> **请注意：** 更多设备相关的信息，请参考[文档](../device/device)



### 连接设备：connect_device(URI)
连接设备的接口，需要传入用于初始化设备的URI字符串，示例：

```
# 连接安卓设备
connect_device("Android://127.0.0.1:5037/SJE5T17B17")

# 连接iOS设备
connect_device("iOS:///127.0.0.1:8100")

# 连接Windows窗口
connect_device("Windows:///123456")

# 连接模拟器
connect_device("Android://127.0.0.1:5037/127.0.0.1:62001?cap_method=JAVACAP&&ori_method=ADBORI")
```

### 连接设备：init_device()
初始化设备的接口，需要传入设备平台、设备的uuid和可选参数等，其中uuid为，Android的序列号，Windows的窗口句柄，或iOS的uuid：

```
init_device(platform='Android', uuid=None, **kwargs)
```
接口使用示例：

```
# 连接安卓设备
init_device(platform="Android",uuid="SJE5T17B17",cap_method="JAVACAP")

# 连接Windows窗口
init_device(platform="Windows",uuid="123456")
```

### 获取当前设备：device()
返回当前正在使用中的设备实例，用法示例如下：

```
dev = device()
dev.swipe_along([[959, 418],[1157, 564],[1044, 824],[751, 638],[945, 415]])
```

### 设置当前设备：set_current()
设置当前的使用设备，可以用于在多设备之间切换使用，示例如下：

```
# 第一种：传入数字0、1、2等，切换当前操作的手机到Airtest连接的第1台、第2台手机
set_current(0)
set_current(1)

# 第二种：切换当前操作的手机到序列号为serialno1、serialno2的手机
set_current("serialno1")
set_current("serialno2")
```

## 如何进行坐标点击/坐标滑动

### 坐标点击

在设备上进行点击操作，可以传入点击位置、点击次数等参数，不同平台下的可选参数稍有不同，示例如下：

```
# 传入绝对坐标作为点击位置
touch([100,100])

# 传入Template图片实例，点击截图中心位置
touch(Template(r"tpl1606730579419.png", target_pos=5, record_pos=(-0.119, -0.042), resolution=(1080, 1920)))

# 点击2次
touch([100,100],times=2)

# Android和Windows平台下，可以设置点击时长
touch([100,100],duration=2)
```

### 坐标滑动

在设备上进行滑动操作，有2种传参方式，一种是传入滑动的起点和终点，一种是传入滑动的起点和滑动方向vector，示例如下：

```
# 传入绝对坐标作为滑动的起点和终点
swipe([378, 1460],[408, 892])

# 传入图像作为起点，沿着某个方向滑动
swipe(Template(r"tpl1606814865574.png", record_pos=(-0.322, 0.412), resolution=(1080, 1920)), vector=[-0.0316, -0.3311])

# 常见的还可以设置滑动的持续时长
swipe([378, 1460],[408, 892],duration=1)
```

## 如何安装/启动/卸载应用

### 启动应用：start_app()
在设备上启动目标应用，需传入应用的包名，支持Android和iOS平台，示例：

```
start_app("com.netease.cloudmusic")
```

### 终止应用运行：stop_app()
在设备上终止目标应用的运行，需传入应用的包名，支持Android和iOS平台，示例：

```
stop_app("com.netease.cloudmusic")
```

### 清除应用数据：clear_app()
清理设备上的目标应用数据，需传入应用的包名，**仅支持Android平台** ，示例：

```
clear_app("com.netease.cloudmusic")
```

### 安装应用：install()
安装应用到设备上，需传入完整的apk的安装路径，**仅支持Android平台**，示例：
```
install(r"D:\demo\tutorial-blackjack-release-signed.apk")
```

### 卸载应用：uninstall()

卸载设备上的应用，需传入被卸载应用的包名，**仅支持Android平台**，示例：

```
uninstall("com.netease.cloudmusic")
```

## 按键事件：keyevent

### Android的keyevent

等同于执行 `adb shell input keyevent KEYNAME` ，示例如下：

```
keyevent("HOME")
# The constant corresponding to the home key is 3
keyevent("3")  # same as keyevent("HOME")
keyevent("BACK")
keyevent("KEYCODE_DEL")
```

### Windows的keyevent
与安卓不同，Windows平台使用 `pywinauto.keyboard module` 模块来进行按键输入，示例：  

```
keyevent("{DEL}")

# 使用Alt+F4关闭Windows窗口
keyevent("%{F4}")
```
### iOS的keyevent

目前仅支持HOME键：
```
keyevent("HOME")
```

## 如何输入文本
在设备上输入文本，文本框需要处于激活状态（即先点击文本框，再使用 `text()` 接口进行输入）。示例如下：

```
touch(文本框的Template实例)
text("输入的文本")

# 默认情况下，text是带回车的，不需要可以传入False
text("123",enter=False)

# 安卓平台下，还支持输入后点击软键盘的搜索按钮
text("123",enter=False,search=True)
```

## 如何删除文本
通过 `keyevent` 接口删除单个字符:
```
keyevent("KEYCODE_DEL")
keyevent("67")  # 67即为删除键，请注意传入的是字符串
```
模拟清空输入框操作:
```
for i in range(10):
    keyevent("67")
```

poco的删除（输入框置空）：

 `poco("xxx").set_text("")` 。

## log相关

### 如何记录log到报告中

`log()` 接口方便插入用户自定义的一些log信息，将会被显示在Airtest报告中。在1.1.6版本的Airtest中，log接口支持传入4个参数：
- `args` ，可以是字符串、非字符串或者 `traceback` 对象
- `timestamp` ，用于自定义当前log的时间戳
- `desc` ，用于自定义log的标题
- `snapshot` ，表示是否需要截取一张当前的屏幕图像并显示到报告中

示例如下：  
```
# 传入字符串
log("123",desc="这是标题01")

# 传入非字符串
data = {"test": 123, "time": 123456}
log(data,desc="这是标题02")

# 传入traceback
try:
    1/0
except Exception as e:
    log(e, desc="这是标题03")
    
# 记录timestamp，并且对当前画面截图
log("123", timestamp=time.time(), desc="这是标题04", snapshot=True)
```
### 如何设置log的保存路径

Airtest提供了一些全局的设置，其中 `LOGFILE` 用于自定义记录log内容的txt文档的名称；`LOGDIR` 用于自定义log内容的保存路径，示例如下：

```
from airtest.core.settings import Settings as ST
from airtest.core.helper import set_logdir

ST.LOG_FILE = "log123.txt"
set_logdir(r'D:\test\1234.air\logs')

auto_setup(__file__)

```

### 如何过滤不必要的log信息
在脚本代码开头加上 **对日志信息等级的设定**：

```
__author__ = "Airtest"

import logging
logger = logging.getLogger("airtest")
logger.setLevel(logging.ERROR)
```
把输出日志信息的级别改成 `[ERROR]` 以后，整个脚本运行过程中只有少量初始化信息输出，更方便查看报错信息。

## 报告

### 报告生成：simple_report()  

生成报告的简单接口：

```
simple_report(filepath, logpath=True, logfile='log.txt', output='log.html')
```

其中可传入的4个参数分别表示：

- `filepath`，脚本文件的路径，可以直接传入变量 `__file__` 
- `logpath` ，log内容所在路径，如为 `True` ，则默认去当前脚本所在路径找log内容
- `logfile` ，log.txt的文件路径
- `output` ，报告的到处路径，必须以 `.html` 结尾

示例如下：

```
from airtest.report.report import simple_report
auto_setup(__file__, logdir=True)

# 此处省略N条用例脚本

simple_report(__file__,logpath=True,logfile=r"D:\test\1234.air\log\log.txt",output=r"D:\test\1234.air\log\log1234.html")
```

### 报告生成：LogToHtml()

报告的基类：

```
class LogToHtml(script_root, log_root='', static_root='', export_dir=None, script_name='', logfile='log.txt', lang='en', plugins=None)
```

 `logtohtml` 类可以传入的参数非常多：

- `script_root` ，脚本路径
- `log_root` ，log文件的路径
- `static_root` ，部署静态资源的服务器路径
- `export_dir` ，导出报告的存放路径
- `script_name` ，脚本名称
- `logfile` ，log文件log.txt的路径
- `lang` ，报告的语言（中文：zh；英文：en）
- `plugins` ，插件，使用了poco或者airtest-selenium会用到

使用 `logtohtml` 生成测试报告时，我们一般先实例化一个 `logtohtml` 对象，然后用这个对象调用类方法 `report()` 生成报告，示例如下： 

```
from airtest.report.report import LogToHtml

# 此处省略N条用例脚本

h1 = LogToHtml(script_root=r'D:\test\1234.air', log_root=r"D:\test\1234.air\log", export_dir=r"D:\test\1234.air" ,logfile=r'D:\test\1234.air\log\log.txt', lang='en', plugins=["poco.utils.airtest.report"])
h1.report()
```

## 截图相关

### 如何用脚本截图
对目标设备进行一次截图，并且保存到文件中，可以传入截图文件名、截图的简短描述、截图压缩精度和截图最大尺寸，示例如下：

```
snapshot(filename="123.jpg",msg="首页截图",quality=90,max_size=800)
```

### 如何进行局部截图
局部截图或者说按坐标截图是大家经常会问到的问题，Airtest提供了 `crop_image(img, rect)` 方法可以帮助我们实现局部截图：   

```
# -*- encoding=utf8 -*-
__author__ = "AirtestProject"

from airtest.core.api import *
# crop_image()方法在airtest.aircv中，需要引入
from airtest.aircv import *

auto_setup(__file__)
screen = G.DEVICE.snapshot()

# 局部截图
screen = aircv.crop_image(screen,(0,160,1067,551))
# 保存局部截图到log文件夹中
try_log_screen(screen)
```
### 如何做局部识图

局部找图的步骤：
- 进行局部截图
- 定义要查找的目标截图对象
- 利用 `match_in` 方法，在局部截图中查找指定的截图对象
```
from airtest.core.api import *
from airtest.aircv import *
auto_setup(__file__)

screen = G.DEVICE.snapshot() 
# 局部截图
local_screen = aircv.crop_image(screen,(0,949,1067,1500))

# 将我们的目标截图设置为一个Template对象
tempalte = Template(r"png_code/设置.png")
# 在局部截图里面查找指定的图片对象
pos = tempalte.match_in(local_screen)

# 返回找到的图片对象的坐标（该坐标是相对于局部截图的坐标）
print(pos)

# 若要返回目标在整个屏幕中的坐标，则x，y都需要加上局部截图时设置的最小x、y
print(pos[0]+0,pos[1]+949)
```


### 如何设置报告的截图精度

`SNAPSHOT_QUALITY` 用于设置全局的截图压缩精度，默认值为10，取值范围[1,100]。示例如下：

```
from airtest.core.settings import Settings as ST

# 设置全局的截图精度为90
ST.SNAPSHOT_QUALITY = 90
```

定义单张截图的压缩精度，示例：

```
# 设置单张截图的压缩精度为90，其余未设置的将按照全局压缩精度来
snapshot(quality=90)
```


### 如何设置报告截图的最大尺寸

在Airtest1.1.6中，新增了一个用于指定截图最大尺寸的设置：`ST.IMAGE_MAXSIZE` 。假如设置为1200，则最后保存的截图长宽都不会超过1200，示例：

```
from airtest.core.settings import Settings as ST

# 设置全局截图尺寸不超过600*600，如果不设置，默认为原图尺寸
ST.IMAGE_MAXSIZE = 600

# 不单独设置的情况下，默认采用ST中的全局变量的数值，即600*600
snapshot(msg="test12")
# 设置单张截图的最大尺寸不超过1200*1200
snapshot(filename="test2.png", msg="test02", quality=90, max_size=1200) 
```

### 如何指定截图保存的路径和名称
对当前设备的屏幕进行截图，并将截图保存在自定义路径下，可以用下述方式实现：
```
screen = G.DEVICE.snapshot()  
pil_img = cv2_2_pil(screen)
pil_img.save(r"D:/test/首页.png", quality=99, optimize=True)
```

## 如何做断言

### 断言存在：assert_exists()

设备屏幕上存在断言目标，需要传入1个断言目标（截图）和在报告上显示的断言步骤信息，示例：

```
assert_exists(Template(r"tpl1607324047907.png", record_pos=(-0.382, 0.359), resolution=(1080, 1920)), "找到首页的天猫入口")  
```


### 断言不存在：assert_not_exists()

设备屏幕上不存在断言目标，与 `assert_exists()` 一样，需要传入1个断言目标（截图）和在报告上显示的断言步骤信息，示例：

```
assert_not_exists(Template(r"tpl1607325103087.png", record_pos=(-0.005, 0.356), resolution=(1080, 1920)), "当前页不存在天猫国际的icon")  
```


### 断言相等：assert_equal()

断言两个值相等，需要传入2个断言的值，还有将被记录在报告中的断言的简短描述：

```
assert_equal("实际值", "预测值", "请填写断言的简短描述")
```

常与poco获取属性的脚本一起做断言，示例如下：

```
assert_equal(poco("com.taobao.taobao:id/dx_root").get_text(), "天猫新品", "控件的text属性值为天猫新品")

assert_equal(str(poco(text="天猫新品").attr("enabled")), "True", "控件的enabled属性值为True")
```

### 断言不相等：assert_not_equal()
断言两个值不相等，与 `assert_equal()` 一样，需要传入2个断言的值，还有将被记录在报告中的断言的简短描述：

```
assert_not_equal("实际值", "预测值", "请填写断言的简短描述")

assert_not_equal("1", "2", "断言1和2不相等")
```

## 如何切换绝对坐标和相对坐标

用代码实现绝对坐标和相对坐标之间的切换：  
```
# 获取设备屏幕分辨率(竖屏)
height = G.DEVICE.display_info['height']
width = G.DEVICE.display_info['width']

# 已知绝对坐标[311,1065]，转换成相对坐标
x1 = 311/width
y1 = 1065/height
poco.click([x1,y1])

# 已知相对坐标[0.3,0.55]，转换成绝对坐标
x2 = 0.3*width
y2 = 0.55*height
touch([x2,y2])

# 如果是横屏设备的话，则分辨率如下
height = G.DEVICE.display_info['width']
width = G.DEVICE.display_info['height']
```

判断当前屏幕为横屏还是竖屏，并获取当前屏幕的分辨率：  

```
if G.DEVICE.display_info['orientation'] in [1,3]:
    height = G.DEVICE.display_info['width']
    width = G.DEVICE.display_info['height']
else:
    height = G.DEVICE.display_info['height']
    width = G.DEVICE.display_info['width']
```

## 如何调用别的.air脚本

如果想要在一个`.air` 脚本中，调用另外一个 `.air` 脚本里封装的公用函数，可以这样做:

```
from airtest.core.api import using
# 相对路径或绝对路径，确保代码能够找得到即可
using("common.air")

from common import common_function
common_function()
```

如果需要引用的子脚本路径统一都放在某个目录下，可以通过设定一个默认项目根目录 `PROJECT_ROOT` ，让使用 `using` 接口时能够在当前根目录下寻找别的子脚本，无需填写完整路径，让脚本之间相互调用使用更加方便。

例如，我们建立一个名为 `test1.air` 的脚本，实际路径为 `/User/test/project/test1.air` :

```
from airtest.core.api import *

def test():
    touch("tmp.png")
```

在同一目录下另外一个 `main.air` 脚本可以这样引用到它里面的 `test` :

```
from airtest.core.api import *

ST.PROJECT_ROOT = "/User/test/project"
using("test1.air")
from test1 import test
```

## 如何在脚本运行过程中录制屏幕

目前仅支持Android设备的录屏，请参见[在运行脚本过程中录屏](../device/android_zh.html#id13)

---

### Wiki Code Image Zh (`docs/wiki/code/image_zh.md`)

# 图像相关的问题


## 如何修改Airtest的图像识别算法
Airtest的全局设置中，`CVSTRATEGY` 用于设置Airtest的图像识别算法，默认情况下 `CVSTRATEGY = ["surf", "tpl", "brisk"]` ，每次查找图片的时候，airtest就会按照这个设置好的算法顺序去执行，直到找出一个符合设定阈值的识别结果，或者是一直按照这个算法顺序循环查找，直到超时。

我们可以自定义Airtest的图像识别算法，示例如下：

```
from airtest.core.settings import Settings as ST

ST.CVSTRATEGY = ["tpl", "sift","brisk"]
```
### 如何判断截图是否存在

检查当前设备画面上是否存在目标截图，常和判断语句一起使用，示例：

```
if exists(Template(r"tpl1606822430589.png", record_pos=(-0.006, 0.069), resolution=(1080, 1920)))
    touch(Template(r"tpl1606822430589.png", record_pos=(-0.006, 0.073), resolution=(1080, 1920)))  
```

### 如何等待某个截图目标出现
等待当前画面上出现某个匹配的 `Template` 图片，常用于等待某一张图片出来之后，再进行下一步操作，可以传入等待的超时时长、查找的时间间隔和首次尝试查找失败的回调函数，示例：

```
def test():
    print("未等待到目标")

wait(Template(r"tpl1606821804906.png", record_pos=(-0.036, -0.189), resolution=(1080, 1920)),timeout=120,interval=3,intervalfunc=test) 
```

## 如何设置图像查询的超时时长
在进行图像匹配时，会循环用几个算法去识别，但是循环识别并不是无限的，这里有一个查询的超时时长设置，一旦查询时间大于超时时长，还是未找到可信度大于阙值的结果，那就认定此次匹配失败，默认的超时时长如下：

```
FIND_TIMEOUT = 20
FIND_TIMEOUT_TMP = 3
```

使用 `FIND_TIMEOUT` 作为超时时长的接口有很多，比如：`assert_exists()`、`touch()`、`wait()`、`swipe()` 等。

而使用 `FIND_TIMEOUT_TMP` 作为超时时长的接口则比较少，比如：`assert_not_exists()`、`exists()` 等。

与阙值类似，我们既可以修改全局的超时时长，也可以设置单条语句的超时时长，示例如下：

```
from airtest.core.settings import Settings as ST

# 设置全局的超时时长为60s
ST.FIND_TIMEOUT = 60
ST.FIND_TIMEOUT_TMP = 60

# 设置单条wait语句的超时时长
wait(Template(r"tpl1607425650104.png", record_pos=(-0.044, -0.177), resolution=(1080, 1920)),timeout=120)
```

### 16.如何修改图像的阙值
`THRESHOLD` 和 `THRESHOLD_STRICT` 都是图像识别的阙值，Airtest1.1.6版本之后，所有用到了图像识别的接口，都是用 `THRESHOLD` 作为阙值。它的默认值为0.7，取值范围[0,1]。

在进行图像匹配时，只有当识别结果的可信度大于阙值时，才认为找到了匹配的结果。

除了可以修改全局的图像识别阙值，我们还支持修改单张图片的阙值，需要注意的是，如我们没有单独设置图像的阙值，将默认使用全局阙值 `THRESHOLD` ，示例如下：

```
from airtest.core.settings import Settings as ST

# 设置全局阙值为0.8
ST.THRESHOLD = 0.8

# 设置单张图片的阙值为0.9
touch(Template(r"tpl1607424190850.png", threshold=0.9, record_pos=(-0.394, -0.176), resolution=(1080, 1920)))
```

在Airtest1.1.6之前， `assert_exists` 使用的图像阙值 是 `THRESHOLD_STRICT` 。所以使用1.1.6之前版本的同学，想要修改 `assert_exists` 的图像阙值，需要设置  `THRESHOLD_STRICT` 的值。

---

### Wiki Device Android (`docs/wiki/device/android.md`)

# Android device connection methods and FAQs

[中文版](android_zh.md)

## Android phone connection

If use AirtestIDE to mobile phone connection, please refer to the [documents](https://airtest.doc.io.netease.com/en/IDEdocs/device_connection/1_android_phone_connection/)

If you're not going to use AirtestIDE, have a look at this statement:

- Opens the **developer options** on the phone, and **allows USB debugging** 
- After using USB to connect the phone, you can see the device using `adb devices` command and refer to [Use ADB to see if the phone is successfully connected](#use-adb-to-see-if-the-phone-is-successfully-connected) 
- On the code and command line, connect the phone with the phone`s serial number, see [Use the phone in your code](#use-the-phone-in-your-code) 


### Use ADB to see if the phone is successfully connected 

`adb` is the official Android command line tool for Google, which allows us to communicate with devices.(if you are interested, please refer to: [adb](https://developer.android.com/studio/command-line/adb).)

We have stored `adb` executables for each platform under `airtest\airtest\core\Android\static\adb` directory, you can use it without downloading.

Take Windows as an example, you can first use the terminal to enter the directory where `adb.exe` is located (in `airtest\airtest\core\Android\static\adb\Windows`, `shift+right click` to open the command line terminal), and then execute the command line of `adb devices` :

```
E:\airtest\airtest\core\android\static\adb\windows>adb devices

List of devices attached
c2b1c2a7        device
eba17551        device
127.0.0.1:10033 device
```

In MAC, you can visit `airtest/core/android/static/adb/mac` directory and run the `./adb devices`, if the adb no executable permissions, can run `chmod + x adb` add executable permissions for it.

- In the above example, you can see that the 3 Android devices currently connected, whose state is `device`, are normally online 
- If the device status is `UNAUTHORIZED`, click OK in the `ALLOW USB Debugging` menu that pops up over the phone 
- If you can't see the device name, you may need to install the phone's official driver on your PC 

### If your phone has a connection problem

Due to different mobile phone manufacturers and the corresponding model, may encounter all sorts of problems in the process of connecting, please refer to the link common problems [Android](https://airtest.doc.io.netease.com/en/IDEdocs/device_connection/2_android_faq/)

### Use the phone in your code 

After confirming that the phone can be successfully connected, we can see the device serial number of the phone in the command line of `adb devices` :

```
> adb devices 

List of devices attached
c2b1c2a7        device
```

The `c2B1c2A7` above is the device serial number of the mobile phone. We define a mobile phone with the following format string:

```
Android://<adbhost>:<adbport>/<serialno>
```

Among them:

- `adbhost` is the IP of the host where adb Server is located. By default, this is `localhost`or `127.0.0.1`
- `adb port` defaults to 5037
- `serialno` is the serial number of the Android phone, such as `c2B1c2a7` just now

Here are some examples:

```
# Will default to the first phone in the current connection if you fill in nothing 
Android:///
# A phone with c2B1C2a7 connected to the default port of the native 
Android://127.0.0.1:5037/c2b1c2a7
# Connect a remote device through ADB connect with the native ADB. Note that 10.254.60.1:5555 is actually Serialno 
Android://127.0.0.1:5037/10.254.60.1:5555
```

#### Connect the phone according to the `Android:///` string 

When we run a script from the command line, we can use `--device Android:///` to specify the Android device on which the script will run, for example:

```
>airtest run untitled.air --device Android:/// phone serial number --log log/
```

In addition, we can use the `connect_device` interface when we want to connect the phone in our code:

```
from airtest.core.api import *
connect_device("Android:///Phone Serial Number")
```

These two methods only need to choose one of them, basically can meet our needs to connect devices.


#### Some special parameters 

Some special devices may appear black screen when connected, such as some emulators, we can add an extra parameter `cap_method=JAVACAP` to force the screen capture mode to be `JAVACAP` :

```
# Connect the emulator and check the `Use Javacap` mode 
Android://127.0.0.1:5037/127.0.0.1:7555?cap_method=JAVACAP
```

In addition, we have two other parameters, `ori_method=ADBORI`, which specifies the rotation mode of the device screen, and `touch_method=ADBTOUCH`, which specifies the click mode of the screen as ADB instruction.

For the most part, we don't need to specify these parameters, and we only need to add additional parameters if some special Android devices (such as some special models of tablets) can`t connect with the default parameters:

```
# Check all the options to connect the device and use && to connect multiple parameter strings 
Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP&&ori_method=ADBORI&&touch_method=ADBTOUCH
```

Note: if any of the characters `^<>|&`appear on the command line, they may need to be escaped to take effect.

Therefore, if you need to write `&&` in the connection string, you need to rewrite it as `^&^&` in Windows, add a `^` symbol for escape, and add `\` for escape under MAC:

```
# -- device Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP&&ori_method=ADBORI is not available under Windows 
--device Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP^&^&ori_method=ADBORI # Windows command line add ^ escape effect
--device Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP\&\&ori_method=ADBORI # MAC command line add \ escape
```

## Android interface calls

All interfaces defined in `airtest.core.api` can be used on the Android platform and can be called directly in the script:

```
from airtest.core.api import *
touch((100, 200))
# Start an application 
start_app("org.cocos2d.blackjack")
# Pass in a key response 
keyevent("BACK")
```

Can refer to [airtest.core.api](https://airtest.readthedocs.io/zh_CN/latest/all_module/airtest.core.api.html) for the API list.


### Android device interface

In addition to the cross-platform interface provided in `airtest.core.api`, Android device objects have many built-in interfaces that can be called,We can [airtest core. Android. Android module](https://airtest.readthedocs.io/zh_CN/latest/all_module/airtest.core.android.android.html) in this document refer to the android device object has a method, and then call something like this:

```
dev = device() # gets the Android object to the current device
print(dev.get_display_info()) # to view the display information for the current device
print(dev.list_app()) # prints out the list of currently installed apps
```

### The ADB instruction call

Using the Android device interface, we can call adb directives like this:

```
# Execute the instruction ADB shell LS on the current device 
print(shell("ls"))

# Execute the ADB instruction for a specific device 
dev = connect_device("Android:///device1")
dev.shell("ls")

# Switch to a device and execute adb instruction 
set_current(0)
shell("ls")
```

## Frequently asked Questions about Android

### Android emulator connection

The simulator is connected in a similar way to the real machine. The following steps are required:

- Open developer options on the emulator and check to allow USB debugging. Some emulators may need to find `Settings - about the phone` multiple times before opening the developer options
- Use ADB to connect the corresponding port number, for example, enter `adb connect 127.0.0.1:62001`, where 7555 is the port number corresponding to the simulator, and each brand simulator is different 
- you can use the code `Android://127.0.0.1:5037/127.0.0.1:62001?cap_method=JAVACAP` connects to the corresponding emulator

Key points to note:

- Most emulators cannot connect with default parameters and must specify `cap_method=JAVACAP` 
- each brand simulator port can be refer to [Android emulator](https://airtest.doc.io.netease.com/en/IDEdocs/device_connection/3_emulator_connection/#2) 

### Slide continuously 

We provide some sliding interfaces to facilitate more complex operations:

```
dev = device()  # gets the current device
dev.pinch()  # Two fingers pinch or separate
dev.swipe_along([(100, 300), (300, 300), (100, 500), (300, 600)]) # continuously slides over a series of coordinates
dev.two_finger_swipe((100, 100), (200, 200))  # both fingers slip together
```

Among them, `swipe_along` can continuously streak through a series of coordinate points, which is the most commonly used interface.

### Custom slide 

In `airtest.core.android.touch_methods.base_touch`, defines four action events:

- `DownEvent(Coordinates, contact=0, pressure=50)` click
- `UpEvent(contact=0)` finger up
- `MoveEvent(coordinates, contact=0, pressure=50)` slide to a coordinate
- `SleepEvent` wait (seconds)

In the above four actions, the `contact` parameter defaults to 0, representing the first finger. If 1 is passed in, the action of the second finger can be defined, so that the complex operation of the double-finger can be achieved.

`pressure=50` defines the pressure when pressed and defaults to 50.

The `touch` interface, for example, is actually made up of `[DownEvent, SleepEvent, UpEvent]` actions, which in theory can be combined to allow you to customize very complex click-and-slide operations.


For example, here`s an example of a two-fingered tap on a screen:

```
from airtest.core.android.touch_methods.base_touch import *
# tap with two fingers
multitouch_event = [
     DownEvent((100, 100), 0),
     DownEvent((200, 200), 1),  # second finger
     SleepEvent(1),
     UpEvent(0), UpEvent(1)]

device().touch_proxy.perform(multitouch_event)
```

In the example code above, press the first finger at the coordinates of (100, 100), press the second finger at (200, 200), and wait for a second before lifting each finger.

Also, `MoveEvent` can be added to achieve more diversified operations, such as an ordinary `swipe` :

```
Swipe_event = [DownEvent((500, 500)), SleepEvent(0.1)]

for i in range(5):
     swipe_event.append(MoveEvent((500 + 100*i, 500 + 100*i)))
     Swipe_event. Append (SleepEvent (0.2))

swipe_event.append(UpEvent())

dev.touch_proxy.perform(swipe_event)
```

Based on this improvement, more complex operations can be achieved, such as long press 2 seconds - slide to a position:

```
from airtest.core.android.touch_methods.base_touch import *
dev = device()

# Long press delete application 
longtouch_event = [
     DownEvent([908, 892]),  # coordinates of the application to be deleted
     SleepEvent(2),
     MoveEvent([165,285]),  # delete the application's garbage can coordinates
     UpEvent(0)]

dev.touch_proxy.perform(longtouch_event)
```

More examples, please refer to the [airtest/playground/android_motionevents.py](https://github.com/AirtestProject/Airtest/blob/master/playground/android_motionevents.py).

#### Debug tips

You can switch on `settings-developer options-show input position` on your phone to debug simulated inputs.

### Record the screen while running the script 

Android phones support recording the screen while running the script. Add the `--recording` parameter to the command line of running the script:

```
airtest run "D:\test\Airtest_example.air"  --device android:/// --log logs/ --recording
```

After running, you can find the mp4 file recorded in the specified log directory.

- If only the `--recording` parameter has been passed, by default `recording_serialnumber.mp4` will be used to name the recording screen file 
- If the file name `--recording test.mp4` is specified and there is more than one phone, name it `serialnumber.mp4` 
- If you specify the filename `--recording test.mp4` and have only one phone, call it `test.mp4` 
- **Note that the file name passed in must end with mp4**
- The default screen recording file is up to 1800 seconds. If you need to record for a longer time, you need to manually call the screen recording interface in the code

If you call the screen recording interface in the code, you can control the clarity and duration of the screen recording. For the document, see [Android.start_recording](../../all_module/airtest.core.android.android.html#airtest.core.android.android.Android.start_recording).

For example, to record a 30-second video with the lowest definition and export it to `test.mp4` in the current directory:

```python
from airtest.core.api import connect_device, sleep
dev = connect_device("Android:///")
# Record the screen with the lowest quality
dev.start_recording(bit_rate_level=1)
sleep(30)
dev.stop_recording(output="test.mp4")
```

`bit_rate_level` is used to control the resolution of screen recording. The value range is 1-5. `bit_rate_level=5` has the highest resolution, but it will take up more hard disk space.

Or set the parameter `max_time=30`, the screen recording will automatically stop after 30 seconds:

```python
dev = device()
dev.start_recording(max_time=30, bit_rate_level=5)
dev.stop_recording(output="test_30s.mp4")
```

The default value of `max_time` is 1800 seconds, so the maximum screen recording time is half an hour, you can modify its value to get a longer screen recording:

```python
dev = device()
dev.start_recording(max_time=3600, bit_rate_level=5)
dev.stop_recording(output="test_hour.mp4")
```

## Refer to the tutorial and documentation for more 

- [Automated Testing on Android Phones-part 1](https://airtest.doc.io.netease.com/en/tutorial/4_Android_automated_testing_one/)
- [Android connection FAQ](https://airtest.doc.io.netease.com/en/IDEdocs/device_connection/2_android_faq/)

---

### Wiki Device Android Zh (`docs/wiki/device/android_zh.md`)

# Android设备连接方法与常见代码示例

[English version](android.md)

## Android手机连接

若使用AirtestIDE进行手机连接，请参考[文档](https://airtest.doc.io.netease.com/IDEdocs/device_connection/1_android_phone_connection/)

若不打算使用AirtestIDE，可以参考以下步骤：

- 打开手机中的 **开发者选项** , 以及 **允许USB调试**
- 使用USB连上手机后，能够使用`adb devices`命令看到设备，参考[使用ADB查看手机是否成功连接](#使用ADB查看手机是否成功连接)
- 在代码和命令行中，使用手机序列号连接手机，参见[在代码中使用手机](#在代码中使用手机)


### 使用ADB查看手机是否成功连接

`adb`是谷歌官方推出的Android命令行工具，可以让我们跟设备进行通信。（感兴趣的话，请参考：[官方地址](https://developer.android.com/studio/command-line/adb)。）

我们已经在`airtest\airtest\core\android\static\adb`目录下，存放了各平台的`adb`可执行文件，大家无需下载也可以使用。

以windows为例，可以先使用终端进入到`adb.exe`所在的目录下（在`airtest\airtest\core\android\static\adb\windows`目录下shift+右键打开命令行终端），然后执行`adb devices`命令行：

```
E:\airtest\airtest\core\android\static\adb\windows>adb devices

List of devices attached
c2b1c2a7        device
eba17551        device
127.0.0.1:10033 device
```

在mac中，可以访问`airtest/core/android/static/adb/mac`目录下，运行 `./adb devices`，若提示adb没有可执行权限，可以运行`chmod +x adb`为它添加可执行权限。

- 在上面这个例子中，可以看到当前连接的3台Android设备，状态为`device`就是正常在线
- 如果设备状态为`unauthorized`，请在手机上弹出的`允许USB调试`菜单中点击同意
- 如果看不到设备名称，可能需要在PC上安装手机对应的官方驱动

### 手机连接遇到问题

由于手机对应的厂商和型号各不相同，可能在连接过程中会遇到各种各样的问题，请参考[Android连接常见问题](https://airtest.doc.io.netease.com/IDEdocs/device_connection/2_android_faq/)

### 在代码中使用手机

确认手机能够成功连接后，我们能够在`adb devices`命令行的结果中看到手机的设备序列号：

```
> adb devices

List of devices attached
c2b1c2a7        device
```

上面的`c2b1c2a7`就是手机的设备序列号，我们用以下格式的字符串来定义一台手机：

```
Android://<adbhost>:<adbport>/<serialno>
```

其中：

- `adbhost`是adb server所在主机的ip，默认是本机，也就是`localhost`或`127.0.0.1`
- `adb port`默认是5037
- `serialno`是android手机的序列号，例如刚才的`c2b1c2a7`

以下是一些示例：

```
# 什么都不填写，会默认取当前连接中的第一台手机
Android:///
# 连接本机默认端口连的一台设备号为c2b1c2a7的手机
Android://127.0.0.1:5037/c2b1c2a7
# 用本机的adb连接一台adb connect过的远程设备，注意10.254.60.1:5555其实是serialno
Android://127.0.0.1:5037/10.254.60.1:5555
```

#### 根据Android:///字符串连接手机

当我们使用命令行运行脚本时，可以使用`--device Android:///`来为它指定脚本运行的Android设备，例如：

```
>airtest run untitled.air --device Android:///手机序列号 --log log/
```

除此之外，当我们想在代码里连接手机时，可以使用`connect_device`接口：

```
from airtest.core.api import *
connect_device("Android:///手机序列号")
```

这两种方式只需要选择其中一种，基本上都能满足我们连接设备的需求。


#### 一些特殊参数

部分特殊设备在连接时可能会出现黑屏的情况，例如一些模拟器，我们可以额外添加`cap_method=JAVACAP`的参数来强制指定屏幕截图方式为`JAVACAP`:

```
# 连接了模拟器，勾选了`Use javacap`模式
Android://127.0.0.1:5037/127.0.0.1:7555?cap_method=JAVACAP
```

除此之外，我们还有另外两个参数，分别是用于指定设备画面旋转模式的`ori_method=ADBORI`，以及指定点击画面方式为ADB指令点击的`touch_method=ADBTOUCH`。

大部分情况下，我们无需指定这些参数，只有在一些特殊的Android设备（例如部分特殊型号的平板）上，使用默认参数无法连接时，才需要加入额外的参数：

```
# 所有的选项都勾选上之后连接的设备，用&&来连接多个参数字符串
Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP&&ori_method=ADBORI&&touch_method=ADBTOUCH
```

注意：命令行中如果有出现 `^ < > | &` 这些字符，可能都需要转义才能生效。

因此如果连接字符串中需要写 `&&` 时，在windows下需要改写成 `^&^&` ，添加一个 `^` 符号进行转义，在mac下则需要添加`\`进行转义：

```
# --device Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP&&ori_method=ADBORI 在windows下不可用
--device Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP^&^&ori_method=ADBORI  # windows命令行添加^转义后效果
--device Android://127.0.0.1:5037/79d03fa?cap_method=JAVACAP\&\&ori_method=ADBORI  # mac命令行添加\转义
```

## Android接口调用

所有在`airtest.core.api`中定义的接口，都可以在Android平台上使用，直接在脚本中调用即可：

```
from airtest.core.api import *
touch((100, 200))
# 启动某个应用
start_app("org.cocos2d.blackjack")
# 传入某个按键响应
keyevent("BACK")
```

可以查阅[airtest.core.api](https://airtest.readthedocs.io/zh_CN/latest/all_module/airtest.core.api.html)文档获得API列表。


### Android设备接口

除了在airtest.core.api中提供的跨平台接口之外，Android设备对象还有很多内置的接口可以调用，我们可以在[airtest.core.android.android module](https://airtest.readthedocs.io/zh_CN/latest/all_module/airtest.core.android.android.html)这个文档中查阅到Android设备对象拥有的方法，然后像这样调用：

```
dev = device()  # 获取到当前设备的Android对象
print(dev.get_display_info())  # 查看当前设备的显示信息
print(dev.list_app())  # 打印出当前安装的app列表
```

### ADB指令调用

利用Android设备接口，我们可以这样调用adb指令：

```
# 对当前设备执行指令 adb shell ls
print(shell("ls"))

# 对特定设备执行adb指令
dev = connect_device("Android:///device1")
dev.shell("ls")

# 切换到某台设备，执行adb指令
set_current(0)
shell("ls")
```

## Android常见问题与代码示例

### Android模拟器连接

模拟器与真机的连接方式类似，需要进行以下步骤：

- 打开模拟器上的开发者选项，并勾选允许USB调试。部分模拟器可能需要找到 `设置-关于手机` 点击多次后才能打开开发者选项
- 使用adb连上对应的端口号，例如输入`adb connect 127.0.0.1:62001`，其中7555是模拟器对应的端口号，每个品牌模拟器不相同
- 可以使用代码`Android://127.0.0.1:5037/127.0.0.1:62001?cap_method=JAVACAP`连上对应的模拟器

注意要点：

- 大部分模拟器无法使用默认参数连接，必须要指定`cap_method=JAVACAP`
- 各品牌模拟器的端口可以查阅[Android模拟器连接](https://airtest.doc.io.netease.com/IDEdocs/device_connection/3_emulator_connection/#2)

### 连续滑动

我们提供了一些滑动方面的接口，方便大家进行更复杂的操作：

```
dev = device()  # 获取当前设备
dev.pinch()  # 双指捏合或分开
dev.swipe_along([(100, 300), (300, 300), (100, 500), (300, 600)])  # 连续滑过一系列坐标
dev.two_finger_swipe( (100, 100), (200, 200) )  # 两个手指一起滑动
```

其中，`swipe_along`可以连续不断地划过一系列坐标点，是最常用的一个接口。

### 自定义滑动

在`airtest.core.android.touch_methods.base_touch`中，定义了4个动作事件：

- `DownEvent(coordinates, contact=0, pressure=50)` 手指按下
- `UpEvent(contact=0)` 手指抬起
- `MoveEvent(coordinates, contact=0, pressure=50)` 滑动到某个坐标
- `SleepEvent(seconds)` 等待

上述4个动作中，`contact`参数默认为0，代表了第一根手指，如果传入1，就可以定义第二根手指的动作，这样就能实现双指的复杂操作了。

`pressure=50`定义了按下时的压力，默认为50。

例如`touch`接口，实际上是由`[DownEvent, SleepEvent, UpEvent]`三个动作组成的，理论上组合这些动作，能够自定义非常复杂的点击滑动操作。


例如这是一个双指轻点屏幕的例子：

```
from airtest.core.android.touch_methods.base_touch import *
# tap with two fingers
multitouch_event = [
    DownEvent((100, 100), 0),
    DownEvent((200, 200), 1),  # second finger
    SleepEvent(1),
    UpEvent(0), UpEvent(1)]

device().touch_proxy.perform(multitouch_event)
```

在上面的示例代码中，先在(100, 100)的坐标按下第一个手指，在(200, 200)按下第二个手指，等待一秒后再分别抬起两个手指。

还可以加入`MoveEvent`来实现更丰富的操作，例如一个普通的`swipe`是这样实现的：

```
swipe_event = [DownEvent((500, 500)), SleepEvent(0.1)]

for i in range(5):
    swipe_event.append(MoveEvent((500 + 100*i, 500 + 100*i)))
    swipe_event.append(SleepEvent(0.2))

swipe_event.append(UpEvent())

dev.touch_proxy.perform(swipe_event)
```

在此基础上进行改进，可以实现更多复杂操作，例如长按2秒-滑动到某个位置：

```
from airtest.core.android.touch_methods.base_touch import *
dev = device()

# 长按删除应用
longtouch_event = [
    DownEvent([908, 892]),  # 待删除应用的坐标
    SleepEvent(2),
    MoveEvent([165,285]),  # 删除应用的垃圾桶坐标
    UpEvent(0)]

dev.touch_proxy.perform(longtouch_event)
```

更多示例，请参考[airtest/playground/android_motionevents.py](https://github.com/AirtestProject/Airtest/blob/master/playground/android_motionevents.py)。

#### Debug tips

你可以打开`手机设置-开发者选项-显示触摸位置`来调试模拟输入的操作，这样做能看到每次点击的位置。


### 在运行脚本过程中录屏

Android手机支持在运行脚本过程中对屏幕进行录制，在运行脚本的命令行中加入`--recording`参数即可：

```
airtest run "D:\test\Airtest_example.air"  --device android:/// --log logs/ --recording
```

运行完毕后，可以在指定的log目录中找到录制完毕的mp4文件。

- 如果只传了`--recording`参数，默认将会使用`recording_手机序列号.mp4`来命名录屏文件
- 如果指定了文件名`--recording test.mp4`，且超过一台手机，就命名为 `手机序列号_test.mp4`
- 如果指定了文件名`--recording test.mp4`，且只有一台手机，就命名为 `test.mp4`
- **注意传入的文件名必须以mp4作为结尾**
- 默认录屏文件最长为1800秒，如果需要录制更长时间，需要手动在代码中调用录屏接口

如果在代码中调用录屏接口，能够控制录屏时的清晰度和时长，文档参见[Android.start_recording](../../all_module/airtest.core.android.android.html#airtest.core.android.android.Android.start_recording)。

例如，以最低清晰度录制一段30秒的视频，并导出到当前目录下的`test.mp4`：

```python
from airtest.core.api import connect_device, sleep
dev = connect_device("Android:///")
# Record the screen with the lowest quality
dev.start_recording(bit_rate_level=1)
sleep(30)
dev.stop_recording(output="test.mp4")
```

`bit_rate_level`用于控制录屏的清晰度，取值范围是1-5，`bit_rate_level=5`清晰度最高，但是占用的硬盘空间也会更大。

或者设置参数`max_time=30`，30秒后将自动停止录屏：

```python
dev = device()
dev.start_recording(max_time=30, bit_rate_level=5)
dev.stop_recording(output="test_30s.mp4")
```

`max_time`默认值为1800秒，所以录屏最大时长是半小时，可以修改它的值以获得更长时间的录屏：

```python
dev = device()
dev.start_recording(max_time=3600, bit_rate_level=5)
dev.stop_recording(output="test_hour.mp4")
```

## 更多参考教程和文档

- [如何在Android手机上进行自动化测试](https://airtest.doc.io.netease.com/tutorial/4_Android_automated_testing_one/)
- [Android连接常见问题](https://airtest.doc.io.netease.com/IDEdocs/device_connection/2_android_faq/)

---

### Wiki Device Device (`docs/wiki/device/device.rst`)

Device Connection
============================

.. toctree::

    platforms.md
    android.md
    android_zh.md

---

### Wiki Device Platforms (`docs/wiki/device/platforms.md`)

Supported Platforms 各平台支持情况
===================

## Overview



| Platforms                  | Airtest                                                      | Poco                                                         |
| -------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| Android                    | √                                                            | √                                                            |
| Emulator                   | √ [model list](#android-emulator)                            | √                                                            |
| iOS                        | √ [ios-Tagent](https://github.com/AirtestProject/iOS-Tagent) | [ios-tagent](https://github.com/AirtestProject/iOS-Tagent)   |
| Windows                    | √                                                            | Not yet                                                      |
| Cocos2dx-js & Cocos2dx-lua | √                                                            | √ [integration doc](https://poco.readthedocs.io/en/latest/source/doc/integration.html#cocos2dx-lua) |
| Unity3D                    | √                                                            | √ [integration doc](https://poco-chinese.readthedocs.io/en/latest/source/doc/integration.html#unity3d) |
| Egret                      | √                                                            | √ [integration doc](https://github.com/AirtestProject/Poco-SDK/tree/master/Egret) |
| WeChat Applet & Webview    | √                                                            | √ [tutorial](https://airtest.doc.io.netease.com/en/IDEdocs/poco_framework/poco_webview/) [中文版本](https://airtest.doc.io.netease.com/IDEdocs/poco_framework/poco_webview/) |
| Netease engines            | √                                                            | √ [tutorial](http://git-qa.gz.netease.com/maki/netease-ide-plugin) |
| Other engines              | √                                                            | √ [implementation doc](https://poco-chinese.readthedocs.io/en/latest/source/doc/implementation_guide.html) |



## Android

Currently we are compatible with **most Android phones** (2.3 <= Android <= 11) on the market, and a few special Android tablets and devices.

- If you encounter problems during the connection, please refer to the device settings of this document according to the different mobile phone manufacturers: [Some manufacturer’s device special problems](https://airtest.doc.io.netease.com/en/IDEdocs/device_connection/2_android_faq/#2)
- For MIUI 11 or above of Xiaomi mobile phone, please use `cap_method=JAVACAP` mode to connect to the phone

目前我们兼容市面上**绝大多数的Android手机**（2.3 <= Android <= 11），和少数特殊Android平板和设备。

- 如果在连接中遇到问题，请根据手机厂商的不同，查看此文档的设备设置：[部分厂商设备特殊问题](https://airtest.doc.io.netease.com/IDEdocs/device_connection/2_android_faq/#2)
- 小米手机的MIUI 11 以上版本，请使用`cap_method=JAVACAP`模式连接手机



## Android Emulator 模拟器

The following emulators have been verified, [Android Emulator Connection Guidelines](https://airtest.doc.io.netease.com/en/IDEdocs/device_connection/3_emulator_connection/)

下列模拟器都经过验证，[Android模拟器连接指引](https://airtest.doc.io.netease.com/IDEdocs/device_connection/3_emulator_connection/)

*	[夜神 Nox](https://www.yeshen.com/)
*	[网易Mumu](https://mumu.163.com/)
*	[逍遥 Memuplay](https://www.xyaz.cn/)	
*	[iTools](https://pro.itools.cn/itools1)
*	[腾讯手游助手](http://www.ttmnq.com/)	
*	[BlueStacks](https://www.bluestacks.com/)
*	AVD

附录：我们对[常见模拟器版本的适配情况](https://juejin.cn/post/6844904194118254599)测试（2020.06，随着版本更新可能失效）



## iOS

According to [iOS-Tagent](https://github.com/AirtestProject/iOS-Tagent) document, the current support situation:

以[iOS-Tagent](https://github.com/AirtestProject/iOS-Tagent)文档为准，目前的支持情况：

| xcode   | iOS    |
| ------- | ------ |
| <= 11.5 | <=13.5 |

---

--- METRICS ---
- Files Extracted: 75
- Estimated Token Budget: ~24552 tokens
- Canonical Reference: https://codewiki.google/github.com/AirtestProject/Airtest
