💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Appium自动化测试(Java版) # Appium自动化测试 ### Appium软件配置(仅设置图片所展示即可) ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124727442.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124737669.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) ### Appium-Inspector工具配置 **Desired Capabilities属性值配置** | 属性名称 | 类型 | 值 | | :-: | :-: | :-: | | deviceName | text | 127.0.0.1:62001 | | platformName | text | Android | | appPackage | text | com.smile.gifmaker | | appActivity | text | com.yxcorp.gifshow.HomeActivity | * 连接到夜神模拟器 ~~~ adb connect 127.0.0.1:62001 ~~~ * 检测设备 ~~~ adb devices ~~~ * 获取包名 在build-tools文件夹下,cmd中输入命令 ~~~ aapt dump badging D:\Android\software\kuaishou.apk(软件路径) ~~~ ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124804881.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) * 获取应用程序入口 在获取包名的同时找launchable-activity的值 ![](https://img.kancloud.cn/ac/ab/acab07080e4af76d0b99e0831ff29645_1223x639.jpg) **配置结果** ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124821700.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) 启动会话后,若出现下面结果,则配置成功。 ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124834932.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) ### 元素探测工具 ##### Appium Inspector工具 ![](https://img.kancloud.cn/26/da/26da346e46adbfcced85f8f3b9de883e_1920x1044.jpg) ##### UIAutomatorViewer工具(SDK提供的原生元素定位工具,不需要提供启动参数) 该工具在Android/Android-SDK/tools/bin目录下 ![](https://img.kancloud.cn/eb/ae/ebaeeb61e9c3fd9acbf2c83b301dd640_784x592.jpg) ### 名称解释 **PackageName**(包名)应用程序的唯一标识 **ActivityName**(类名)一个页面的名字 可以通过命令 ~~~ adb shell dumpsys activity | find "mFocusedActivity" ~~~ 查看当前聚焦页面的包名和类名 ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=2020120412491094.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) ### App类型对比 ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124920986.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) ### APP页面布局 ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124929228.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) ### APP页面控件 ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124934369.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) ### ADB组件 ![在这里插入图片描述](https://www.icode9.com/img/ll/?i=20201204124942218.png?,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NDg2NDM3,size_16,color_FFFFFF,t_70) #### adb常用命令 * 查看帮助手册 ~~~ adb help ~~~ * 检测连接到电脑的安卓设备(注意模拟器的连接) ~~~ adb devices ~~~ * 从手机中拉取信息放到本地电脑上 ~~~ adb pull<手机路径><本机路径> ~~~ * 从本地推送信息到手机上去 ~~~ adb push<本机路径><手机路径> ~~~ * 登录设备shell模式(命令行的人机界面) ~~~ adb shell ~~~ * 安装应用 ~~~ adb install xxx.apk ~~~ * 卸载应用 ~~~ adb uninstall com.ss.android.ugc.aweme(应用程序包名) ~~~ * 查看前台应用包名 ~~~ adb shell dumpsys activity | find "mFocusedActivity" ~~~ * 终止adb服务 ~~~ adb kill-server ~~~ * 启动adb服务 ~~~ adb start-server ~~~ * 启动App ~~~ adb shell am start -n com.tencent.weishi(包名)/com.tencent.oscar.module.main.MainActivity(入口) ~~~ * 清除应用的数据和缓存 ~~~ adb shell pm clear 包名 ~~~ * 坐标点击 ~~~ adb shell input tap x轴坐标 y轴坐标 ~~~ * 列出所有包名 ~~~ adb shell pm list packages ~~~ * 打印日志 ~~~ adb logcat (ctrl+c终止抓取) ~~~ ### 初体验 ~~~java package pers.lele; import io.appium.java_client.android.AndroidDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.DesiredCapabilities; import java.net.MalformedURLException; import java.net.URL; public class FirstAppium { public static AndroidDriver<WebElement> androidDriver; public static void main(String[] args) throws MalformedURLException, InterruptedException { //1、创建配置对象 DesiredCapabilities desiredCapabilities = new DesiredCapabilities(); //2、添加配置 //deviceName:测试的设备 desiredCapabilities.setCapability("deviceName","127.0.0.1:62001"); //platformName desiredCapabilities.setCapability("platformName","Android"); //appPackage:测试的App desiredCapabilities.setCapability("appPackage","com.tencent.weishi"); //automationName:uiautomator2解决输入框输入不了数据 //desiredCapabilities.setCapability("automationName","uiautomator2"); //appActivity:测试App启动入口 desiredCapabilities.setCapability("appActivity","com.tencent.oscar.module.splash.SplashActivity"); //3.创建驱动 //第一个参数:Appium通讯地址 //第二个参数:配置对象 androidDriver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"),desiredCapabilities); searchTest(); } public static void searchTest() throws InterruptedException { //等待元素加载完毕 Thread.sleep(1000*10); androidDriver.findElementById("com.tencent.weishi:id/tv_tip_close").click(); //1、找到搜索按钮并点击 androidDriver.findElementById("com.tencent.weishi:id/noname_base_search").click(); //2、找到搜索框,输入路人王 androidDriver.findElementById("com.tencent.weishi:id/search_input").sendKeys("路人王"); //断言: /* String expected = ""; String result androidDriver.currentActivity(); Assert.assertEquals(expected,result); */ //驱动销毁 //androidDriver.quit(); } } ~~~ ### Appium元素定位 * **ID**:控件的唯一身份标识,但是可能由于app项目开发人员不严谨导致一个页面有多个相同的id ### 元素等待 * 强制等待 ~~~ Thread.sleep(); ~~~ * 隐式等待 ~~~ androidDriver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS); ~~~ * 显示等待:针对某个元素设置等待时间 ~~~ WebDriverWait webDriverWait = new WebDriverWait(androidDriver,10); WebElement webElement = webDriverWait.until(new ExpectedCondition<WebElement>() { @NullableDecl @Override public WebElement apply(@NullableDecl WebDriver webDriver) { return androidDriver.findElementById("com.tencent.weishi:id/noname_base_search"); } }); webElement.click(); ~~~ ### 手势操作-滑动 ~~~ TouchAction touchAction = new TouchAction(androidDriver); PointOption startPoint = PointOption.point(476, 1326); PointOption endPoint = PointOption.point(414, 234); Duration duration = Duration.ofMillis(500); WaitOptions options = WaitOptions.waitOptions(duration); touchAction.press(startPoint).waitAction(options).moveTo(endPoint).release(); touchAction.perform(); ~~~