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上面的積累已經一年多,

           起初學東西是拿來用,不知其原理,只知道這么用,長期以來,並未有什么進步。最近看到一些大牛分享的學習思路,才發現學東西要循序漸進,

           學會使用->熟練使用->了解掌握其原理->分析改造源碼->造輪子

          經過這一系列的學習和總結,就能成為資深人士。

           


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM