Appium环境搭建试验

Appium是什么

Appiun是一套测试框架,采用典型的C/S架构。
通过Appium可以很方便的实现自动化测试手机应用,减少手工测试的投入。
Appium是一套框架,和具体使用的语言无关,你可以有很多种选择,Python/Java/Php等等。
用代码把你想要做的事情描述清楚,剩下的就交给Appium去做吧。
她就是你的得力助手,她会按你的旨意完成你交代的事情,并且会告诉你关心的结果。

搭建Appium需要哪些

Appium是用Node.js编写的,所以你需要安装Node.js,给她提供展示的舞台。
舞台搭建好了,现在就是演员Appium出场了,她有两张面孔,前台与幕后。前台就是Appium桌面版,幕后是服务端版。
桌面版包含了服务端版,额外提供了一个界面来让你下达操作手机的指令,以及查看手机应用的UI布局信息。故操作手机的方式有两种,通过界面的参数指定需要完成的动作,还可以直接使用脚本。不管你通过哪一种方式,最后都是把这些输入交给Appium服务端处理的,她会把这些转换成对应的命令,通过UIAutomator发送到手机端的Bootstrap.jar,完成你期望的操作,在沿着反方向返回结果。所以Appium服务端是必不可少的,至于桌面版,看你的需求了。建议安装桌面版的,因为你可以方便查看手机应用的UI资源,在你编写测试脚本的时候,这些就是你用来操作应用程序的资源。

目的是要编写脚本去操纵手机应用,在你选择了使用的编程语言之后,你需要安装对应的运行环境,以及封装的Appium开发包。

