当前位置: 首页 > news >正文

Appium 三种wait方法(appium 学习之改造轮子)

前些日子,配置好了appium测试环境,至于环境怎么搭建,参考:http://www.cnblogs.com/tobecrazy/p/4562199.html

                    知乎Android客户端登陆:http://www.cnblogs.com/tobecrazy/p/4579631.html

                                       appium实现截图和清空EditText:  http://www.cnblogs.com/tobecrazy/p/4592405.html

学过selenium的都知道,一般等待元素加载有三种办法:

  • sleep                  Thread.sleep(60000) 强制等待60s
  • implicitlyWait      
     driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);  

     

        隐式等待,全局等待30s不管元素是否已经加载
  • WebDriverWait     显示等待,这个需要增加一定等待时间,显示等待时间可以通过WebDriverWait 和util来决定,比如这个timeOut是60,如果该元素60s以内出现就不在等待
WebDriverWait wait = new WebDriverWait(driver, 60);
    WebElement e= wait.until(new  ExpectedCondition<WebElement>() {
            @Override
            public WebElement apply(WebDriver d) {
                return d.findElement(By.id("q"));
            }
        })

  以上三种方法中,只用WebDriverWait是selenium所特有,在java-client中也找不到相应,如果想使用这种方法怎么办?

改造轮子,首先添加AndroidDriverWait.java, 其实是将WebDriverWait的类型改成AndroidDriverWait

具体代码如下:

  

 1 package com.dbyl.core;
 2 
 3 /*
 4 Copyright 2007-2009 Selenium committers
 5 
 6 Licensed under the Apache License, Version 2.0 (the "License");
 7 you may not use this file except in compliance with the License.
 8 You may obtain a copy of the License at
 9 
10      http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17  */
18 
19 import org.openqa.selenium.NotFoundException;
20 import org.openqa.selenium.TimeoutException;
21 import org.openqa.selenium.WebDriver;
22 import org.openqa.selenium.WebDriverException;
23 import org.openqa.selenium.remote.RemoteWebDriver;
24 import org.openqa.selenium.support.ui.Clock;
25 import org.openqa.selenium.support.ui.FluentWait;
26 import org.openqa.selenium.support.ui.Sleeper;
27 import org.openqa.selenium.support.ui.SystemClock;
28 
29 import io.appium.java_client.android.AndroidDriver;
30 
31 import java.util.concurrent.TimeUnit;
32 
33 /**
34  * A specialization of {@link FluentWait} that uses WebDriver instances.
35  */
36 public class AndroidDriverWait extends FluentWait<AndroidDriver> {
37   public final static long DEFAULT_SLEEP_TIMEOUT = 500;
38   private final WebDriver driver;
39 
40   /**
41    * Wait will ignore instances of NotFoundException that are encountered (thrown) by default in
42    * the 'until' condition, and immediately propagate all others.  You can add more to the ignore
43    * list by calling ignoring(exceptions to add).
44    *
45    * @param driver The WebDriver instance to pass to the expected conditions
46    * @param timeOutInSeconds The timeout in seconds when an expectation is called
47    * @see AndroidDriverWait#ignoring(java.lang.Class)
48    */
49   public AndroidDriverWait(AndroidDriver driver, long timeOutInSeconds) {
50     this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, DEFAULT_SLEEP_TIMEOUT);
51   }
52 
53   /**
54    * Wait will ignore instances of NotFoundException that are encountered (thrown) by default in
55    * the 'until' condition, and immediately propagate all others.  You can add more to the ignore
56    * list by calling ignoring(exceptions to add).
57    *
58    * @param driver The WebDriver instance to pass to the expected conditions
59    * @param timeOutInSeconds The timeout in seconds when an expectation is called
60    * @param sleepInMillis The duration in milliseconds to sleep between polls.
61    * @see AndroidDriverWait#ignoring(java.lang.Class)
62    */
63   public AndroidDriverWait(AndroidDriver driver, long timeOutInSeconds, long sleepInMillis) {
64     this(driver, new SystemClock(), Sleeper.SYSTEM_SLEEPER, timeOutInSeconds, sleepInMillis);
65   }
66 
67   /**
68    * @param driver The WebDriver instance to pass to the expected conditions
69    * @param clock The clock to use when measuring the timeout
70    * @param sleeper Object used to make the current thread go to sleep.
71    * @param timeOutInSeconds The timeout in seconds when an expectation is
72    * @param sleepTimeOut The timeout used whilst sleeping. Defaults to 500ms called.
73    */
74   public AndroidDriverWait(AndroidDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds,
75       long sleepTimeOut) {
76     super(driver, clock, sleeper);
77     withTimeout(timeOutInSeconds, TimeUnit.SECONDS);
78     pollingEvery(sleepTimeOut, TimeUnit.MILLISECONDS);
79     ignoring(NotFoundException.class);
80     this.driver = driver;
81   }
82 
83   @Override
84   protected RuntimeException timeoutException(String message, Throwable lastException) {
85     TimeoutException ex = new TimeoutException(message, lastException);
86     ex.addInfo(WebDriverException.DRIVER_INFO, driver.getClass().getName());
87     if (driver instanceof RemoteWebDriver) {
88       RemoteWebDriver remote = (RemoteWebDriver) driver;
89       if (remote.getSessionId() != null) {
90         ex.addInfo(WebDriverException.SESSION_ID, remote.getSessionId().toString());
91       }
92       if (remote.getCapabilities() != null) {
93         ex.addInfo("Capabilities", remote.getCapabilities().toString());
94       }
95     }
96     throw ex;
97   }
98 }
View Code

