自动测试框架

../_images/autotest.jpg

ArduPilot 的 AutoTest 套件允许创建可重复的测试,有助于防止 ArduPilot 行为出现倒退。它基于 ArduPilot 的 SITL 架构,即完全基于软件的解决方案。

使用 ArduPilot 的自动测试功能:

  • 减少重复运行相同场景所花费的时间,从而提高开发流程的效率。 sim_vehicle.py

  • 允许您反复复制 ArduPilot 中的不良行为,并可能将该测试交付给有能力解决问题的开发人员("测试驱动开发)

  • 通过锁定对 ArduPilot 行为的测试,减少 ArduPilot 行为回归的机会

概述

自动测试套件在 ArduPilot 的自动测试服务器上运行,大部分提交到主分支,但也可在本地运行,以审核软件更改。添加测试非常简单,我们鼓励通过测试来展示补丁如何改善飞行行为。

运行自动测试

警告

不要在不带参数的情况下运行 autotest.py,除非你知道自己在做什么,或者喜欢收拾烂摊子。

AutoTest 需要有效的 SITL 环境才能运行。使用 SITL 指令 (SITL)来获取有效环境。建议使用 ArduPilot Vagrant 虚拟机配置文件来获取工作环境。

致词

备注

运行自动测试时 --加速 可能会导致足够多的网络流量,以至于 MAVProxy 无法跟上。诸如 "设置 RC 超时 "或飞行器进入 GCS 故障保护等错误就是典型的故障。重新运行通常可以使测试通过。减少 --加速 系数通常足以避免这个问题。

可提供帮助:

pbarker@bluebottle:~/rc/ardupilot(master)$ ./Tools/autotest/autotest.py --helpUsage: autotest 选项:-h、--help 显示帮助信息并退出 --skip=SKIP 跳过的步骤列表(逗号分隔) --list 列出可用的步骤 --viewerip=VIEWERIP 发送 MAVLink 和 fg 数据包的 IP 地址 --map 显示地图 --experimental 启用实验性测试 --timeout=TIMEOUT 以秒为单位的最长运行时间 --frame=FRAME 指定帧类型 --show-test-timings 显示每个测试的运行时间 构建选项:--no-configure在构建前不配置 --waf-configure-args=WAF_CONFIGURE_ARGS在configure中传递给waf的额外参数 -j J构建CPU --no-clean在构建前不清理 --debug使构建的二进制文件调试二进制文件 模拟选项:--speedup=SPEEDUP 模拟运行速度 --valgrind 在 valgrind 下运行 ArduPilot 二进制文件 --gdb 在 gdb 下运行 ArduPilot 二进制文件 --gdbserver 在 gdbserver 下运行 ArduPilot 二进制文件 -B BREAKPOINT, --breakpoint=BREAKPOINT 在调试器中的指定位置添加断点 pbarker@bluebottle:~/rc/ardupilot(master)$

autotest.py 会调用一系列 "步骤",这些步骤将按顺序执行:

./工具/自动测试/自动测试.py 构建.旋翼飞行器 测试.旋翼飞行器

该命令在 ArduPilot 签出的根目录下有效。它指示 AutoTest 构建 ArduCopter SITL 二进制文件,启动该二进制文件,对其进行测试,然后将其杀死。输出 (样品)非常啰嗦,但所有步骤运行完毕后都会给出摘要。

备注

旧版本 autotest.py 使用这些步骤:

构建.ArduPlane 构建.ArduCopter 构建.APMrover2 构建.ArduSub 构建.天线跟踪器 苍蝇.ArduCopter 苍蝇.ArduPlane 苍蝇.垂直起降 跳水.ArduSub 驾驶.APMrover2 驾驶.平衡机器人 驾驶.平衡器 苍蝇.CopterAVC

备注

--列表 :列出可用步骤(构建、测试、默认设置、示例)

备注

"这款" --无清洁 选项可以大大缩短开发周期

备注

开发测试时,请考虑省略 "构建 "步骤,除非您要更改 ArduPilot 代码。

复杂调用

./工具/自动测试/自动测试.py --没有-清洗 构建.旋翼飞行器 测试.旋翼飞行器 构建.无人车UGV 测试.无人车UGV 测试.平衡机器人 构建.固定翼飞行器 测试.固定翼飞行器 测试.垂直起降 构建.潜航器 测试.潜航器 构建.旋翼飞行器 测试.旋翼飞行器 构建.跟踪器 测试.跟踪器

在编写本报告时,这些测试将调用所有载具测试。预计运行时间约为 40 分钟。

运行特定子测试

要运行特定的子测试,只需在测试名称和子测试名称之间添加带".

./工具/自动测试/自动测试.py 构建.固定翼飞行器 测试.固定翼飞行器.节流阀故障安全

与 GDB 一起使用

AutoTest 可以在 gdb 下运行 ArduPilot 二进制程序:

./工具/自动测试/自动测试.py --没有-清洗 --gdb --排错 构建.旋翼飞行器 测试.旋翼飞行器

在 X 窗口系统环境中,xterm 窗口将包含 GDB 终端;ArduPilot 二进制程序的 stderr 也将显示在该窗口中。在 X 不可用但 GNU 屏幕 则会创建一个具有相同内容的独立屏幕。

您可以在命令行上插入断点(多次使用可插入多个断点):

./工具/自动测试/自动测试.py --没有-清洗 --gdb --排错 -B 旋翼飞行器::更新 构建.旋翼飞行器 测试.旋翼飞行器

您可以在测试中插入 Python 方法调用,使(飞行)控制器进入附加调试器:

自我.发送调试陷阱()

该功能与 --禁用断点 命令行选项,因为可以在发送调试陷阱时启用断点。

与 Valgrind 一起使用

AutoTest 可以在 Valgrind memcheck 工具下运行 ArduPilot 二进制程序。这对于发现读取未初始化内存等情况非常有用。

警告

ArduPilot 通过重载 功能。某些版本的 Valgrind 无法理解这一点。所提供的 xenial32 Vagrant 虚拟机包含的 Valgrind 版本不会出现这个问题。

./工具/自动测试/自动测试.py --没有-清洗 --谷粒 --排错 构建.无人车UGV 测试.无人车UGV

特殊日志文件(如 arducopter-+-valgrind.log) 会在使用该工具运行时由自动测试创建。在自动测试运行结束时,它们应始终为空。

提取结果

自动测试运行后,会提供多个日志文件。

登录 autotest.py的 stdout 是显而易见的!

DataFlash 文件位于 "日志 "目录下:

pbarker@bluebottle:~/rc/ardupilot(master)$ ls -lt logs total 21356 -rw-r--r-- 1 pbarker pbarker 8474624 Jul 27 12:07 00000003.BIN -rw-r--r-- 1 pbarker pbarker 3 Jul 27 12:06 LASTLOG.TXT -rw-r--r-- 1 pbarker pbarker 13307904 Jul 27 12:06 00000002.BIN -rw-r--r-- 1 pbarker pbarker 73728 Jul 27 12:05 00000001.BIN pbarker@bluebottle:~/rc/ardupilot(master)$

MAVLink 遥测日志位于 "buildlogs "目录下。该目录通常比 ArduPilot 根目录高一级。

pbarker@bluebottle:~/rc/ardupilot(master)$ ls -l ../buildlogs/*tlog -rw-r--r-- 2 pbarker pbarker 2541216 Jul 27 12:11 ../buildlogs/Rover-test.tlog pbarker@bluebottle:~/rc/ardupilot(master)$

备注

在 Vagrant 虚拟机上,ArduPilot 根目录挂载在 /vagrant 上。vagrant "用户没有权限在"/"下创建 "buildlogs "目录,因此buildlogs目录出现在/tmp/buildlogs下

警告

并非所有参与测试的 MAVLink 流量都会出现在 buildlogs tlog 文件中。只有进出 MAVProxy 本身的流量(相对于额外的 MAVProxy 输出)才会出现。更多信息请参阅 AutoTest Structure(自动测试结构)。

输出文件与自动测试服务器的相关性

ArduPilot 的自动测试服务器 显示最近一次自动测试运行的结果。如果自动测试服务器上的测试失败,可以使用 autotest.py

AutoTest 的 "测试结果 "部分反映了 autotest.py的返回值。

AutoTest 的 "测试日志 "部分反映了 buildlogs 目录的内容。

可以使用 "convertgpx "步骤创建 AutoTest "飞行轨迹 "部分的图像。

自动测试结构

文件结构

Tools/autotest/autotest.py

自动测试套件的主要入口

Tools/autotest/antennatracker.py

包含天线跟踪器的测试

Tools/autotest/arducopter.py

包含多旋翼和旋翼飞行器形式的 ArduCopter 测试

Tools/autotest/rover.py

包含 ArduRover 的测试

Tools/autotest/ardusub.py

包含 ArduSub 的测试

Tools/autotest/arduplane.py

包含 ArduPlane 的测试

Tools/autotest/balancebot.py

包含对平衡机器人/自平衡机器人的测试

Tools/autotest/quadplane.py

包含对 ArduPlane 的 QuadPlane 代码的测试

Tools/autotest/pysim/util.py

AutoTest 使用的各种实用功能

Tools/autotest/vehicle_test_suite.py

包含一个基类,由每辆车测试例程继承

网络结构

AutoTest 网络管道非常复杂。

从测试的角度来看:

self.mavproxy

用于与 MAVProxy 进程交互的 pexpect 对象。所有 MAVProxy 命令在发送到该对象时都有效,例如 设置 噪音 0.这并非总是可用--如果测试需要 MAVProxy,则应使用 self.start_mavproxy() 和 self.stop_mavproxy()。

self.mav

连接到模拟的主输出端口(通常为 TCP 5760 端口)的 mavudp 对象。

self.mav.mav

mavudp 的 MAVLink 对象。可用于通过 MAVLink 向 SITL 二进制程序发送信息: self.mav.mav.system_time_send(time.time() * 1000000, 0)

遥控重写

测试呼吁 self.set_rc(ch、 值) 有效设置了模拟载具的 RC 输入。需要注意的是,这些并不是 "RC 覆盖",而是 "真正的 "模拟 RC 输入。SITL 二进制程序通过网络端口监听代表 RC 输入的 8 位或 16 位数据包。在调用 MAVProxy 时,本应作为 MAVLink RC 覆盖数据包发送的数据会被传送到该网络端口。

添加测试

备注

自动测试脚本在不断变化。本文档可能已经过时。

git commit 是向 ArduPilot 套件添加全新测试的一个合理示例。

使用自动测试进行自动 git 分叉

Tools/autotest/bisect-helper.py 的脚本参数。 git 横切 运行.它可以按名称运行自动测试测试,并告诉你是哪个提交破坏了该测试。

为了实现这一目标

  • 确保你还没有运行 bisect - git 横切 重置

  • 为您的新测试(基于主测试)创建一个主题分支,该测试现在失败了,但您知道它在过去的某个阶段会通过的

  • 编写你的测试--在你的主题分支上应该会失败,然后提交

  • 你可以在过去的某个阶段创建一个分支,然后将你的测试选入该分支来测试你的分支。这可能并非易事,这取决于自动测试框架做了哪些修改

  • cp Tools/autotest/bisect-helper.py /tmp # 始终使用现代助手

  • git 横切 重置

  • git 横切 启动

  • git 横切 坏的 - 我们知道测试失败的地方写着

  • git 横切 HEAD~1024 - 这时我们就知道测试通过了

  • 时间 git 横切 运行 /tmp/bisect-helper.py --自动测试 --自动驾驶载具=飞机 --自动测试--测试=NeedEKFToArm --autotest-branch=wip/bisection-using-named-test

在最后一条命令中,您需要指定载具、新测试名称和包含新测试的主题分支名称。

运行之后,您就能知道是哪个提交破坏了正在测试的功能。此外,您还可以为回归套件创建一个新测试,并将其提交!

与 callgrind / kcachegrind 一起使用

Valgrind 实际上是一个工具集合,主要与 "memcheck "工具一起使用,用于查找内存读写问题。

Valgrind 的 callgrind 工具允许进行性能分析。autotest.py 内置支持在 callgrind 下运行 ArduPilot。

pbarker@bluebottle:~/rc/ardupilot(tmp/kcachegrind)$ ./Tools/autotest/autotest.py build.Copter lckfile='/home/pbarker/rc/buildlogs/autotest.lck' step=build.Copter 正在运行:("git rev-parse HEAD") in (/home/pbarker/rc/ardupilot) .. bin/arducopter 4795907 173448 172104 5141459 构建命令将存储在 build/sitl/compile_commands.json 'build' 成功完成 (15.974s) pbarker@bluebottle:~/rc/ardupilot(tmp/kcachegrind)$ rm callgrind.out.* pbarker@bluebottle:~/rc/ardupilot(tmp/kcachegrind)$ ./Tools/autotest/autotest.py --callgrind test.Copter.Callisto lckfile='/home/pbarker/rc/buildlogs/autotest.lck' step=test.Copter.AT-0368.6: Stopping SITL >>>> PASSED STEP: test.Copter.Callisto at Tue Nov 30 08:55:20 2021 pbarker@bluebottle:~/rc/ardupilot(tmp/kcachegrind)$ kcachegrind
./_images/kcachegrind.png