• 论测试工程师的职责 at May 25, 2020

    这几张图值得存下来👍

  • 作业1

    class TestXueqiu:
    def setup(self):
    self.__init_app()

    # 常用元素
    self.__search_locator = (MobileBy.ID, 'tv_search')
    self.__search_input_locator = (MobileBy.ID, 'search_input_text')
    self.__trade_locator = (MobileBy.XPATH, '//*[contains(@resource-id, "tab_name") and @text="交易"]')

    def __init_app(self):
    caps = {}
    caps['deviceName'] = 'xu'
    caps['platformName'] = 'Android'
    caps['appPackage'] = 'com.xueqiu.android'
    caps['appActivity'] = '.view.WelcomeActivityAlias'

    # 重置数据
    caps['noReset'] = True
    # 不关闭app
    caps['dontStopAppOnReset'] = True
    # 使用中文
    caps['unicodeKeyboard'] = True
    # 重置键盘
    caps['resetKeyboard'] = True
    # 初始安装就可
    caps['skipServerInstallation'] = True

    self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', caps)
    self.driver.implicitly_wait(10)

    def find(self, by, value=None):
    if isinstance(by, tuple):
    return self.driver.find_element(*by)
    return self.driver.find_element(by, value)

    def test_webview_context(self):
    # 点击交易页
    self.find(self.__trade_locator).click()

    # 切换到webview
    WebDriverWait(self.driver, 30).until(lambda x: len(self.driver.contexts) > 1)
    self.driver.switch_to.context(self.driver.contexts[-1])

    # 港美股开户
    self.find(By.CSS_SELECTOR, '.trade_home_info_3aI>*[text="港美股开户"]').click()
    # 跳转另一个页面
    WebDriverWait(self.driver, 30).until(lambda x: len(self.driver.window_handles) > 3)
    self.driver.switch_to.window(self.driver.window_handles[-1])
    # 输入手机号与错误的验证码,点击确认
    # 等待页面加载完成
    phone_locator = (By.CSS_SELECTOR, 'input[placeholder="请输入手机号"]')
    WebDriverWait(self.driver, 30).until(expected_conditions.visibility_of_element_located(phone_locator))
    self.find(phone_locator).send_keys('13511112222')
    self.find(By.CSS_SELECTOR, 'input[placeholder="请输入验证码"]').send_keys('1234')
    self.find(By.CSS_SELECTOR, '.open_form-submit_1Ms[text=立即开户]').click()

    # 切换回原生
    self.driver.switch_to.context(self.driver.contexts[0])
    # 点击关闭回到交易页
    self.find(MobileBy.ID, 'action_bar_back').click()

    def teardown(self):
    # pass
    time.sleep(10)
    self.driver.quit()

  • 作业1

    testcase - test_market

    class TestMarket:
    def setup(self):
    self.market = App().start().main().goto_market_quotations_page()

    def test_market_quotations_add_follow(self):
    # 进入行情-点击搜索-添加自选-返回
    self.market.goto_search_page().search('阿里').add_follow('09988').search_close()

    def teardown(self):
    pass

    page - main - goto_market_quotations_page

    class Main(BasePage):
    _search_locator = (MobileBy.ID, 'tv_search')
    _profile_locator = (MobileBy.XPATH, '//*[contains(@resource-id, "tab_name") and @text="我的"]')
    _market_locator = (MobileBy.XPATH, '//*[contains(@resource-id, "tab_name") and @text="行情"]')

    def goto_market_quotations_page(self):
    self.find(self._market_locator).click()
    return Market(self._driver)

    page - market

    class Market(BasePage):
    _search_locator = (MobileBy.ID, 'action_search')

    def goto_search_page(self):
    self.find(self._search_locator).click()
    return Search(self._driver)

    page - search


    class Search(BasePage):

    _search_input_locator = (MobileBy.ID, 'search_input_text')
    _stock_btn_locator = (
    MobileBy.XPATH, '//*[contains(@resource-id, "title_container")]/android.widget.TextView[@text="股票"]')

    def search(self, key: string):
    # 搜索指定内容
    self.find(self._search_input_locator).clear()
    self.find(self._search_input_locator).send_keys(key)
    # 点击第一条搜索结果
    self.find(MobileBy.ID, 'name').click()

    return self

    def search_close(self):
    self.find(MobileBy.ID, 'action_close').click()
    return self

    def add_follow(self, stock_type):
    follow_btn_locator = (MobileBy.XPATH,
    '//*[contains(@resource-id, "stockCode") and @text="%s"]/../../..//*[contains(@resource-id, "follow_btn")]' % stock_type)

    # 点击股票分类
    self.find(self._stock_btn_locator).click()
    # 点击加自选按钮
    self.find(follow_btn_locator).click()

    return self
  • 作业1

    # 加载启动参数,启动appium-server给出http地址
    2020-02-28 22:20:56:214 [Appium] Welcome to Appium v1.16.0
    2020-02-28 22:20:56:216 [Appium] Non-default server args:
    2020-02-28 22:20:56:217 [Appium] logFile: appium.log
    2020-02-28 22:20:56:218 [Appium] logTimestamp: true
    2020-02-28 22:20:56:218 [Appium] localTimezone: true
    2020-02-28 22:20:56:259 [Appium] Appium REST http interface listener started on 0.0.0.0:4723
    # 接收到client端连接请求和携带的capabilities参数
    2020-02-28 22:25:00:647 [HTTP] --> POST /wd/hub/session
    2020-02-28 22:25:00:648 [HTTP] {"capabilities":{"firstMatch":[{"appium:deviceName":"xu","platformName":"Android","appium:appPackage":"com.xueqiu.android","appium:appActivity":".view.WelcomeActivityAlias","appium:dontStopAppOnReset":true,"appium:unicodeKeyboard":true,"appium:resetKeyboard":true}]},"desiredCapabilities":{"deviceName":"xu","platformName":"Android","appPackage":"com.xueqiu.android","appActivity":".view.WelcomeActivityAlias","dontStopAppOnReset":true,"unicodeKeyboard":true,"resetKeyboard":true}}
    2020-02-28 22:25:00:652 [W3C] Calling AppiumDriver.createSession() with args: [{"deviceName":"xu","platformName":"Android","appPackage":"com.xueqiu.android","appActivity":".view.WelcomeActivityAlias","dontStopAppOnReset":true,"unicodeKeyboard":true,"resetKeyboard":true},null,{"firstMatch":[{"appium:deviceName":"xu","platformName":"Android","appium:appPackage":"com.xueqiu.android","appium:appActivity":".view.WelcomeActivityAlias","appium:dontStopAppOnReset":true,"appium:unicodeKeyboard":true,"appium:resetKeyboard":true}]}]
    2020-02-28 22:25:00:653 [BaseDriver] Event 'newSessionRequested' logged at 1582899900653 (22:25:00 GMT+0800 (GMT+08:00))
    # 根据client的配置参数,调用Uiautomator2引擎创建session用于后面其他操作
    2020-02-28 22:25:07:920 [Appium] Appium v1.16.0 creating new AndroidUiautomator2Driver (v1.44.2) session
    2020-02-28 22:25:07:930 [BaseDriver] W3C capabilities and MJSONWP desired capabilities were provided
    2020-02-28 22:25:07:931 [BaseDriver] Creating session with W3C capabilities: {
    2020-02-28 22:25:07:932 [BaseDriver] "alwaysMatch": {
    2020-02-28 22:25:07:933 [BaseDriver] "platformName": "Android",
    2020-02-28 22:25:07:934 [BaseDriver] "appium:deviceName": "xu",
    2020-02-28 22:25:07:934 [BaseDriver] "appium:appPackage": "com.xueqiu.android",
    2020-02-28 22:25:07:935 [BaseDriver] "appium:appActivity": ".view.WelcomeActivityAlias",
    2020-02-28 22:25:07:936 [BaseDriver] "appium:dontStopAppOnReset": true,
    2020-02-28 22:25:07:937 [BaseDriver] "appium:unicodeKeyboard": true,
    2020-02-28 22:25:07:937 [BaseDriver] "appium:resetKeyboard": true
    2020-02-28 22:25:07:938 [BaseDriver] },
    2020-02-28 22:25:07:938 [BaseDriver] "firstMatch": [
    2020-02-28 22:25:07:938 [BaseDriver] {}
    2020-02-28 22:25:07:939 [BaseDriver] ]
    2020-02-28 22:25:07:939 [BaseDriver] }
    2020-02-28 22:25:07:958 [BaseDriver] Session created with session id: 5c88be64-a177-4c04-8a55-fed284b25e36
    # UiAutomator2启动配置的app
    2020-02-28 22:25:07:963 [UiAutomator2] Starting 'com.xueqiu.android' directly on the device
    # 根据环境变量的配置找到系统的build-toolsadb工具
    2020-02-28 22:25:07:973 [ADB] Found 1 'build-tools' folders under 'F:\android\android-sdk' (newest first):
    2020-02-28 22:25:07:974 [ADB] F:/android/android-sdk/build-tools/29.0.3
    2020-02-28 22:25:07:989 [ADB] Using 'adb.exe' from 'F:\android\android-sdk\platform-tools\adb.exe'
    # 查找系统中的可用android设备,查找成功后进行连接
    2020-02-28 22:25:07:989 [AndroidDriver] Retrieving device list
    2020-02-28 22:25:07:990 [ADB] Trying to find a connected android device
    2020-02-28 22:25:07:990 [ADB] Getting connected devices...
    2020-02-28 22:25:08:765 [ADB] Connected devices: [{"udid":"127.0.0.1:7555","state":"device"}]
    # 确认使用的设备和adb,设置本设备的id
    2020-02-28 22:25:08:766 [AndroidDriver] Using device: 127.0.0.1:7555
    2020-02-28 22:25:08:767 [ADB] Using 'adb.exe' from 'F:\android\android-sdk\platform-tools\adb.exe'
    2020-02-28 22:25:08:767 [ADB] Setting device id to 127.0.0.1:7555
    # 检查当前sdk版本是否能够使用
    2020-02-28 22:25:08:768 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell getprop ro.build.version.sdk'
    2020-02-28 22:25:09:203 [ADB] Current device property 'ro.build.version.sdk': 23
    2020-02-28 22:25:09:203 [ADB] Device API level: 23
    # 确认是否有需要安装的包
    2020-02-28 22:25:09:204 [AndroidDriver] No app sent in, not parsing package/activity
    2020-02-28 22:25:09:205 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 wait-for-device'
    2020-02-28 22:25:09:445 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell echo ping'
    # 确认设备上是否安装io.appium.settings,若已安装,确认版本是否正确、是否需要升级、是否正在运行
    2020-02-28 22:25:09:652 [AndroidDriver] Pushing settings apk to device...
    2020-02-28 22:25:09:653 [ADB] Getting install status for io.appium.settings
    2020-02-28 22:25:09:653 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell dumpsys package io.appium.settings'
    2020-02-28 22:25:09:900 [ADB] 'io.appium.settings' is installed
    2020-02-28 22:25:09:900 [ADB] Getting package info for 'io.appium.settings'
    2020-02-28 22:25:09:900 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell dumpsys package io.appium.settings'
    2020-02-28 22:25:10:152 [ADB] The version name of the installed 'io.appium.settings' is greater or equal to the application version name ('3.1.0' >= '3.1.0')
    2020-02-28 22:25:10:153 [ADB] There is no need to install/upgrade 'C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\node_modules\_io.appium.settings@3.1.0@io.appium.settings\apks\settings_apk-debug.apk'
    2020-02-28 22:25:10:153 [ADB] Getting IDs of all 'io.appium.settings' processes
    2020-02-28 22:25:10:154 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell 'pgrep --help; echo $?''
    2020-02-28 22:25:10:328 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell pgrep -f io\\.appium\\.settings'
    2020-02-28 22:25:10:530 [AndroidDriver] io.appium.settings is already running. There is no need to reset its permissions.
    2020-02-28 22:25:10:531 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell appops set io.appium.settings android\:mock_location allow'
    # 开始记录设备上操作的日志,根据client指示启动Unicode keyboard
    2020-02-28 22:25:13:906 [Logcat] Starting logcat capture
    2020-02-28 22:25:14:075 [AndroidDriver] Enabling Unicode keyboard support
    2020-02-28 22:25:14:075 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell settings get secure default_input_method'
    2020-02-28 22:25:14:929 [AndroidDriver] Unsetting previous IME io.appium.settings/.UnicodeIME
    2020-02-28 22:25:14:929 [AndroidDriver] Setting IME to 'io.appium.settings/.UnicodeIME'
    2020-02-28 22:25:14:930 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell ime enable io.appium.settings/.UnicodeIME'
    2020-02-28 22:25:15:564 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell ime set io.appium.settings/.UnicodeIME'
    # 通过UiAutomator2 Server将本系统8204端口转发到待测设备的端口6790
    2020-02-28 22:25:16:558 [UiAutomator2] Forwarding UiAutomator2 Server port 6790 to 8204
    2020-02-28 22:25:16:559 [ADB] Forwarding system: 8204 to device: 6790
    2020-02-28 22:25:16:560 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 forward tcp\:8204 tcp\:6790'
    # 确认io.appium.uiautomator2.server是否正常安装,若已安装,确认版本是否正确
    2020-02-28 22:25:16:826 [ADB] Getting install status for io.appium.uiautomator2.server
    2020-02-28 22:25:16:826 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell dumpsys package io.appium.uiautomator2.server'
    2020-02-28 22:25:17:041 [ADB] 'io.appium.uiautomator2.server' is installed
    2020-02-28 22:25:17:041 [ADB] Getting package info for 'io.appium.uiautomator2.server'
    2020-02-28 22:25:17:041 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell dumpsys package io.appium.uiautomator2.server'
    2020-02-28 22:25:17:279 [ADB] The version name of the installed 'io.appium.uiautomator2.server' is greater or equal to the application version name ('4.5.5' >= '4.5.5')
    2020-02-28 22:25:17:280 [UiAutomator2] io.appium.uiautomator2.server installation state: sameVersionInstalled
    # 通过uiautomator2.serverapp进行签名
    2020-02-28 22:25:17:282 [ADB] Checking app cert for C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\node_modules\_appium-uiautomator2-server@4.5.5@appium-uiautomator2-server\apks\appium-uiautomator2-server-v4.5.5.apk
    2020-02-28 22:25:17:289 [ADB] Using 'apksigner.bat' from 'F:\android\android-sdk\build-tools\29.0.3\apksigner.bat'
    2020-02-28 22:25:17:290 [ADB] Starting 'F:\android\android-sdk\build-tools\29.0.3\apksigner.bat' with args '["verify","--print-certs","C:\\Users\\Administrator\\AppData\\Roaming\\npm\\node_modules\\appium\\node_modules\\_appium-uiautomator2-server@4.5.5@appium-uiautomator2-server\\apks\\appium-uiautomator2-server-v4.5.5.apk"]'
    2020-02-28 22:25:24:253 [ADB] apksigner stdout: Signer #1 certificate DN: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
    2020-02-28 22:25:24:254 [ADB] Signer #1 certificate SHA-256 digest: a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc
    2020-02-28 22:25:24:254 [ADB] Signer #1 certificate SHA-1 digest: 61ed377e85d386a8dfee6b864bd85b0bfaa5af81
    2020-02-28 22:25:24:255 [ADB] Signer #1 certificate MD5 digest: e89b158e4bcf988ebd09eb83f5378e87
    # 确认io.appium.uiautomator2.server.test是否正常安装,使用其检测io.appium.uiautomator2.server
    2020-02-28 22:25:24:255 [ADB]
    2020-02-28 22:25:24:255 [ADB] 'C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\node_modules\_appium-uiautomator2-server@4.5.5@appium-uiautomator2-server\apks\appium-uiautomator2-server-v4.5.5.apk' is already signed.
    2020-02-28 22:25:24:255 [ADB] Getting install status for io.appium.uiautomator2.server.test
    2020-02-28 22:25:24:256 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell dumpsys package io.appium.uiautomator2.server.test'
    2020-02-28 22:25:24:500 [ADB] 'io.appium.uiautomator2.server.test' is installed
    2020-02-28 22:25:24:500 [ADB] Checking app cert for C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\node_modules\_appium-uiautomator2-server@4.5.5@appium-uiautomator2-server\apks\appium-uiautomator2-server-debug-androidTest.apk
    2020-02-28 22:25:24:501 [ADB] Starting 'F:\android\android-sdk\build-tools\29.0.3\apksigner.bat' with args '["verify","--print-certs","C:\\Users\\Administrator\\AppData\\Roaming\\npm\\node_modules\\appium\\node_modules\\_appium-uiautomator2-server@4.5.5@appium-uiautomator2-server\\apks\\appium-uiautomator2-server-debug-androidTest.apk"]'
    2020-02-28 22:25:26:798 [ADB] apksigner stdout: Signer #1 certificate DN: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
    2020-02-28 22:25:26:799 [ADB] Signer #1 certificate SHA-256 digest: a40da80a59d170caa950cf15c18c454d47a39b26989d8b640ecd745ba71bf5dc
    2020-02-28 22:25:26:799 [ADB] Signer #1 certificate SHA-1 digest: 61ed377e85d386a8dfee6b864bd85b0bfaa5af81
    2020-02-28 22:25:26:799 [ADB] Signer #1 certificate MD5 digest: e89b158e4bcf988ebd09eb83f5378e87
    # 等待uiautomator2服务可用
    2020-02-28 22:25:26:799 [ADB]
    2020-02-28 22:25:26:800 [ADB] 'C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\node_modules\_appium-uiautomator2-server@4.5.5@appium-uiautomator2-server\apks\appium-uiautomator2-server-debug-androidTest.apk' is already signed.
    2020-02-28 22:25:26:800 [UiAutomator2] Server packages are not going to be (re)installed
    2020-02-28 22:25:26:803 [UiAutomator2] Waiting up to 30000ms for services to be available
    2020-02-28 22:25:26:804 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell pm list instrumentation'
    2020-02-28 22:25:27:465 [UiAutomator2] Instrumentation target 'io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner' is available
    2020-02-28 22:25:27:466 [UiAutomator2] No app capability. Assuming it is already on the device
    # 检测被测app是否安装,已安装则关闭和清理数据
    2020-02-28 22:25:27:466 [ADB] Getting install status for com.xueqiu.android
    2020-02-28 22:25:27:467 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell dumpsys package com.xueqiu.android'
    2020-02-28 22:25:32:985 [ADB] 'com.xueqiu.android' is installed
    2020-02-28 22:25:32:985 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell am force-stop com.xueqiu.android'
    2020-02-28 22:25:33:598 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell pm clear com.xueqiu.android'
    2020-02-28 22:25:34:673 [AndroidDriver] Performed fast reset on the installed 'com.xueqiu.android' application (stop and clear)
    2020-02-28 22:25:34:674 [UiAutomator2] Performing shallow cleanup of automation leftovers
    2020-02-28 22:25:34:757 [UiAutomator2] The following obsolete sessions are still running: ["59c5e142-6095-4479-8a22-222e5ef9ad3a"]
    2020-02-28 22:25:34:758 [UiAutomator2] Cleaning up the obsolete sessions
    2020-02-28 22:25:35:823 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell am force-stop io.appium.uiautomator2.server.test'
    # UIAutomator2 server启动
    2020-02-28 22:25:36:450 [UiAutomator2] Starting UIAutomator2 server 4.5.5
    2020-02-28 22:25:36:450 [UiAutomator2] Using UIAutomator2 server from 'C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\node_modules\_appium-uiautomator2-server@4.5.5@appium-uiautomator2-server\apks\appium-uiautomator2-server-v4.5.5.apk' and test from 'C:\Users\Administrator\AppData\Roaming\npm\node_modules\appium\node_modules\_appium-uiautomator2-server@4.5.5@appium-uiautomator2-server\apks\appium-uiautomator2-server-debug-androidTest.apk'
    2020-02-28 22:25:36:451 [UiAutomator2] Waiting up to 30000ms for UiAutomator2 to be online...
    2020-02-28 22:25:36:453 [ADB] Creating ADB subprocess with args: ["-P",5037,"-s","127.0.0.1:7555","shell","am","instrument","-w","io.appium.uiautomator2.server.test/androidx.test.runner.AndroidJUnitRunner"]
    # 使用io.appium.uiautomator2.server.test.AppiumUiAutomator2Server测试能否正常与被测app通信
    2020-02-28 22:25:37:361 [Instrumentation] io.appium.uiautomator2.server.test.AppiumUiAutomator2Server:
    2020-02-28 22:25:37:598 [WD Proxy] Matched '/status' to command name 'getStatus'
    2020-02-28 22:25:37:602 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8204/wd/hub/status] with no body
    2020-02-28 22:25:37:636 [WD Proxy] Got response with unknown status: {"code":"ECONNRESET"}
    2020-02-28 22:25:38:639 [WD Proxy] Matched '/status' to command name 'getStatus'
    2020-02-28 22:25:38:639 [WD Proxy] Proxying [GET /status] to [GET http://127.0.0.1:8204/wd/hub/status] with no body
    2020-02-28 22:25:38:714 [WD Proxy] Got response with status 200: {"sessionId":"None","value":{"ready":true,"message":"UiAutomator2 Server is ready to accept commands"}}
    2020-02-28 22:25:38:715 [UiAutomator2] The initialization of the instrumentation process took 2264ms
    # 发送请求到app,根据client参数进行初始化设置,并且获取一些设备系统数据
    2020-02-28 22:25:38:715 [WD Proxy] Matched '/session' to command name 'createSession'
    2020-02-28 22:25:38:715 [WD Proxy] Proxying [POST /session] to [POST http://127.0.0.1:8204/wd/hub/session] with body: {"capabilities":{"firstMatch":[{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"Android","deviceName":"xu","appPackage":"com.xueqiu.android","appActivity":".view.WelcomeActivityAlias","dontStopAppOnReset":true,"unicodeKeyboard":true,"resetKeyboard":true},"platformName":"Android","deviceName":"127.0.0.1:7555","appPackage":"com.xueqiu.android","appActivity":".view.WelcomeActivityAlias","dontStopAppOnReset":true,"unicodeKeyboard":true,"resetKeyboard":true,"deviceUDID":"127.0.0.1:7555"}],"alwaysMatch":{}}}
    2020-02-28 22:25:38:725 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":{"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","capabilities":{"firstMatch":[{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"Android","deviceName":"xu","appPackage":"com.xueqiu.android","appActivity":".view.WelcomeActivityAlias","dontStopAppOnReset":true,"unicodeKeyboard":true,"resetKeyboard":true},"platformName":"Android","deviceName":"127.0.0.1:7555","appPackage":"com.xueqiu.android","appActivity":".view.WelcomeActivityAlias","dontStopAppOnReset":true,"unicodeKeyboard":true,"resetKeyboard":true,"deviceUDID":"127.0.0.1:7555"}],"alwaysMatch":{}}}}
    2020-02-28 22:25:38:725 [WD Proxy] Determined the downstream protocol as 'W3C'
    2020-02-28 22:25:38:736 [WD Proxy] Proxying [GET /appium/device/info] to [GET http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/appium/device/info] with no body
    2020-02-28 22:25:38:855 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":{"androidId":"deb5fd5ae5cda16b","manufacturer":"Netease","model":"MuMu","brand":"Android","apiVersion":"23","platformVersion":"6.0.1","carrierName":"","realDisplaySize":"576x1024","displayDensity":192,"networks":[{"type":1,"typeName":"WIFI","subtype":0,"subtypeName":"","isConnected":true,"detailedState":"CONNECTED","state":"CONNECTED","extraInfo":"\"ywdx8k\"","isAvailable":true,"isFailover":false,"isRoaming":false,"capabilities":{"transportTypes":"TRANSPORT_WIFI","networkCapabilities":"NET_CAPABILITY_NOT_RESTRICTED,NET_CAPABILITY_NOT_VPN,NET_CAPABILITY_INTERNET,NET_CAPABILITY_TRUSTED,NET_CAPABILITY_VALIDATED","linkUpstreamBandwidthKbps":1048576,"linkDownBandwidthKbps":1048576,"signalStrength":-55,"networkSpecifier":null,"SSID":null}}],"locale":"zh_CN","timeZone":"Asia\/Shanghai","bluetooth":{"state":"OFF"}}}
    2020-02-28 22:25:38:857 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell dumpsys window'
    2020-02-28 22:25:39:123 [AndroidDriver] Screen already unlocked, doing nothing
    2020-02-28 22:25:39:123 [UiAutomator2] Starting 'com.xueqiu.android/.view.WelcomeActivityAlias and waiting for 'com.xueqiu.android/.view.WelcomeActivityAlias'
    2020-02-28 22:25:39:124 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell am start -W -n com.xueqiu.android/.view.WelcomeActivityAlias -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000'
    2020-02-28 22:25:50:454 [WD Proxy] Proxying [GET /appium/device/pixel_ratio] to [GET http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/appium/device/pixel_ratio] with body: {}
    2020-02-28 22:25:51:138 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":1.2}
    2020-02-28 22:25:51:140 [WD Proxy] Matched '/appium/device/system_bars' to command name 'getSystemBars'
    2020-02-28 22:25:51:141 [WD Proxy] Proxying [GET /appium/device/system_bars] to [GET http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/appium/device/system_bars] with body: {}
    2020-02-28 22:25:51:240 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":{"statusBar":29}}
    2020-02-28 22:25:51:242 [WD Proxy] Matched '/window/current/size' to command name 'getWindowSize'
    2020-02-28 22:25:51:243 [WD Proxy] Proxying [GET /window/current/size] to [GET http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/window/current/size] with body: {}
    2020-02-28 22:25:51:257 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":{"height":1024,"width":576}}
    2020-02-28 22:25:51:258 [Appium] New AndroidUiautomator2Driver session created successfully, session 5c88be64-a177-4c04-8a55-fed284b25e36 added to master session list
    2020-02-28 22:25:51:260 [BaseDriver] Event 'newSessionStarted' logged at 1582899951259 (22:25:51 GMT+0800 (GMT+08:00))
    2020-02-28 22:25:51:261 [W3C (5c88be64)] Cached the protocol value 'W3C' for the new session 5c88be64-a177-4c04-8a55-fed284b25e36
    2020-02-28 22:25:51:262 [W3C (5c88be64)] Responding to client with driver.createSession() result: {"capabilities":{"platform":"LINUX","webStorageEnabled":false,"takesScreenshot":true,"javascriptEnabled":true,"databaseEnabled":false,"networkConnectionEnabled":true,"locationContextEnabled":false,"warnings":{},"desired":{"platformName":"Android","deviceName":"xu","appPackage":"com.xueqiu.android","appActivity":".view.WelcomeActivityAlias","dontStopAppOnReset":true,"unicodeKeyboard":true,"resetKeyboard":true},"platformName":"Android","deviceName":"127.0.0.1:7555","appPackage":"com.xueqiu.android","appActivity":".view.WelcomeActivityAlias","dontStopAppOnReset":true,"unicodeKeyboard":true,"resetKeyboard":true,"deviceUDID":"127.0.0.1:7555","deviceApiLevel":23,"platformVersion":"6.0.1","deviceScreenSize":"576x1024","deviceScreenDensity":192,"deviceModel":"MuMu","deviceManufacturer":"Netease","pixelRatio":1.2,"statBarHeight":29,"viewportRect":{"left":0,"top":29,"width":576,"height":995}}}
    2020-02-28 22:25:51:269 [HTTP] <-- POST /wd/hub/session 200 50621 ms - 957
    2020-02-28 22:25:51:270 [HTTP]
    2020-02-28 22:25:51:272 [HTTP] --> POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/timeouts
    # client指定的隐式等待时间
    2020-02-28 22:25:51:272 [HTTP] {"implicit":10000}
    2020-02-28 22:25:51:275 [W3C (5c88be64)] Calling AppiumDriver.timeouts() with args: [null,null,null,null,10000,"5c88be64-a177-4c04-8a55-fed284b25e36"]
    2020-02-28 22:25:51:276 [BaseDriver] W3C timeout argument: {"implicit":10000}}
    2020-02-28 22:25:51:277 [BaseDriver] Set implicit wait to 10000ms
    2020-02-28 22:25:51:277 [W3C (5c88be64)] Responding to client with driver.timeouts() result: null
    2020-02-28 22:25:51:279 [HTTP] <-- POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/timeouts 200 6 ms - 14
    2020-02-28 22:25:51:279 [HTTP]
    # 执行用例中的操作,获取element进行操作,且将操作结果返回
    2020-02-28 22:26:31:281 [HTTP] --> POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element
    2020-02-28 22:26:31:282 [HTTP] {"using":"id","value":"tv_agree"}
    2020-02-28 22:26:31:284 [W3C (5c88be64)] Calling AppiumDriver.findElement() with args: ["id","tv_agree","5c88be64-a177-4c04-8a55-fed284b25e36"]
    2020-02-28 22:26:31:284 [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
    2020-02-28 22:26:31:285 [BaseDriver] Waiting up to 10000 ms for condition
    2020-02-28 22:26:31:286 [WD Proxy] Matched '/element' to command name 'findElement'
    2020-02-28 22:26:31:286 [WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/element] with body: {"strategy":"id","selector":"tv_agree","context":"","multiple":false}
    2020-02-28 22:26:32:169 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":{"ELEMENT":"65383a94-c37e-4eb9-8c14-10f0cc936654","element-6066-11e4-a52e-4f735466cecf":"65383a94-c37e-4eb9-8c14-10f0cc936654"}}
    2020-02-28 22:26:32:170 [W3C (5c88be64)] Responding to client with driver.findElement() result: {"element-6066-11e4-a52e-4f735466cecf":"65383a94-c37e-4eb9-8c14-10f0cc936654","ELEMENT":"65383a94-c37e-4eb9-8c14-10f0cc936654"}
    2020-02-28 22:26:32:171 [HTTP] <-- POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element 200 889 ms - 137
    2020-02-28 22:26:32:171 [HTTP]
    2020-02-28 22:26:32:173 [HTTP] --> POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element/65383a94-c37e-4eb9-8c14-10f0cc936654/click
    2020-02-28 22:26:32:174 [HTTP] {"id":"65383a94-c37e-4eb9-8c14-10f0cc936654"}
    2020-02-28 22:26:32:175 [W3C (5c88be64)] Calling AppiumDriver.click() with args: ["65383a94-c37e-4eb9-8c14-10f0cc936654","5c88be64-a177-4c04-8a55-fed284b25e36"]
    2020-02-28 22:26:32:176 [WD Proxy] Matched '/element/65383a94-c37e-4eb9-8c14-10f0cc936654/click' to command name 'click'
    2020-02-28 22:26:32:176 [WD Proxy] Proxying [POST /element/65383a94-c37e-4eb9-8c14-10f0cc936654/click] to [POST http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/element/65383a94-c37e-4eb9-8c14-10f0cc936654/click] with body: {"element":"65383a94-c37e-4eb9-8c14-10f0cc936654"}
    2020-02-28 22:26:32:254 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":null}
    2020-02-28 22:26:32:255 [W3C (5c88be64)] Responding to client with driver.click() result: null
    2020-02-28 22:26:32:255 [HTTP] <-- POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element/65383a94-c37e-4eb9-8c14-10f0cc936654/click 200 82 ms - 14
    2020-02-28 22:26:32:256 [HTTP]
    2020-02-28 22:26:32:257 [HTTP] --> POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element
    2020-02-28 22:26:32:258 [HTTP] {"using":"id","value":"tv_search"}
    2020-02-28 22:26:32:258 [W3C (5c88be64)] Calling AppiumDriver.findElement() with args: ["id","tv_search","5c88be64-a177-4c04-8a55-fed284b25e36"]
    2020-02-28 22:26:32:259 [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
    2020-02-28 22:26:32:259 [BaseDriver] Waiting up to 10000 ms for condition
    2020-02-28 22:26:32:259 [WD Proxy] Matched '/element' to command name 'findElement'
    2020-02-28 22:26:32:259 [WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/element] with body: {"strategy":"id","selector":"tv_search","context":"","multiple":false}
    2020-02-28 22:26:32:672 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":{"ELEMENT":"049549c3-f514-4df7-b718-478eab5e3359","element-6066-11e4-a52e-4f735466cecf":"049549c3-f514-4df7-b718-478eab5e3359"}}
    2020-02-28 22:26:32:672 [W3C (5c88be64)] Responding to client with driver.findElement() result: {"element-6066-11e4-a52e-4f735466cecf":"049549c3-f514-4df7-b718-478eab5e3359","ELEMENT":"049549c3-f514-4df7-b718-478eab5e3359"}
    2020-02-28 22:26:32:673 [HTTP] <-- POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element 200 415 ms - 137
    2020-02-28 22:26:32:674 [HTTP]
    2020-02-28 22:26:32:675 [HTTP] --> POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element/049549c3-f514-4df7-b718-478eab5e3359/click
    2020-02-28 22:26:32:675 [HTTP] {"id":"049549c3-f514-4df7-b718-478eab5e3359"}
    2020-02-28 22:26:32:676 [W3C (5c88be64)] Calling AppiumDriver.click() with args: ["049549c3-f514-4df7-b718-478eab5e3359","5c88be64-a177-4c04-8a55-fed284b25e36"]
    2020-02-28 22:26:32:677 [WD Proxy] Matched '/element/049549c3-f514-4df7-b718-478eab5e3359/click' to command name 'click'
    2020-02-28 22:26:32:677 [WD Proxy] Proxying [POST /element/049549c3-f514-4df7-b718-478eab5e3359/click] to [POST http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/element/049549c3-f514-4df7-b718-478eab5e3359/click] with body: {"element":"049549c3-f514-4df7-b718-478eab5e3359"}
    2020-02-28 22:26:34:347 [WD Proxy] Got response with status 200: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":null}
    2020-02-28 22:26:34:347 [W3C (5c88be64)] Responding to client with driver.click() result: null
    2020-02-28 22:26:34:348 [HTTP] <-- POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element/049549c3-f514-4df7-b718-478eab5e3359/click 200 1673 ms - 14
    2020-02-28 22:26:34:348 [HTTP]
    2020-02-28 22:26:34:350 [HTTP] --> POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element
    2020-02-28 22:26:34:350 [HTTP] {"using":"id","value":"search_input_text"}
    2020-02-28 22:26:34:351 [W3C (5c88be64)] Calling AppiumDriver.findElement() with args: ["id","search_input_text","5c88be64-a177-4c04-8a55-fed284b25e36"]
    2020-02-28 22:26:34:351 [BaseDriver] Valid locator strategies for this request: xpath, id, class name, accessibility id, -android uiautomator
    2020-02-28 22:26:34:352 [BaseDriver] Waiting up to 10000 ms for condition
    2020-02-28 22:26:34:352 [WD Proxy] Matched '/element' to command name 'findElement'
    2020-02-28 22:26:34:352 [WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/element] with body: {"strategy":"id","selector":"search_input_text","context":"","multiple":false}
    2020-02-28 22:26:35:352 [WD Proxy] Got response with status 404: {"sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":{"error":"no such element","message":"An element could not be located on the page using the given search parameters","stacktrace":"io.appium.uiautomator2.common.exceptions.ElementNotFoundException: An element could not be located on the page using the given search parameters\n\tat io.appium.uiautomator2.handler.FindElement.safeHandle(FindElement.java:78)\n\tat io.appium.uiautomator2.handler.request.SafeRequestHandler.handle(SafeRequestHandler.java:38)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleRequest(AppiumServlet.java:252)\n\tat io.appium.uiautomator2.server.AppiumServlet.handleHttpRequest(AppiumServlet.java:242)\n\tat io.appium.uiautomator2.http.ServerHandler.channelRead(ServerHandler.java:51)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:366)\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:352)\n\tat io.netty.chann...
    2020-02-28 22:26:35:352 [W3C] Matched W3C error code 'no such element' to NoSuchElementError
    2020-02-28 22:26:35:353 [BaseDriver] Waited for 1001 ms so far
    2020-02-28 22:26:35:858 [WD Proxy] Matched '/element' to command name 'findElement'
    2020-02-28 22:26:35:859 [WD Proxy] Proxying [POST /element] to [POST http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/element] with body: {"
    strategy":"id","selector":"search_input_text","context":"","multiple":false}
    2020-02-28 22:26:36:719 [WD Proxy] Got response with status 200: {"
    sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":{"ELEMENT":"d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9","element-6066-11e4-a52e-4f735466cecf":"d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9"}}
    2020-02-28 22:26:36:720 [W3C (5c88be64)] Responding to client with driver.findElement() result: {"
    element-6066-11e4-a52e-4f735466cecf":"d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9","ELEMENT":"d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9"}
    2020-02-28 22:26:36:722 [HTTP] <-- POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element 200 2371 ms - 137
    2020-02-28 22:26:36:723 [HTTP]
    2020-02-28 22:26:36:726 [HTTP] --> POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element/d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9/value
    2020-02-28 22:26:36:727 [HTTP] {"
    text":"阿里","value":["",""],"id":"d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9"}
    2020-02-28 22:26:36:729 [W3C (5c88be64)] Calling AppiumDriver.setValue() with args: [["
    ",""],"d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9","5c88be64-a177-4c04-8a55-fed284b25e36"]
    2020-02-28 22:26:36:731 [WD Proxy] Matched '/element/d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9/value' to command name 'setValue'
    2020-02-28 22:26:36:732 [Protocol Converter] Added 'value' property ["
    ",""] to 'setValue' request body
    2020-02-28 22:26:36:733 [WD Proxy] Proxying [POST /element/d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9/value] to [POST http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602/element/d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9/value] with body: {"
    elementId":"d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9","text":"阿里","replace":false,"unicodeKeyboard":true,"value":["",""]}
    2020-02-28 22:26:37:338 [WD Proxy] Got response with status 200: {"
    sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":null}
    2020-02-28 22:26:37:339 [W3C (5c88be64)] Responding to client with driver.setValue() result: null
    2020-02-28 22:26:37:339 [HTTP] <-- POST /wd/hub/session/5c88be64-a177-4c04-8a55-fed284b25e36/element/d7a0b0d6-0d10-4c95-bc04-8ffb6873bcb9/value 200 614 ms - 14
    2020-02-28 22:26:37:340 [HTTP]
    # 本次操作执行完毕,关闭和删除会话,重置数据
    2020-02-28 22:27:37:341 [BaseDriver] Shutting down because we waited 60 seconds for a command
    2020-02-28 22:27:37:343 [Appium] Closing session, cause was 'New Command Timeout of 60 seconds expired. Try customizing the timeout using the 'newCommandTimeout' desired capability'
    2020-02-28 22:27:37:343 [Appium] Removing session '5c88be64-a177-4c04-8a55-fed284b25e36' from our master session list
    2020-02-28 22:27:37:345 [UiAutomator2] Deleting UiAutomator2 session
    2020-02-28 22:27:37:348 [UiAutomator2] Deleting UiAutomator2 server session
    2020-02-28 22:27:37:349 [WD Proxy] Matched '/' to command name 'deleteSession'
    2020-02-28 22:27:37:350 [WD Proxy] Proxying [DELETE /] to [DELETE http://127.0.0.1:8204/wd/hub/session/bd22984c-3d3c-4b26-882a-5fdecc95f602] with no body
    2020-02-28 22:27:37:417 [WD Proxy] Got response with status 200: {"
    sessionId":"bd22984c-3d3c-4b26-882a-5fdecc95f602","value":null}
    2020-02-28 22:27:37:417 [UiAutomator2] Resetting IME to 'io.appium.settings/.UnicodeIME'
    2020-02-28 22:27:37:417 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 shell ime set io.appium.settings/.UnicodeIME'
    2020-02-28 22:27:38:244 [Instrumentation] .
    2020-02-28 22:27:38:807 [Instrumentation] Time: 121.033
    2020-02-28 22:27:38:807 [Instrumentation]
    # 关闭成功后退出进程,停止日志记录,移除tcp连接
    2020-02-28 22:27:38:808 [Instrumentation] OK (1 test)
    2020-02-28 22:27:39:059 [Instrumentation] The process has exited with code 0
    2020-02-28 22:27:39:320 [Logcat] Stopping logcat capture
    2020-02-28 22:27:39:336 [ADB] Removing forwarded port socket connection: 8204
    2020-02-28 22:27:39:336 [ADB] Running 'F:\android\android-sdk\platform-tools\adb.exe -P 5037 -s 127.0.0.1\:7555 forward --remove tcp\:8204'

    作业2、作业3

    import time
    from appium import webdriver
    from appium.webdriver.common.mobileby import MobileBy
    from appium.webdriver.common.touch_action import TouchAction


    class TestXueqiu:
    def setup(self):
    self.__init_app()

    # 常用元素
    self.__search_locator = (MobileBy.ID, 'tv_search')
    self.__search_input_locator = (MobileBy.ID, 'search_input_text')

    def __init_app(self):
    caps = {}
    caps['deviceName'] = 'xu'
    caps['platformName'] = 'Android'
    caps['appPackage'] = 'com.xueqiu.android'
    caps['appActivity'] = '.view.WelcomeActivityAlias'

    # 重置数据
    # caps['noReset'] = True
    # 不关闭app
    caps['dontStopAppOnReset'] = True
    # 使用中文
    caps['unicodeKeyboard'] = True
    # 重置键盘
    caps['resetKeyboard'] = True
    # 初始安装就可
    # caps['skipServerInstallation'] = True

    self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', caps)
    self.driver.implicitly_wait(10)

    def find(self, by, value=None):
    if isinstance(by, tuple):
    return self.driver.find_element(*by)
    return self.driver.find_element(by, value)

    def __search(self, content, first=True):
    # 再次搜索无该按钮
    if first:
    self.find(self.__search_locator).click()
    # 搜索指定内容
    self.find(self.__search_input_locator).clear()
    self.find(self.__search_input_locator).send_keys(content)
    # 点击第一条搜索结果
    self.find(MobileBy.ID, 'name').click()

    def test_search_and_get_target_price(self):
    stock_btn_locator = (MobileBy.XPATH, '//*[contains(@resource-id, "title_container")]/android.widget.TextView[@text="股票"]')
    hk_price_locator = (MobileBy.XPATH, '//*[contains(@resource-id, "stockCode") and @text="09988"]/../../..//*[contains(@resource-id, "current_price")]')

    self.__search('阿里')
    # 点击股票分类
    self.find(stock_btn_locator).click()
    # 获取香港上市的阿里巴巴股票price
    price_element = self.find(hk_price_locator)
    price = price_element.get_attribute('text')
    assert 200 <= float(price)

    def test_follow_stock_and_get_result(self):
    stock_btn_locator = (MobileBy.XPATH, '//*[contains(@resource-id, "title_container")]/android.widget.TextView[@text="股票"]')
    follow_btn_locator = (MobileBy.XPATH, '//*[contains(@resource-id, "stockCode") and @text="09988"]/../../..//*[contains(@resource-id, "follow_btn")]')
    followed_btn_locator = (MobileBy.XPATH, '//*[contains(@resource-id, "stockCode") and @text="09988"]/../../..//*[contains(@resource-id, "followed_btn")]')

    self.__search('阿里')
    # 点击股票分类
    self.find(stock_btn_locator).click()
    # 点击加自选按钮
    self.find(follow_btn_locator).click()

    # 再次搜索
    self.__search('阿里', False)
    # 点击股票分类
    self.find(stock_btn_locator).click()
    # 获取元素的所有attributetext
    followed_btn_text = self.find(followed_btn_locator).get_attribute('text')
    assert '已添加' in followed_btn_text

    def teardown(self):
    pass
    # time.sleep(10)
    # self.driver.quit()

  • 问题求教

    关于send_keys()输入字符串的问题?
    打开的是一个electron的win桌面应用

    options = webdriver.ChromeOptions()
    options.add_argument("--remote-debugging-port=9222")
    options.set_capability('platform', 'WINDOWS')
    options.set_capability('version', '10')
    options.binary_location = app_path
    driver = webdriver.Chrome(options=options)

    driver.delete_all_cookies()

    user = app.find_element_by_css_selector('#user-mobile')
    app.execute_script('document.querySelector("#user-mobile").value="";')
    user.send_keys('12333333456')

    代码输入的与实际输入的内容不符,会少一些;使用了PyKeyboard.type_string()也会这样;只能一个一个字符输入。
    应该不是selenium的问题,但找不出具体原因来,不知道老师知不知道是什么原因。

  • 课间作业1

    from selenium import webdriver

    class TestSelenium:

    @classmethod
    def setup_class(cls):
    cls.driver = webdriver.Chrome()

    @classmethod
    def teardown_class(cls):
    cls.driver.quit()

    def test_testerhome(self):
    self.driver.get('https://testerhome.com')

    teams = self.driver.find_element_by_link_text('社团')
    teams.click()

    hogwarts = self.driver.find_element_by_link_text('霍格沃兹测试学院')
    hogwarts.click()

    topics = self.driver.find_elements_by_xpath('//div[@class="panel-body"]/a[contains(@href, "/topics")]')
    topics[0].click()

    课间作业2

    def test_2(self):
    self.driver.get('https://testerhome.com')

    topic_element = self.driver.find_element_by_css_selector('a[title="MTSC2020 中国互联网测试开发大会议题征集"]')
    topic_element.click()

    dir_btn_element = self.driver.find_element_by_css_selector('.toc-container button')
    dir_btn_element.click()

    time.sleep(3)
    element = self.driver.find_element_by_xpath('//li[contains(@class,"toc-item")]/a[text()="征集议题范围"]')
    element.click()

    课后作业3

    import os
    import sys
    import yaml
    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By


    project_dir = os.getcwd()
    sys.path.append(project_dir)
    with open(project_dir + r'\test_selenium.yml', 'rb') as f:
    config = yaml.load(f, Loader=yaml.FullLoader)


    class TestSelenium:
    def setup_class(self):
    options = webdriver.ChromeOptions()
    # close all chrome window, and cmd: chrome.exe --remote-debugging-port=9222
    # options.debugger_address = config['debugger_address']
    self.driver = webdriver.Chrome(options=options)

    self.driver.implicitly_wait(5)

    def teardown_class(self):
    self.driver.quit()

    def wait_element(self, timeout, method):
    return WebDriverWait(self.driver, timeout=timeout).until(method)

    def element(self, by, value):
    if by == 'css_selector':
    return self.driver.find_element_by_css_selector(value)
    elif by == 'xpath':
    return self.driver.find_element_by_xpath(value)
    else:
    raise BaseException('no such find element method [%s]' % by)

    def login_work_wexin(self):
    work_wexin = config['test_work_wexin']
    cookies = work_wexin['cookies']
    login_url = work_wexin['wexin_login']

    # open work.wexin
    self.driver.get(login_url)

    # cookies = self.driver.get_cookies()
    # {
    # 'domain': cookie['domain'],
    # 'name': cookie['name'],
    # 'value': cookie['value'],
    # 'path': '/',
    # 'expires': None
    # }

    # use cookies login
    self.driver.delete_all_cookies()
    for cookie in cookies:
    self.driver.add_cookie(cookie)

    self.driver.refresh()

    # @pytest.mark.parametrize('member', config['test_work_wexin']['add_member']) # 若使用参数化则不用for循环,但每次都需要重新打开一次urladd页面
    def test_work_wexin_add_member(self):
    # login work wexin
    self.login_work_wexin()

    members = config['test_work_wexin']['add_member']

    # add member page
    self.driver.find_element_by_css_selector('[node-type="addmember"]').click()

    # write member info
    last_member_index = len(members) - 1
    for index, member in enumerate(members):
    self.element('css_selector', '#username').send_keys(member['name'])
    self.element('css_selector', '#memberAdd_acctid').send_keys(member['id'])
    self.element('css_selector', 'input[name="gender"][value="%s"]' % member['gender']).click()
    self.element('css_selector', '#memberAdd_phone').send_keys(member['mobile'])
    self.element('css_selector', '#memberEdit_address').send_keys(member['address'])
    self.element('css_selector', '#memberAdd_title').send_keys(member['title'])

    # save member
    if last_member_index != index:
    save = EC.element_to_be_clickable((By.XPATH, '//div[contains(@class,"member_colRight_operationBar")]/a[text()="保存并继续添加"]'))
    else:
    save = EC.element_to_be_clickable((By.XPATH, '//div[contains(@class,"member_colRight_operationBar")]/a[text()="保存"]'))
    self.wait_element(10, save).click()

  • 十一期_Python 测试_20191222 at December 25, 2019

    课后作业2

    import os
    import pytest
    import shutil
    import subprocess
    import logging


    logging.basicConfig(level=logging.DEBUG)
    log = logging.getLogger('TestDiv')


    def div(a, b):
    return a/b


    def teardown_module(module):
    '''generate allure report'''
    log.info('\n-------tear down generate report-------\n')

    if os.path.exists('unit/report/allure_html'):
    shutil.rmtree('unit/report/allure_html')

    build_html_cmd = 'allure generate unit/report/allure_results/ -o unit/report/allure_html'
    build_open_cmd = 'allure serve unit/report/allure_results/'

    build_html = subprocess.Popen(build_open_cmd, shell=True, stdout=subprocess.PIPE)
    build_html.wait()


    class TestDiv:

    @pytest.mark.p0
    @pytest.mark.parametrize('a, b, expected', [
    (2, 1, 2),
    (1, 2, 0.5),
    (3, 9, 0.334),
    (-1, -2, 0.5),
    (2147483647, 2, 1073741823.5),
    (-2147483648, -2, 1073741824.0),
    ])
    def test_type_int(self, a, b, expected):
    '''
    test Integer division
    '''
    assert div(a, b) == expected

    @pytest.mark.p0
    @pytest.mark.parametrize('a, b, expected', [
    (1.5, 1, 1.5),
    (2, 0.5, 4),
    (2.25, 0.5, 4.5),
    (2, -0.5, -4),
    (1.7976931348623157e+308, 2, 8.988465674311579e+307),
    (2.2250738585072014e-308, -1, -2.2250738585072014e-308),
    ])
    def test_type_float(self, a, b, expected):
    '''
    test division value has float
    '''
    assert div(a, b) == expected

    @pytest.mark.p1
    @pytest.mark.parametrize('a, b', [
    ('2', 1),
    ('a', 5),
    (2, (1,)),
    ([2], 5),
    (5, {'a': 1}),
    (5, None),
    (False, 5),
    (2, True),
    ])
    def test_type_error(self, a, b):
    '''
    test division value has type not digital
    '''
    with pytest.raises(TypeError):
    div(a, b)

    @pytest.mark.p1
    @pytest.mark.parametrize('a, b', [
    (2, 0)
    ])
    def test_dividend_zero(self, a, b):
    '''
    test divisor of 0
    '''
    with pytest.raises(ZeroDivisionError):
    div(a, b)

    @pytest.mark.p2
    @pytest.mark.parametrize('a, b', [
    (2, 2147483648),
    (-2147483649, -2),
    (2, 1.7976931348623157e+307),
    (-2, 2.2250738585072014e-309),
    ])
    def test_over_digital_length(self, a, b):
    '''
    test int and float over max/min length
    '''
    assert div(a, b) is None

    allure报告

  • 十一期_Python 测试_20191222 at December 22, 2019

    课件作业1

    def test_div():
    a = 1.5
    b = 2

    assert a/b == div(a, b)

    def test_div_more():
    for x in range(10):
    a = x
    b = x + 1
    assert a/b == div(a, b)
  • 1.jvmPath没有问题;
    2.路径我换成了绝对路径;
    3.用这种方式加绝对路径就成功了!
    太感谢啦!,不过为什么使用startJVM(jvmpath=jvmPath, classpath="-Djava.class.path=test.jar", convertStrings=False),参数带key的方式就会失败呢?