接着需要修改接口:ExpectedCondition,将其WebDriver的类型替换为AndroidDriver

具体代码:

 1 /*
 2 Copyright 2007-2009 Selenium committers
 3 
 4 Licensed under the Apache License, Version 2.0 (the "License");
 5 you may not use this file except in compliance with the License.
 6 You may obtain a copy of the License at
 7 
 8      http://www.apache.org/licenses/LICENSE-2.0
 9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15  */
16 
17 package com.dbyl.core;
18 
19 import io.appium.java_client.android.AndroidDriver;
20 
21 import com.google.common.base.Function;
22 
23 
24 /**
25  * Models a condition that might reasonably be expected to eventually evaluate to something that is
26  * neither null nor false. Examples would include determining if a web page has loaded or that an
27  * element is visible.
28  * <p>
29  * Note that it is expected that ExpectedConditions are idempotent. They will be called in a loop by
30  * the {@link WebDriverWait} and any modification of the state of the application under test may
31  * have unexpected side-effects.
32  * 
33  * @param <T> The return type
34  */
35 public interface ExpectedCondition<T> extends Function<AndroidDriver, T> {}
View Code

经过修改之后,就可以在appium中直接使用:

        //wait for 60s if WebElemnt show up less than 60s , then return , until 60s
        WebElement showClose = new AndroidDriverWait(driver, 60)
                .until(new ExpectedCondition<WebElement>() {
                    public WebElement apply(AndroidDriver d) {
                        return d.findElement(By
                                .id("com.zhihu.android:id/showcase_close"));
                    }

                });

个人心得:

          做自动化也有4年多,之前做的是server端的测试,并未太多的关注过selenium,现在selenium上面的积累已经一年多,

           起初学东西是拿来用,不知其原理,只知道这么用,长期以来,并未有什么进步。最近看到一些大牛分享的学习思路,才发现学东西要循序渐进,

           学会使用->熟练使用->了解掌握其原理->分析改造源码->造轮子

          经过这一系列的学习和总结,就能成为资深人士。

           

相关文章:

  • 文件服务器 之 Debian下配置使用Subversion版本控制服务器
  • 浏览器缓存机制(转)
  • C#网络编程系列文章索引
  • iOS Web应用开发:运用HTML5、CSS3与JavaScript
  • Makefile 中:= ?= += =的区别
  • centos7zabbix-agen安装
  • vue-i18n beforeDestroy不能调用this.$t
  • 验证码识别并复制到剪切板
  • cheerp 简介
  • CSS 三角实现
  • 第十二章 Java内存模型与线程
  • 从源码分析如何优雅的使用 Kafka 生产者
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • 阿里云重庆大学大数据训练营落地分享
  • Android Studio多渠道打包实战
  • ES6指北【2】—— 箭头函数
  • CSS盒模型深入
  • Django 博客开发教程 8 - 博客文章详情页
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • iOS编译提示和导航提示
  • Java-详解HashMap
  • js学习笔记
  • MySQL主从复制读写分离及奇怪的问题
  • python3 使用 asyncio 代替线程
  • Python爬虫--- 1.3 BS4库的解析器
  • SOFAMosn配置模型
  • 开发基于以太坊智能合约的DApp
  • 判断客户端类型,Android,iOS,PC
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 06-01 点餐小程序前台界面搭建
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​2020 年大前端技术趋势解读
  • ​MySQL主从复制一致性检测
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • # C++之functional库用法整理
  • (zt)基于Facebook和Flash平台的应用架构解析
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .net core控制台应用程序初识
  • .NET Standard / dotnet-core / net472 —— .NET 究竟应该如何大小写?
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • .Net组件程序设计之线程、并发管理(一)
  • 。Net下Windows服务程序开发疑惑
  • /usr/bin/env: node: No such file or directory
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解
  • [20170705]diff比较执行结果的内容.txt
  • [AIGC codze] Kafka 的 rebalance 机制
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [C++] 统计程序耗时
  • [C++]STL之map
  • [CSS]浮动