When all is said and done, Appium is just an HTTP server. It sits and waits for connections from a client, which then instructs Appium what kind of session to start and what kind of automation behaviors to enact once a session is started. This means that you never use Appium just by itself. You always have to use it with a client library of some kind (or, if you're adventurous, cURL!). -- 来自官网的介绍

官网说的是Appium Client,但我更喜欢称它为包,为开发人员更方便编码的库。
还有就是手机端对应的相关驱动之类的了,Android的话,需要安装JRE和SDK。

整个过程需要注意的地方

苹果的M1芯片暂时还没有官方的完全支持,不支持Java,当然也就不支持Android了。在参考了网上的的相关文章,以及自己遇到的各种问题之后,我建议采用这样的方式,因为比较简单。下载 IntelliJ IDEA ,之后通过 Tools --> Android --> SDK Manger 打开如下窗口:

找到你需要的安装就好,安装这个默认会安装Java的环境。最后记得设置Java和Android的环境变量,如果一切顺利,环境就搭好了。
你可以通过npm来安装一个检查员appium-doctor,她可以帮助你检查环境需要的是否都准备就绪。

安装命令如下:

npm install -g appium-doctor

通过Appium删除微信僵尸好友

原理其实很简单,通过操作UI界面的控件对应的resource-id,模拟人手操作界面的过程。
可以参考 文章 里面的讲解,我也是参考了才会有下面的代码的。

import time
from appium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException

friends = set()
default_wait_time = 2   # 2秒
server = 'http://localhost:4723/wd/hub'
desired_capabilities = {
    'platformName': 'Android',  # 操作系统
    'deviceName': '215cb0a4',  # 设备ID,使用cmd中adb devices命令得到
    'platformVersion': '10',  # 设备版本号,在手机设置中查看
    'appPackage': 'com.tencent.mm',  # app包名
    'appActivity': 'com.tencent.mm.ui.LauncherUI',  # app启动时主Activity
    'noReset': True  # 是否保留session信息,避免重新登录
}
driver = webdriver.Remote(server, desired_capabilities)


def has_warn(res_id):
    try:
        time.sleep(default_wait_time)
        driver.find_element_by_id(res_id)
        return True
    except NoSuchElementException:
        return False


def switch_tab(tab_name):
    time.sleep(default_wait_time)
    address_list = driver.find_elements_by_id('com.tencent.mm:id/dub')
    for address in address_list:
        cur_tab = address.get_attribute('text')
        if cur_tab == tab_name:
            address.click()
    time.sleep(default_wait_time)


def select_func(fun_name):
    time.sleep(default_wait_time)
    address_list = driver.find_elements_by_id('com.tencent.mm:id/rt')
    for address in address_list:
        cur_fun = address.get_attribute('text')
        if cur_fun == fun_name:
            address.click()
            break
    time.sleep(default_wait_time)


def come_back(times):
    while times > 0:
        driver.press_keycode(4)
        times -= 1
    time.sleep(default_wait_time)


def wait_load(res_id):
    wait = WebDriverWait(driver, 10)
    return wait.until(EC.presence_of_element_located((By.ID, res_id)))


def button_click(res_id):
    wait_load(res_id).click()


def send_words(res_id, keys):
    wait_load(res_id).send_keys(keys)


def reach_end(your_name, last_name):
    time.sleep(3)
    over = False
    address_list = driver.find_elements_by_id('com.tencent.mm:id/ft6')
    for address in address_list:
        friend = address.get_attribute('text')
        if friend != your_name and friend != '微信团队' and friend != '文件传输助手':
            friends.add(friend)
        if friend == last_name:
            over = True
    x = driver.get_window_size()['width']
    y = driver.get_window_size()['height']
    driver.swipe(0.5 * x, 0.75 * y, 0.5 * x, 0.25 * x)
    return over


def get_friends(your_name, last_name):
    while not reach_end(your_name, last_name):
        continue


def find_friend(full_name):
    flag = False
    button_click('com.tencent.mm:id/he6')      # 搜索圈
    send_words('com.tencent.mm:id/bxz', full_name)      # 搜索框
    try:
        address = driver.find_element_by_id('com.tencent.mm:id/ir3')  # 联系人
        if address.get_attribute("text") == full_name:  # 联系人名字
            return True
    except NoSuchElementException:
        flag = False
    come_back(2)
    return flag


def delete_friend(full_name):
    come_back(2)
    button_click('com.tencent.mm:id/d8')       # 三个点按钮
    button_click('com.tencent.mm:id/h8t')      # 好友头像
    button_click('com.tencent.mm:id/d8')       # 三个点按钮
    button_click('com.tencent.mm:id/ijq')      # 删除
    button_click('com.tencent.mm:id/ffp')      # 提示框删除


def proc_select(full_name):
    if not find_friend(full_name):
        return False
    button_click('com.tencent.mm:id/ir3')      # 联系人
    button_click('com.tencent.mm:id/au0')      # 加号
    select_func('转账')
    button_click('com.tencent.mm:id/e64')      # 数字1
    button_click('com.tencent.mm:id/e6c')      # 提交转账
    if has_warn('com.tencent.mm:id/ffh'):       # 非好友提示框
        button_click('com.tencent.mm:id/ffp')      # 知道了按钮
        delete_friend(full_name)
        print(full_name + '已经删除了你, 现在你的世界也没有她了')
    else:
        come_back(6)


print('微信打开了,开始处理僵尸好友')
time.sleep(5)
switch_tab('通讯录')
get_friends('雪域', '99末班车')
switch_tab('微信')
while len(friends):
    proc_select(friends.pop())
print('僵尸好友处理完毕,已经退出微信')

我很好奇,为什么同样的按钮,我看到的resource-id和作者看到的不同。
所以,这个代码对你的手机也许并不管用,可能还会有其它未知的风险,你需要结合你自己的环境检验。

一点收获

  1. 在获取资源时,需要等待它加载完毕,否则获取不到,出现异常
  2. Python在使用try...except...finally结构的异常捕获时,except的返回值不起作用,会被finally的覆盖
  3. 手机打开USB调试还不能使用Appium,还需要打开允许通过USB安装应用程序
  4. 程序逻辑似乎没有问题,但是运行着就停了,可能是手机卡顿,还有可能是安全管家阻止了

参考文档

官方参考文档
Appium Desktop下载
讲在Mac上使用Appium遇到的坑
讲解Appium框架交互原理
讲解npm是什么

posted @ 2022-08-06 21:57  99末班车  阅读(51)  评论(0编辑  收藏  举报