以下基於
python3.8;airtestIDE1.2.11;airtest1.2.2;pocoui1.0.83
之前我們都是在AirtestIDE里運行腳本,但如果用在工作中,大批量用例運行、並行運行、定時或集成Jenkins運行,就要用到命令行運行了。
想要用命令運行,必須要裝獨立於AirtestIDE的Python環境,還沒裝的可以看下之前的文章Airtest之python本地環境安裝、獨立IDE運行
裝好環境之后,在命令行中輸入airtest run -h
,如果出現下圖,就表示安裝成功了
如果你是Windows且提示沒有airtest run這個命令,那就是你python的環境變量沒配好,網上搜一下配好環境變量。實在不行,試試python -m airtest run -h
先給出一個完整示例大家有個印象:
airtest run "D:\qasite.air" --device "android://127.0.0.1:5037/65fade15?cap_method=JAVACAP&&ori_method=MINICAPORI&&touch_method=MINITOUCH"
--log "D:\log" --compress 90 --recording qasite.mp4
在解說參數之前,我先放上之前的各個平台連接AirtestIDE的文章,里面的內容都是基礎:
AirtestIDE連接安卓真機及常見問題
airtestIDE連接模擬器及常見問題
airtest之使用tidevice工具輕松連接iOS
Airtest連接Windows窗口(應用)
參數說明:
-
腳本路徑:airtest run命令后緊跟的第1個參數是腳本的絕對路徑,當然你也可以用相對路徑,但為了避免路徑層級搞亂,我還是推薦大家用絕對路徑,簡單明了。路徑用雙引號包住,防止因為特殊符號報錯
-
--device參數后跟的是設備連接字符串,用雙引號包住。以上面例子進行說明:
①android表示連的是安卓手機。
②127.0.0.1:5037表示連接的是本機的5037端口,如果你要連遠程服務器的真機,就寫對應的IP和端口。如果不寫,則默認是本機的5037。
③65fade15表示手機序列號,安卓通過adb devices
獲取。
④cap_method=JAVACAP&&ori_method=MINICAPORI&&touch_method=MINITOUCH表示了幾個連接的特殊參數,一般這些參數全部不用寫,Airtest會自動適配,除非模擬器或個別手機連接有問題時才用,具體使用看上面的連接文章吧。
設備連接字符串URI示例:
# 什么都不寫,連接第一台安卓手機
"android:///"
# 連接65fade15這台安卓(推薦寫法)
"android:///65fade15"
# 連接一台模擬器,並指定參數。其中127.0.0.1:62001是模擬器的序列號
"Android://127.0.0.1:5037/127.0.0.1:62001?cap_method=JAVACAP&&ori_method=MINICAPORI&&touch_method=MINITOUCH"
# 通過tidevice連接ios手機,'07bbb06a267ee'是UDID,通過`tidevice info`獲取,具體看上面tidevice文章連接
"ios:///http+usbmux://07bbb06a267ee"
# 連接整個windows桌面
"Windows:///"
# 連接匹配的窗口名稱正則
"Windows:///?title_re=.*記事本.*"
- --log表示運行過程中日志和截圖存放路徑,注意事項同第1個參數腳本路徑。如果不寫這個參數,可以運行,但不記錄日志,無法生成報告。
-
--compress表示運行過程中截圖的質量,從1-99,數字越小,截圖越模糊,但圖片大小越小,可不寫,默認為10
-
--recording表示將運行過程錄屏,'qasite.mp4'表示錄屏文件名,不寫會有默認文件名,錄屏僅支持安卓平台
-
--no-image參數表示運行過程中不再截圖,這樣生成報告后就不會有截圖。與'--compress'參數互斥。我個人推薦最好還是要截圖,這樣生成報告后可以看到運行的整個過程。
看完上面如果你還是不會寫,可以在AirtestIDE里先運行,然后復制日志第一行的命令,再自己修改一下
源碼解析
我們看看運行命令之后,代碼到底是如何流轉的
# 文件位置:your_python_path/site-packages/airtest/__main__.py # -*- coding: utf-8 -*- from airtest.cli.__main__ import main if __name__ == '__main__': main()
命令行運行airtest后,首先進入到這里,可以看是調用了airtest.cli.__main__
中的 main()方法,進入查看:
# 文件位置:your_python_path/site-packages/airtest/cli/__main__.py # -*- coding: utf-8 -*- from airtest.cli.parser import get_parser def main(argv=None): ap = get_parser() args = ap.parse_args(argv) if args.action == "info": from airtest.cli.info import get_script_info print(get_script_info(args.script)) elif args.action == "report": from airtest.report.report import main as report_main report_main(args) elif args.action == "run": from airtest.cli.runner import run_script run_script(args) elif args.action == "version": from airtest.utils.version import show_version show_version() else: ap.print_help() if __name__ == '__main__': main()
(1)首先ap = get_parser()
獲取參數
(2)其次args = ap.parse_args(argv)
對參數進行正確性檢查
(3)最后根據具體的命令執行不同邏輯,我們可以看到一共有4個子命令:
1.airtest info
獲取腳本信息(目前沒發現這個功能有啥實際用處,具體可以查看官方文檔);
2.airtest report
生成報告;
3.airtest run
運行腳本,執行了run_script(args)
;
4.airtest version
打印版本號;
5.如果都沒匹配上,則輸入幫助命令
下面分別看下(1)(2)(3)的源碼:
(1)ap = get_parser()
# 文件位置:your_python_path/site-packages/airtest/cli/parser.py # -*- coding: utf-8 -*- import argparse import sys from airtest.report.report import get_parger as report_parser from airtest.cli.runner import setup_by_args def get_parser(): ap = argparse.ArgumentParser() subparsers = ap.add_subparsers(dest="action", help="version/run/info/report") # subparser version subparsers.add_parser("version", help="show version and exit") # subparser run ap_run = subparsers.add_parser("run", help="run script") runner_parser(ap_run) # subparser info ap_info = subparsers.add_parser("info", help="get & print author/title/desc info of script") ap_info.add_argument("script", help="script filename") # subparser report ap_report = subparsers.add_parser("report", help="generate report of script") report_parser(ap_report) return ap def runner_parser(ap=None): if not ap: ap = argparse.ArgumentParser() ap.add_argument("script", help="air path") ap.add_argument("--device", help="connect dev by uri string, e.g. Android:///", nargs="?", action="append") ap.add_argument("--log", help="set log dir, default to be script dir", nargs="?", const=True) ap.add_argument("--compress", required=False, type=int, choices=range(1, 100), help="set snapshot quality, 1-99", default=10) ap.add_argument("--recording", help="record screen when running", nargs="?", const=True) ap.add_argument("--no-image", help="Do not save screenshots", nargs="?", const=True) return ap
可以看到Airtest也是用了argparse這個命令行的庫,在'run'時,執行了runner_parser(ap_run)
runner_parser()
則是airtest run
命令的具體參數設定
(2)args = ap.parse_args(argv)
# 文件位置:your_python_path/site-packages/airtest/Lib/argparse.py # ===================================== # Command line argument parsing methods # ===================================== def parse_args(self, args=None, namespace=None): args, argv = self.parse_known_args(args, namespace) if argv: msg = _('unrecognized arguments: %s') self.error(msg % ' '.join(argv)) return args
參數檢查,如果你把參數輸錯了或者輸入了一個不存在的參數,則會提示'unrecognized arguments',你可以自己隨便加一個參數運行試試看,比如airtest run --gongzhonghao qasite
(3)run_script(args)
# 文件位置:your_python_path/site-packages/airtest/cli/runner.py def run_script(parsed_args, testcase_cls=AirtestCase): global args # make it global deliberately to be used in AirtestCase & test scripts args = parsed_args suite = unittest.TestSuite() suite.addTest(testcase_cls()) result = unittest.TextTestRunner(verbosity=0).run(suite) if not result.wasSuccessful(): sys.exit(-1)
用過unittest的同學對這個肯定不會陌生,這里就是調用unittest運行用例。
入參中的AirtestCase
就是基於unittest二次封裝的類,感興趣的同學可以自己看看/airtest/cli/runner.py
以上就是命令大體的一個運行過程。
---------------------------------------------------------------------------------
關注微信公眾號即可在手機上查閱,並可接收更多測試分享~