第 11 期_appium 自动化测试_20200216

环境准备

安装appium
官方文档的安装方式(基本安装不上):

npm install -g appium

淘宝cnpm (最稳定的方法)

npm install -g cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org 
cnpm install -g appium

android sdk: https://developer.android.com/studio#downloads

安装完成的几个关键

  • adb放在了PATH变量下
  • ANDROID_HOME变量为设为sdk的路径
  • java在PATH变量下,可以直接执行

真机或者模拟器

  • 模拟器使用Android Studio或者sdk中的sdkmanager进行创建
  • 真机需要自备
  • 网易mumu模拟器 https://mumu.163.com/
avdmanager list
avdmanager create avd -n test -k "system-images;android-27;google_apis_playstore;x86"
emulator -list-avds

appium python client

第11期——Appium Desktop⽤例录制

演练app:雪球官方新版本-安卓iOS版下载-应用宝官网

app信息
获取当前界面元素:adb shell dumpsys activity top
获取任务列表:adb shell dumpsys activity activities
app入口
adb logcat |grep -i displayed
aapt dump badging mobike.apk | grep launchable-activity
apkanalyzer 最新版本的sdk中才有
启动应用
adb shell am start -W -n com.xueqiu.android/.view.WelcomeActivityAlias -S

adb install -r ~/Downloads/com.xueqiu.android_12.3.2_247.apk

雪球app的入口

com.xueqiu.android/.view.WelcomeActivityAlias

第11期——元素定位⽅法与隐式等待 (ID/AID/XPath)

#绝对定位不推荐:
/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.view.ViewGroup/android.widget.LinearLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.HorizontalScrollView/android.widget.FrameLayout/android.widget.LinearLayout[1]/android.widget.FrameLayout[3]/android.widget.LinearLayout/android.widget.FrameLayout[1]/android.widget.TextView

#相对定位(推荐):
//*[@text='热门' and contains(@resource-id, 'title')]

第11期——常⽤⾃动化api

第11期——⻓按/滑动等TouchAction的应⽤

第11期——⾼级定位 (XPath/UISelector)

class MobileBy(By):
    IOS_PREDICATE = '-ios predicate string'
    IOS_UIAUTOMATION = '-ios uiautomation'
    IOS_CLASS_CHAIN = '-ios class chain'
    ANDROID_UIAUTOMATOR = '-android uiautomator'
    ANDROID_VIEWTAG = '-android viewtag'
    ANDROID_DATA_MATCHER = '-android datamatcher'
    ANDROID_VIEW_MATCHER = '-android viewmatcher'
    WINDOWS_UI_AUTOMATION = '-windows uiautomation'
    ACCESSIBILITY_ID = 'accessibility id'
    IMAGE = '-image'
    CUSTOM = '-custom'

第11期——显式等待机制

第11期——Android Toast识别

    def test_toast(self):
        scroll_to_element = (
            MobileBy.ANDROID_UIAUTOMATOR,
            'new UiScrollable('
                'new UiSelector().scrollable(true).instance(0))'
                '.scrollIntoView('
                    'new UiSelector().text("Views").instance(0));')
        self.driver.find_element(*scroll_to_element).click()

        scroll_to_element = (
            MobileBy.ANDROID_UIAUTOMATOR,
            'new UiScrollable('
                'new UiSelector().scrollable(true).instance(0))'
                '.scrollIntoView('
                    'new UiSelector().text("Popup Menu").instance(0));')
        self.driver.find_element(*scroll_to_element).click()
        # self.driver.find_element(By.XPATH, "//*[@text='MAKE A POPUP!']").click()
        self.driver.find_element(MobileBy.ACCESSIBILITY_ID, "Make a Popup!").click()
        self.driver.find_element(By.XPATH, "//*[@text='Search']").click()
        toast=self.driver.find_element(By.XPATH, "//*[@class='android.widget.Toast']").text
        assert "Search" in toast
        assert "Clicked" in toast

第11期——UI属性断⾔与hamcrest断⾔

public enum Attribute {
    CHECKABLE(new String[]{"checkable"}),
    CHECKED(new String[]{"checked"}),
    CLASS(new String[]{"class", "className"}),
    CLICKABLE(new String[]{"clickable"}),
    CONTENT_DESC(new String[]{"content-desc", "contentDescription"}),
    ENABLED(new String[]{"enabled"}),
    FOCUSABLE(new String[]{"focusable"}),
    FOCUSED(new String[]{"focused"}),
    LONG_CLICKABLE(new String[]{"long-clickable", "longClickable"}),
    PACKAGE(new String[]{"package"}),
    PASSWORD(new String[]{"password"}),
    RESOURCE_ID(new String[]{"resource-id", "resourceId"}),
    SCROLLABLE(new String[]{"scrollable"}),
    SELECTION_START(new String[]{"selection-start"}),
    SELECTION_END(new String[]{"selection-end"}),
    SELECTED(new String[]{"selected"}),
    TEXT(new String[]{"text", "name"}),
    // The main difference of this attribute from the preceding one is that
    // it does not replace null values with empty strings
    ORIGINAL_TEXT(new String[]{"original-text"}, false, false),
    BOUNDS(new String[]{"bounds"}),
    INDEX(new String[]{"index"}, false, true),
    DISPLAYED(new String[]{"displayed"}),
    CONTENT_SIZE(new String[]{"contentSize"}, true, false);

第11期——参数化与数据驱动应⽤ CSV/Excel/Json/Yaml

作业1

分析appium的log,提取所有的appium调用的命令,对每个命令,分析他的用途。
拔高部分:把每个命令的执行时间也打印下

作业2

搜索股票,点击股票分类,选择香港上市的阿里巴巴股票(根据xpath,而不是顺序),断言股价大于200

作业3

添加某只股票到自选,然后再次搜索并验证,股票已经加入自选。(不要使用文字内容判断,使用get attribute)