UI 自动化测试应用与实践
一、知识梳理
- 单元测试: 单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。(开源框架常用)
- 集成测试: 在单元测试的基础上,将所有模块按照设计要求组装成为子系统或系统,进行集成测试。
- 验收测试: α测试 === development β测试 === preview γ测试 === production。
- 白盒测试:又称结构测试、透明盒测试,测试方法有代码检查法、静态结构分析法。(TS、Eslint、Sonar)
- 黑盒测试:又称功能测试,再不考虑内部结构的前提下测试产品功能。(测试组:80%)
- 静态测试: 通过分析软件的代码、设计、文档和配置而不执行软件来测试软件的过程。(接口测试)
- 动态测试: 使用各种输入和场景执行软件并检查其行为和输出来测试软件的过程。(UI 测试)
二、UI 自动化测试 - 意义
- 它可以帮助我们提高软件质量、减少人工测试的工作量,提高测试效率。
- 通过自动化测试,我们可以快速、准确地检测软件界面的各种功能和交互,发现潜在的问题和缺陷,确保软件在不同环境下的稳定性和一致性。
- UI自动化测试还可以提供可靠的回归测试,确保软件在不断迭代更新中不会引入新的问题。总之,UI自动化测试是保障软件质量和用户体验的重要手段,对于提高开发效率和降低风险非常有帮助。
三、UI 自动化测试 - 三板斧
名称 | 简介 | 应用解读 |
---|---|---|
Selenium | Selenium 是最受欢迎的UI自动化测试框架之一,支持多种编程语言,如Java、Python和C#。它可以模拟用户在网页上的操作,执行各种测试任务。 | Appium 目标的一个子集,Selenium 与各个 Web 浏览器供应商和W3C 标准组织合作,将其 API 变成了官方的 Web 浏览器标准,称为WebDriver 规范。 |
Appium | Appium是一个开源的UI自动化测试框架,专门用于移动应用程序的测试。它支持多种移动平台,如iOS和Android,并提供跨平台的测试能力。 | 基于WebDriver 规范打造统一平台化能力,不仅仅支持iOS 和 Android,Appium 希望支持用户交互从 Web 到移动设备或从 Web 到电视不同的情况,提供了驱动的概念。 |
Cypress | Cypress是一个现代化的JavaScript前端测试框架,旨在对Web应用程序进行端到端的自动化测试。它具有简单易用的API和强大的调试功能。 | Cypress 不是基于 WebDriver 开发的,Cypress 使用自己的架构和协议来直接与浏览器交互,而不是通过 WebDriver 接口,Cypress 更适合用于前端端到端测试,而 WebDriver/Selenium WebDriver 更适合用于跨浏览器和跨平台的 Web 应用程序测试。 |
下图来源于 Appium:
三、UI Automator
UI Automator 测试框架提供了一组 API,用于构建在用户应用和系统应用上执行交互的界面测试。通过 UI Automator API。
# uiautomatorviewer bash 位置
cd ~/Library/Android/sdk/tools/bin
1. uiautomatorviewer-xx.x.x-dev.jar
/Library/Android/sdk/tools/lib
#!/bin/bash
1. 1. Copyright 2012, The Android Open Source Project
1. 1. Licensed under the Apache License, Version 2.0 (the "License");
1. you may not use this file except in compliance with the License.
1. You may obtain a copy of the License at
1. 1. http://www.apache.org/licenses/LICENSE-2.0
1. 1. Unless required by applicable law or agreed to in writing, software
1. distributed under the License is distributed on an "AS IS" BASIS,
1. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1. See the License for the specific language governing permissions and
1. limitations under the License.
1. Set up prog to be the path of this script, including following symlinks,
1. and set up progdir to be the fully-qualified pathname of its directory.
prog=" $0"
while [ -h "${prog}" ]; do
newProg=`/bin/ls -ld "${prog}"`
newProg=`expr "${newProg}" : ".* -> (.*)$"`
if expr "x${newProg}" : 'x/' >/dev/null; then
prog="${newProg}"
else
progdir=`dirname "${prog}"`
prog="${progdir}/${newProg}"
fi
done
oldwd=`pwd`
progdir=`dirname "${prog}"`
progname=`basename "${prog}"`
cd "${progdir}/.."
progdir=`pwd`
prog="${progdir}"/bin/"${progname}"
cd "${oldwd}"
jarfile=`basename $APP_HOME/lib/uiautomatorviewer-26.0.0-dev.jar`
frameworkdir="$progdir"
libdir="$progdir"
if [ ! -r "$frameworkdir/$jarfile" ]
then
frameworkdir=`dirname "$progdir"`/tools/lib
libdir=`dirname "$progdir"`/tools/lib
fi
if [ ! -r "$frameworkdir/$jarfile" ]
then
frameworkdir=`dirname "$progdir"`/framework
libdir=`dirname "$progdir"`/lib
fi
if [ ! -r "$frameworkdir/$jarfile" ]
then
echo "${progname}: can't find $jarfile"
exit 1
fi
javaCmd="java"
os=`uname`
if [ $os == 'Darwin' ]; then
javaOpts="-Xmx1600M -XstartOnFirstThread"
else
javaOpts="-Xmx1600M"
fi
if [ `uname` = "Linux" ]; then
export GDK_NATIVE_WINDOWS=true
fi
while expr "x $1" : 'x-J' >/dev/null; do
opt=`expr "x $1" : 'x-J(.*)'`
javaOpts="${javaOpts} -${opt}"
shift
done
jarpath="$frameworkdir/$jarfile"
1. Figure out the path to the swt.jar for the current architecture.
1. if ANDROID_SWT is defined, then just use this.
1. else, if running in the Android source tree, then look for the correct swt folder in prebuilt
1. else, look for the correct swt folder in the SDK under tools/lib/
swtpath=""
if [ -n "$ANDROID_SWT" ]; then
swtpath="$ANDROID_SWT"
else
vmarch=`"${progdir}"/bin/archquery`
if [ -n "$ANDROID_BUILD_TOP" ]; then
osname=`uname -s | tr A-Z a-z`
swtpath="${ANDROID_BUILD_TOP}/prebuilts/tools/${osname}-${vmarch}/swt"
else
swtpath="${frameworkdir}/${vmarch}"
fi
fi
1. Combine the swtpath and the framework dir path.
if [ -d "$swtpath" ]; then
frameworkdir="${swtpath}:${frameworkdir}"
1. frameworkdir="${frameworkdir}"
else
echo "SWT folder '${swtpath}' does not exist."
echo "Please export ANDROID_SWT to point to the folder containing swt.jar for your platform."
exit 1
fi
echo "${javaCmd}" $javaOpts -classpath="$frameworkdir" -Dcom.android.uiautomator.bindir="$progdir" -jar "$jarpath" " $@ "
exec "${javaCmd}" $javaOpts -classpath="$frameworkdir" -Dcom.android.uiautomator.bindir="$progdir" -jar "$jarpath" " $@ "
四、uiautomator2
UiAutomator 是Google提供的用来做安卓自动化测试的一个Java库,功能很强,可以对第三方App进行测试,获取屏幕上任意一个APP的任意一个控件属性,并对其进行任意操作。但有两个缺点:
改进方案: 在手机上运行了一个 HTTP ****PRC 服务,将uiautomator中的功能开放出来,然后再将这些http接口封装成Python库。
整体过程:
atx-agent
(守护进程), 随后atx-agent
启动uiautomator2服务(默认7912端口)进行监听;五、业务实践
业务痛点:
工具答疑:
问:测试同学已经有了框架,我们在做是不是重复造轮子?
扩展插件不是为了取代测试已有的测试体系,而是为了打开前端介入参与的大门。提供了转义层,通过可配置的方式实现脚本的转化,这样不仅不会干扰整个测试的体系,反而会促进测试用例的转化。
插件扩展是具有针对性的,目前受众是前端。当然,不排除后面服务端、客户端参与进来,也同样会出针对idea相关的插件。
插件核心是【转化】,当把这部分完善好提炼出来,它就不会局限于插件本身了。就像vue template 转化成 js bundle 的时候,依赖的是 @vue/compiler-core 一样的道理。
理想情况下,测试现有的工程可以划分来看,运行环境 + 脚本,运行环境实际上可以保持不变,脚本可以共同来维护,前端可以转化生成脚本,脚本也可以逆转成前端结构,这一点就是构建DSL的思想。