zoukankan      html  css  js  c++  java
  • Appium的安装和使用

    <!DOCTYPE html>
    <html>
    <head>
    <title>Appium的安装和使用</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style type="text/css">
    /* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
    /* Author: Nicolas Hery - http://nicolashery.com */
    /* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */
    /* Source: https://github.com/nicolahery/markdownpad-github */

    /* RESET
    =============================================================================*/

    html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    }

    /* BODY
    =============================================================================*/

    body {
    font-family: Helvetica, arial, freesans, clean, sans-serif;
    font-size: 14px;
    line-height: 1.6;
    color: #333;
    background-color: #fff;
    padding: 20px;
    max- 960px;
    margin: 0 auto;
    }

    body>*:first-child {
    margin-top: 0 !important;
    }

    body>*:last-child {
    margin-bottom: 0 !important;
    }

    /* BLOCKS
    =============================================================================*/

    p, blockquote, ul, ol, dl, table, pre {
    margin: 15px 0;
    }

    /* HEADERS
    =============================================================================*/

    h1, h2, h3, h4, h5, h6 {
    margin: 20px 0 10px;
    padding: 0;
    font-weight: bold;
    -webkit-font-smoothing: antialiased;
    }

    h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
    font-size: inherit;
    }

    h1 {
    font-size: 28px;
    color: #000;
    }

    h2 {
    font-size: 24px;
    border-bottom: 1px solid #ccc;
    color: #000;
    }

    h3 {
    font-size: 18px;
    }

    h4 {
    font-size: 16px;
    }

    h5 {
    font-size: 14px;
    }

    h6 {
    color: #777;
    font-size: 14px;
    }

    body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
    margin-top: 0;
    padding-top: 0;
    }

    a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
    margin-top: 0;
    padding-top: 0;
    }

    h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
    margin-top: 10px;
    }

    /* LINKS
    =============================================================================*/

    a {
    color: #4183C4;
    text-decoration: none;
    }

    a:hover {
    text-decoration: underline;
    }

    /* LISTS
    =============================================================================*/

    ul, ol {
    padding-left: 30px;
    }

    ul li > :first-child,
    ol li > :first-child,
    ul li ul:first-of-type,
    ol li ol:first-of-type,
    ul li ol:first-of-type,
    ol li ul:first-of-type {
    margin-top: 0px;
    }

    ul ul, ul ol, ol ol, ol ul {
    margin-bottom: 0;
    }

    dl {
    padding: 0;
    }

    dl dt {
    font-size: 14px;
    font-weight: bold;
    font-style: italic;
    padding: 0;
    margin: 15px 0 5px;
    }

    dl dt:first-child {
    padding: 0;
    }

    dl dt>:first-child {
    margin-top: 0px;
    }

    dl dt>:last-child {
    margin-bottom: 0px;
    }

    dl dd {
    margin: 0 0 15px;
    padding: 0 15px;
    }

    dl dd>:first-child {
    margin-top: 0px;
    }

    dl dd>:last-child {
    margin-bottom: 0px;
    }

    /* CODE
    =============================================================================*/

    pre, code, tt {
    font-size: 12px;
    font-family: Consolas, "Liberation Mono", Courier, monospace;
    }

    code, tt {
    margin: 0 0px;
    padding: 0px 0px;
    white-space: nowrap;
    border: 1px solid #eaeaea;
    background-color: #f8f8f8;
    border-radius: 3px;
    }

    pre>code {
    margin: 0;
    padding: 0;
    white-space: pre;
    border: none;
    background: transparent;
    }

    pre {
    background-color: #f8f8f8;
    border: 1px solid #ccc;
    font-size: 13px;
    line-height: 19px;
    overflow: auto;
    padding: 6px 10px;
    border-radius: 3px;
    }

    pre code, pre tt {
    background-color: transparent;
    border: none;
    }

    kbd {
    -moz-border-bottom-colors: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    background-color: #DDDDDD;
    background-image: linear-gradient(#F1F1F1, #DDDDDD);
    background-repeat: repeat-x;
    border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
    border-image: none;
    border-radius: 2px 2px 2px 2px;
    border-style: solid;
    border- 1px;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    line-height: 10px;
    padding: 1px 4px;
    }

    /* QUOTES
    =============================================================================*/

    blockquote {
    border-left: 4px solid #DDD;
    padding: 0 15px;
    color: #777;
    }

    blockquote>:first-child {
    margin-top: 0px;
    }

    blockquote>:last-child {
    margin-bottom: 0px;
    }

    /* HORIZONTAL RULES
    =============================================================================*/

    hr {
    clear: both;
    margin: 15px 0;
    height: 0px;
    overflow: hidden;
    border: none;
    background: transparent;
    border-bottom: 4px solid #ddd;
    padding: 0;
    }

    /* TABLES
    =============================================================================*/

    table th {
    font-weight: bold;
    }

    table th, table td {
    border: 1px solid #ccc;
    padding: 6px 13px;
    }

    table tr {
    border-top: 1px solid #ccc;
    background-color: #fff;
    }

    table tr:nth-child(2n) {
    background-color: #f8f8f8;
    }

    /* IMAGES
    =============================================================================*/

    img {
    max- 100%
    }
    </style>
    </head>
    <body>
    <h2>Appium</h2>
    <ul>
    <li>基于 WebDrive 协议的一个自动化测试框架,可以对 Android、iOS 以及混合开发的移动端应用进行自动化测试。</li>
    <li>优势:可以使用 Python 、Ruby 、 Java 、 JavaScript、Php 、 C# 等语言进行开发。</li>
    <li>劣势:Appium 在 Android 官方的自动化框架 UiAutomator 和 iOS 官方的 UiAutomation 上进行的封装,所以效率上没有直接使用官方的框架好。</li>
    <li>目前已经有了 GUI 版本,环境配置更加方便和快速。</li>
    <li><a href="http://appium.io/">官网</a></li>
    </ul>
    <h2>安装</h2>
    <ul>
    <li><a href="https://bitbucket.org/appium/appium.app/downloads/AppiumForWindows_1_4_13_1.zip">最新 GUI 版本下载</a></li>
    </ul>
    <h2>使用</h2>
    <h3>配置</h3>
    <p><img src="http://i.imgur.com/dJHDKBh.png" /></p>
    <p><img src="http://i.imgur.com/f5ZviwP.png" /></p>
    <h3>瑞信信息</h3>
    <ul>
    <li>Package: com.xxx.xxx</li>
    <li>Launch Activity: com.xxx.xxx.ui.activity.WelcomeActivity</li>
    <li>Device Name:4d003d169c0c4037,可以通过 adb devices 命令查询到</li>
    <li>PlatformVersion:测试设备的 Android 版本号</li>
    </ul>
    <h2>脚本的编写(以 Java 为例,其他语言的 Api 类似)</h2>
    <h3>定位</h3>
    <ul>
    <li>常用 Api 通过各种属性定位</li>
    <li>
    <p>在 Android 测试中,一般使用 findElementsById() 或者 findElementById() 方法就够了,假如需要定位的控件没有 id的话,可以让开发人员帮忙添加上。</p>
    </li>
    <li>
    <p>T findElementById(String id)</p>
    </li>
    <li>T findElementByName(String using)</li>
    <li>T findElementByClassName(String using)</li>
    <li>T findElementByXPath(String using)</li>
    <li>List<T> findElementsById(String id):通过 id 获取到定位</li>
    <li>List<T> findElementsByName(String using):通过 name 获取到定位</li>
    <li>List<T> findElementsByClassName(String using):通过类名获取到定位</li>
    <li>List<T> findElementsByXPath(String using):通过 XPath 定位(定位比较准,不会存在歧义的一种定位方法,就是比较麻烦,万一客户端的布局文件进行了修改,XPath 需要重写)</li>
    </ul>
    <h4>示例</h4>
    <ul>
    <li>driver.findElement(By.xpath(&quot;.//*[@text='Add Contact']&quot;))</li>
    <li>driver.findElementById(&quot;com.xxx.xxx:id/login_btn&quot;);</li>
    <li>driver.findElement(By.id(&quot;com.xxx.xxx:id/login_btn&quot;));</li>
    <li>driver.findElementsById(&quot;com.xxx.xxx:id/login_btn&quot;).get(0)</li>
    </ul>
    <h3>点击</h3>
    <ul>
    <li>void click()</li>
    </ul>
    <h3>EditText 等控件输入文本</h3>
    <ul>
    <li>void sendKeys(CharSequence... keysToSend)</li>
    </ul>
    <h3>滑动</h3>
    <ul>
    <li>
    <p>swipe(int startx, int starty, int endx, int endy, int duration)</p>
    <ul>
    <li>startx:开始坐标 x </li>
    <li>starty:开始坐标 y</li>
    <li>endx:结束坐标 x</li>
    <li>endy:结束坐标 y</li>
    <li>duration:滑动持续时间</li>
    </ul>
    </li>
    <li>
    <p>向左滑动,手机分辨率为1080P,即1920×1080,坐标可以写成从(900,500)滑动到(400,500)。(该写法为 Android 中的 sp ,针对兼容性问题,目前在 Android 使用的是 dp ,所以这里用 sp 的话,会在不同分辨率的机子上出现问题,因此针对不同的设备,在脚本运行前需要进行代码的检查和校验)</p>
    </li>
    <li>
    <p>Android 坐标系</p>
    <ul>
    <li>
    <p>Android 坐标系是以 x 轴的正方向和 y 轴的下方向为坐标系,即数学中的第四象限</p>
    <p><img src="http://i.imgur.com/VtRhIYZ.png" /></p>
    </li>
    </ul>
    </li>
    </ul>
    <h3>截图</h3>
    <ul>
    <li><X> X getScreenshotAs(OutputType<X> outputType)</li>
    </ul>
    <h3>缩放</h3>
    <ul>
    <li>
    缩:
    <ul>
    <li>
    void pinch(WebElement el)
    <ul>
    <li>webElement:一般通过 findViewBy... 方法可以获取到 WebElement 的子类</li>
    </ul>
    </li>
    <li>
    void pinch(int x, int y)
    <ul>
    <li>(x,y):坐标</li>
    </ul>
    </li>
    </ul>
    </li>
    <li>
    放:
    <ul>
    <li>
    void zoom(WebElement webElement):缩放每个控件
    <ul>
    <li>webElement:一般通过 findViewBy... 方法可以获取到 WebElement 的子类</li>
    </ul>
    </li>
    <li>
    void zoom(int x, int y):通过(x,y)坐标缩放
    <ul>
    <li>(x,y):坐标</li>
    </ul>
    </li>
    </ul>
    </li>
    </ul>
    <h3>隐藏键盘</h3>
    <ul>
    <li>void hideKeyboard()</li>
    </ul>
    <h3>获取和设置横竖屏</h3>
    <ul>
    <li>
    <p>ScreenOrientation getOrientation():获取手机横竖屏信息</p>
    <ul>
    <li>返回值是一个枚举类型,通过 value() 方法可以得到手机屏幕的横竖屏信息。</li>
    <li>landscape:横屏</li>
    <li>portrait:竖屏</li>
    </ul>
    </li>
    <li>
    <p>void rotate(ScreenOrientation orientation):设置手机横竖屏</p>
    <ul>
    <li>
    orientation:枚举类型
    <ul>
    <li>ScreenOrientation.LANDSCAPE</li>
    <li>ScreenOrientation.PORTRAIT</li>
    </ul>
    </li>
    </ul>
    </li>
    </ul>
    <h3>等待时间</h3>
    <ul>
    <li>
    <p>Thread.sleep(1000):当前线程睡眠时间</p>
    </li>
    <li>
    <p>在一定时间内等待某个元素的出现</p>
    <pre><code> WebDriverWait wait = new WebDriverWait(driver, 10);
    wait.until(new ExpectedCondition&lt;WebElement&gt;() {
    @Override
    public WebElement apply(WebDriver d) {
    return d.findElement(By.id(&quot;com.xxx.xxx:id/backlog_list_layout&quot;));
    }
    });
    </code></pre>

    </li>
    <li>
    <p>等待某个元素的出现</p>
    <pre><code>private void waitForVisible(WebDriver driver, final By by, int waitTime) {
    WebDriverWait wait = new WebDriverWait(driver, waitTime);
    for (int i = 0; i &lt; waitTime; i++) {
    try {
    driver.findElement(by);
    break;
    } catch (Exception e) {
    driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    }
    }
    wait.until(ExpectedConditions.visibilityOfElementLocated(by));
    }
    </code></pre>

    </li>
    </ul>
    <h3>判断某个元素是否显示在屏幕上</h3>
    <ul>
    <li>boolean isDisplayed()</li>
    </ul>
    <h3>断言</h3>
    <ul>
    <li>
    <p>断言,在 org.junit.Assert 包里,判断是否与预期结果一致。</p>
    </li>
    <li>
    <p>void assertNull(Object object)</p>
    </li>
    <li>void assertNotNull(Object object)</li>
    <li>void assertEquals(Object expected, Object actual) </li>
    </ul>
    <h3>应用工具类Api</h3>
    <ul>
    <li>
    <p>app 是否安装:boolean isAppInstalled(String bundleId):</p>
    <ul>
    <li>bundleId:应用的包名</li>
    <li>返回值:返回一个布尔值,true 表示已安装了该应用</li>
    </ul>
    </li>
    <li>
    <p>安装 apk:void installApp(String appPath):</p>
    <ul>
    <li>appPath:apk路径</li>
    </ul>
    </li>
    <li>
    <p>移出指定包名的app:void removeApp(String bundleId)</p>
    <ul>
    <li>bundleId:应用的包名</li>
    </ul>
    </li>
    <li>运行app:void launchApp()</li>
    <li>关闭app:void closeApp()</li>
    <li>
    <p>app放到后台:void runAppInBackground(int seconds)</p>
    <ul>
    <li>seconds:后台放置时间</li>
    </ul>
    </li>
    <li>
    <p>执行命令:Response execute(String command)</p>
    <ul>
    <li>command:命令</li>
    <li>返回值是一个 Resonse,可以解析 Response 来判断是否执行成功。</li>
    </ul>
    </li>
    </ul>
    <h2>代码示例</h2>
    <h3>Java</h3>
    <pre><code>package com.saucelabs.appium;

    import io.appium.java_client.AppiumDriver;
    import io.appium.java_client.android.AndroidDriver;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.openqa.selenium.By;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.remote.DesiredCapabilities;

    import java.io.File;
    import java.net.URL;
    import java.util.List;

    import static org.junit.Assert.assertEquals;

    public class AndroidTest {

    private AppiumDriver&lt;WebElement&gt; driver;

    @Before
    public void setUp() throws Exception {
    File classpathRoot = new File(System.getProperty(&quot;user.dir&quot;));
    File appDir = new File(classpathRoot, &quot;../../../apps/ApiDemos/bin&quot;);
    File app = new File(appDir, &quot;ApiDemos-debug.apk&quot;);
    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability(&quot;deviceName&quot;,&quot;Android Emulator&quot;);
    capabilities.setCapability(&quot;platformVersion&quot;, &quot;4.4&quot;);
    capabilities.setCapability(&quot;app&quot;, app.getAbsolutePath());
    capabilities.setCapability(&quot;appPackage&quot;, &quot;io.appium.android.apis&quot;);
    capabilities.setCapability(&quot;appActivity&quot;, &quot;.ApiDemos&quot;);
    driver = new AndroidDriver&lt;&gt;(new URL(&quot;http://127.0.0.1:4723/wd/hub&quot;), capabilities);
    }

    @After
    public void tearDown() throws Exception {
    driver.quit();
    }

    @Test
    public void apiDemo(){
    WebElement el = driver.findElement(By.xpath(&quot;.//*[@text='Animation']&quot;));
    assertEquals(&quot;Animation&quot;, el.getText());
    el = driver.findElementByClassName(&quot;android.widget.TextView&quot;);
    assertEquals(&quot;API Demos&quot;, el.getText());
    el = driver.findElement(By.xpath(&quot;.//*[@text='App']&quot;));
    el.click();
    List&lt;WebElement&gt; els = driver.findElementsByClassName(&quot;android.widget.TextView&quot;);
    assertEquals(&quot;Activity&quot;, els.get(2).getText());
    }

    }
    </code></pre>

    <h3>Python</h3>
    <pre><code>import os
    from time import sleep

    import unittest

    from appium import webdriver

    # Returns abs path relative to this file and not cwd
    PATH = lambda p: os.path.abspath(
    os.path.join(os.path.dirname(__file__), p)
    )

    class SimpleAndroidTests(unittest.TestCase):
    def setUp(self):
    desired_caps = {}
    desired_caps['platformName'] = 'Android'
    desired_caps['platformVersion'] = '4.2'
    desired_caps['deviceName'] = 'Android Emulator'
    desired_caps['app'] = PATH(
    '../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk'
    )

    self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

    def tearDown(self):
    # end the session
    self.driver.quit()

    def test_find_elements(self):
    el = self.driver.find_element_by_accessibility_id('Graphics')
    el.click()
    el = self.driver.find_element_by_accessibility_id('Arcs')
    self.assertIsNotNone(el)

    self.driver.back()

    el = self.driver.find_element_by_accessibility_id(&quot;App&quot;)
    self.assertIsNotNone(el)

    els = self.driver.find_elements_by_android_uiautomator(&quot;new UiSelector().clickable(true)&quot;)
    self.assertGreaterEqual(12, len(els))

    self.driver.find_element_by_android_uiautomator('text(&quot;API Demos&quot;)')


    def test_simple_actions(self):
    el = self.driver.find_element_by_accessibility_id('Graphics')
    el.click()

    el = self.driver.find_element_by_accessibility_id('Arcs')
    el.click()

    self.driver.find_element_by_android_uiautomator('new UiSelector().text(&quot;Graphics/Arcs&quot;)')


    if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(SimpleAndroidTests)
    unittest.TextTestRunner(verbosity=2).run(suite)
    </code></pre>

    <blockquote>
    <p><a href="https://github.com/appium/sample-code/tree/master/sample-code/examples">GitHub示例代码</a></p>
    </blockquote>
    <h2>app示例代码</h2>
    <h3>测试环境下,app登录,进入待办1000次,并截图</h3>
    <pre><code>import io.appium.java_client.AppiumDriver;
    import io.appium.java_client.android.AndroidDriver;
    import io.appium.java_client.android.AndroidElement;
    import org.apache.commons.io.FileUtils;
    import org.junit.After;
    import org.junit.Assert;
    import org.junit.Before;
    import org.junit.Test;
    import org.openqa.selenium.By;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.WebElement;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.openqa.selenium.remote.SessionId;
    import org.openqa.selenium.support.ui.ExpectedCondition;
    import org.openqa.selenium.support.ui.ExpectedConditions;
    import org.openqa.selenium.support.ui.WebDriverWait;

    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    import java.util.concurrent.TimeUnit;


    public class AppTest {
    private AppiumDriver&lt;AndroidElement&gt; driver;

    @Before
    public void setUp() throws Exception {
    // set up appium
    File classpathRoot = new File(System.getProperty(&quot;user.dir&quot;));
    File appDir = new File(classpathRoot, &quot;apps&quot;);
    File app = new File(appDir, &quot;app.apk&quot;);
    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability(&quot;deviceName&quot;, &quot;4d003d169c0c4037&quot;);
    capabilities.setCapability(&quot;platformVersion&quot;, &quot;5.0.1&quot;);
    capabilities.setCapability(&quot;app&quot;, app.getAbsolutePath());
    capabilities.setCapability(&quot;appPackage&quot;, &quot;com.xxx.xxx&quot;);
    capabilities.setCapability(&quot;appActivity&quot;, &quot;.ui.activity.WelcomeActivity&quot;);
    driver = new AndroidDriver&lt;&gt;(new URL(&quot;http://127.0.0.1:4723/wd/hub&quot;), capabilities);
    }

    @After
    public void tearDown() throws Exception {
    driver.removeApp(&quot;com.xxx.xxx&quot;);
    SessionId sessionId = driver.getSessionId();
    sessionId = null;
    driver.quit();
    }


    @Test
    public void appLogin() {
    waitForVisible(driver, By.id(&quot;com.xxx.xxx:id/login_btn&quot;), 10);
    if (driver.findElementsById(&quot;com.xxx.xxx:id/login_btn&quot;).get(0).isDisplayed()) {
    AndroidElement userName = driver.findElementsById(&quot;com.xxx.xxx:id/login_username_edit_text&quot;).get(0);
    userName.sendKeys(&quot;username&quot;);
    AndroidElement password = driver.findElementsById(&quot;com.xxx.xxx:id/login_password_edit_text&quot;).get(0);
    password.click();

    driver.hideKeyboard();
    //判断登录框是否输入了
    Assert.assertEquals(&quot;username&quot;, userName.getText());
    //等待2秒
    driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

    password.click();
    password.sendKeys(&quot;password&quot;);
    //隐藏弹出的键盘
    driver.hideKeyboard();
    //判断输入的密码不为空
    Assert.assertNotNull(password.getText());
    //点击登录按钮
    driver.findElementsById(&quot;com.xxx.xxx:id/login_btn&quot;).get(0).click();
    //登录等待
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    task();
    }
    }


    private void task() {
    AndroidElement androidElement = driver.findElementsById(&quot;com.xxx.xxx:id/main_tab_apps&quot;).get(0);
    driver.zoom(androidElement);
    waitForVisible(driver, By.id(&quot;com.xxx.xxx:id/main_tab_msgs&quot;), 10);
    //跳转到应用页面
    driver.findElementsById(&quot;com.xxx.xxx:id/main_tab_apps&quot;).get(0).click();
    //等待5秒
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    //判断GridView是否显示
    if (driver.findElementsById(&quot;com.xxx.xxx:id/application_grid_view&quot;).get(0).isDisplayed()) {
    System.out.println(&quot;待办开始时间:&quot; + getCurrentTime());
    for (int i = 0; i &lt; 1000; i++) {
    AndroidElement daibanElement = driver.findElementsById(&quot;com.xxx.xxx:id/item_content_linear&quot;).get(0);
    daibanElement.click();
    driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
    taskLogin(i);
    }
    System.out.println(&quot;待办结束时间:&quot; + getCurrentTime());
    }
    }

    boolean isFirst = true;

    //待办登录
    // @Test
    public void taskLogin(int time) {
    driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
    if (isFirst) {
    AndroidElement userName = driver.findElementsById(&quot;com.xxx.xxx:id/login_username_edit_text&quot;).get(0);
    userName.sendKeys(&quot;username&quot;);

    driver.hideKeyboard();
    Assert.assertEquals(&quot;username&quot;, userName.getText());
    //等待1秒
    driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    AndroidElement password = driver.findElementById(&quot;com.xxx.xxx:id/login_password_edit_text&quot;);
    if (password.getText().trim().equals(&quot;&quot;)) {
    System.out.println(&quot;password为null&quot;);
    password.click();
    password.sendKeys(&quot;1&quot;);
    //隐藏弹出的键盘
    driver.hideKeyboard();
    }
    isFirst = false;
    }
    driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    //点击登录按钮
    driver.findElementsById(&quot;com.xxx.xxx:id/login_btn&quot;).get(0).click();
    System.out.println(&quot;第 &quot; + time + &quot; 次登录&quot;);
    backTask(time);
    }

    //截图
    public void getScreen(int time) {
    String fileRoute = &quot;/testing/screen/&quot;;
    String picname = fileRoute + String.valueOf(time) + &quot;.png&quot;;
    File screen = driver.getScreenshotAs(OutputType.FILE);
    System.out.println(picname);
    File screenFile = new File(picname);
    try {
    FileUtils.copyFile(screen, screenFile);
    System.out.println(&quot;第 &quot; + time + &quot; 截图&quot;);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

    //从待办列表返回
    public void backTask(int time) {
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    List&lt;AndroidElement&gt; elementsById = driver.findElementsById(&quot;com.xxx.xxx:id/backlog_list_layout&quot;);
    getScreen(time);
    if (null != elementsById &amp;&amp; elementsById.size() &gt; 0) {
    AndroidElement backButton = elementsById.get(0);
    if (backButton.isDisplayed()) {
    backButton.click();
    }
    //长时间操作,可能会出现无法获取到backButton的情况,做判断,list是否为null或者size为0;
    } else if (null == elementsById || elementsById.size() == 0) {
    //等待10秒,直到能找到backButton元素
    getScreen(-1);
    WebDriverWait wait = new WebDriverWait(driver, 10);
    wait.until(new ExpectedCondition&lt;WebElement&gt;() {
    @Override
    public WebElement apply(WebDriver d) {
    return d.findElement(By.id(&quot;com.xxx.xxx:id/backlog_list_layout&quot;));
    }
    });
    driver.findElementsById(&quot;com.xxx.xxx:id/backlog_list_layout&quot;).get(0).click();

    }
    }

    private String getCurrentTime() {
    SimpleDateFormat df = new SimpleDateFormat(&quot;yyyy-MM-dd:HH-mm-ss&quot;);
    return df.format(new Date());
    }


    private void waitForVisible(WebDriver driver, final By by, int waitTime) {
    WebDriverWait wait = new WebDriverWait(driver, waitTime);
    for (int i = 0; i &lt; waitTime; i++) {
    try {
    driver.findElement(by);
    break;
    } catch (Exception e) {
    driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    }
    }
    wait.until(ExpectedConditions.visibilityOfElementLocated(by));
    }
    }
    </code></pre>


    </body>
    </html>
    <!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->

  • 相关阅读:
    “阿基里斯与乌龟”的终结性思考
    这个世界本来的样子
    Seven times have I despised my soul 《我曾七次鄙视自己的灵魂》
    Youth is not a time of life, it is a state of mind.
    对于过去所犯的错误,最好的道歉是在将来做正确的事
    使用UltraISO刻录自己的音乐CD步骤
    为什么一个目录里放超过十个Mp4文件会导致资源管理器和播放程序变卡变慢?
    用Perl发送邮件小例子
    用df命令显示磁盘使用量和占用率。
    三个JS函数闭包(closure)例子
  • 原文地址:https://www.cnblogs.com/liyiran/p/6289896.html
Copyright © 2011-2022 走看看