windows可以参考 windows配置
开始正文之前 啰嗦一句 网易推出 airtest 对于新手来说更加的友好
安装Appium
首先通过brew安装nodejs:
brew install node
配置国内源,在个人目录下新建一个.npmrc文件,写入:
registry=https://registry.npm.taobao.org/
开始安装Appium:
(如果报为 check permission的错误 可以先 执行 npm install cnpm -g)
npm install -g appium
npm install -g appium-doctor
只要运行appium-doctor命令就可以知道你还需要设置哪些环境变量,比如:
tcyxdeMacBook-Pro:~ tcyx$ appium-doctor
info AppiumDoctor Appium Doctor v.1.6.0
info AppiumDoctor ### Diagnostic starting ###
info AppiumDoctor ✔ The Node.js binary was found at: /usr/local/bin/node
info AppiumDoctor ✔ Node version is 8.1.2
info AppiumDoctor ✔ Xcode is installed at: /Applications/Xcode.app/Contents/Developer
info AppiumDoctor ✔ Xcode Command Line Tools are installed.
info AppiumDoctor ✔ DevToolsSecurity is enabled.
info AppiumDoctor ✔ The Authorization DB is set up properly.
WARN AppiumDoctor ✖ Carthage was NOT found!
info AppiumDoctor ✔ HOME is set to: /Users/tcyx
info AppiumDoctor ✔ ANDROID_HOME is set to: /Users/tcyx/Library/Android/sdk/
info AppiumDoctor ✔ JAVA_HOME is set to: /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home
info AppiumDoctor ✔ adb exists at: /Users/tcyx/Library/Android/sdk/platform-tools/adb
info AppiumDoctor ✔ android exists at: /Users/tcyx/Library/Android/sdk/tools/android
info AppiumDoctor ✔ emulator exists at: /Users/tcyx/Library/Android/sdk/tools/emulator
info AppiumDoctor ✔ Bin directory of $JAVA_HOME is set
info AppiumDoctor ### Diagnostic completed, one fix needed. ###
info AppiumDoctor
info AppiumDoctor ### Manual Fixes Needed ###
info AppiumDoctor The configuration cannot be automatically fixed, please do the following first:
WARN AppiumDoctor - Please install Carthage. Visit https://github.com/Carthage/Carthage#installing-carthage for more information.
info AppiumDoctor ###
info AppiumDoctor
info AppiumDoctor Bye! Run appium-doctor again when all manual fixes have been applied!
info AppiumDoctor
只要确保ANDROID_HOME 和 JAVA_HOME 正确配置,另外SDK Tools 和Platform Tools都加入PATH就基本完成了。可以参考user目录下的.bash_profile设置:
export ANDROID_HOME=~/Library/Android/sdk/
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home
export PATH=~/bin:$PATH:/usr/local/bin:$ANDROID_HOME/platform-tools/:$JAVA_HOME/bin
加完之后执行
source .bash_profile
安装 Appium-Client
java : https://github.com/appium/java-client/blob/master/docs/Installing-the-project.md
python : https://github.com/appium/python-client
启动Appium 服务端
appium -p 4492 -bp 2251 -U 915e6afc
-p 主要的Appium端
-bp Appium引导端口
-U deviceID
实例代码
代码基于同城游App编写,可以根据你们自己App的情况进行修改。
Java实现
package com.uc108.gamecenter;
import com.sun.jdi.connect.spi.TransportService;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.Command;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.URL;
import java.time.Duration;
import static java.lang.Thread.sleep;
public class AppTest {
private AppiumDriver<AndroidElement> driver;
private String camera_id_mi = "com.android.camera:id/v9_shutter_button_internal";
private String camera_id_zte = "com.zte.camera:id/photo_shutter_button";
private String camera_ok_mi = "com.android.camera:id/inten_done_apply";
private String camera_ok_zte = "com.zte.camera:id/attach_photo_ok";
private String camera_save_mi = "com.miui.gallery:id/ok";
private String camera_save_zte = "com.android.gallery3d:id/action_done";
private String package_name = "com.uc108.mobile.gamecenter";
private void sleep(int time){
try {
Thread.sleep(time);
}catch (Exception e){
e.printStackTrace();
}
}
private boolean findItem(String item_text){
try {
driver.findElementByXPath("//*[@text='" + item_text + "']");
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
private void scroll(String targetText){
while (true){
if(!findItem(targetText)){
new TouchAction(driver).press(PointOption.point(600, 600))
.waitAction(WaitOptions.waitOptions(Duration.ofMillis(1000)))
.moveTo(PointOption.point(200, 200)).release().perform();
sleep(1000);
}else{
break;
}
}
}
@Before
public void setup() throws Exception {
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability("platformName", "Android"); //指定测试平台
cap.setCapability("deviceName", "e131cc03"); //指定测试机的ID,通过adb命令`adb devices`获取
cap.setCapability("platformVersion", "5.1.1");
//将上面获取到的包名和Activity名设置为值
cap.setCapability("appPackage", "com.uc108.mobile.gamecenter");
cap.setCapability("appActivity", "com.tcy365.m.hallhomemodule.ui.SplashActivity");
driver = new AndroidDriver(new URL("http://127.0.0.1:4491/wd/hub"), cap);
sleep(20000);
}
@Test
public void chooseCity(){
driver.findElementById(package_name + ":id/userPortrait").click();
sleep(3000);
driver.findElementById(package_name + ":id/rl_area").click();
sleep(3000);
scroll("新疆");
sleep(3000);
driver.findElementByXPath("//*[@text='新疆']").click();
sleep(3000);
scroll("乌鲁木齐");
sleep(3000);
driver.findElementByXPath("//*[@text='乌鲁木齐']").click();
sleep(3000);
driver.execute("goBack");
sleep(1000);
}
@After
public void tearDown() throws Exception {
driver.quit();
}
}
python实现
# -*- coding: UTF-8 -*-
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
import time
import threading
from time import sleep
desired_caps_4491 = {
'platformName': 'Android',
'platformVersion': '5.1.1',
'deviceName': 'e131cc03',
'appPackage': 'com.uc108.mobile.gamecenter',
'appActivity': 'com.tcy365.m.hallhomemodule.ui.SplashActivity',
'noReset': True,
'unicodeKeyboard': True,
'resetKeyboard': True
}
desired_caps_4492 = {
'platformName': 'Android',
'platformVersion': '7.1.1',
'deviceName': '915e6afc',
'appPackage': 'com.uc108.mobile.gamecenter',
'appActivity': 'com.tcy365.m.hallhomemodule.ui.SplashActivity',
'unicodeKeyboard': True,
'resetKeyboard': True,
'automationName': 'UiAutomator2'
}
package_name = 'com.uc108.mobile.gamecenter'
# 根据文字找到某个item
def find_item(driver, item_text):
try:
driver.find_element_by_xpath("//*[@text='" + item_text + "']")
return True
except Exception:
return False
# 滚动到某个item
def scroll(driver, width, height, target_text):
while True:
if not find_item(driver, target_text):
print(width)
print(height)
# driver.scroll()
# TouchAction(driver).press(100, 100).move_to(200, 200).perform()
driver.swipe(0, 0, width, height, duration=sleep(3))
height = height
sleep(1)
else:
break
camera_id_mi = 'com.android.camera:id/v9_shutter_button_internal'
camera_id_zte = 'com.zte.camera:id/photo_shutter_button'
camera_ok_mi = 'com.android.camera:id/inten_done_apply'
camera_ok_zte = 'com.zte.camera:id/attach_photo_ok'
camera_save_mi = 'com.miui.gallery:id/ok'
camera_save_zte = 'com.android.gallery3d:id/action_done'
# 拍照切换头像
def take_photo(driver, type):
driver.find_element_by_id(package_name + ':id/userPortrait').click()
sleep(1)
driver.find_element_by_id(package_name + ':id/rl_profile').click()
sleep(1)
driver.find_element_by_id(package_name + ':id/iv_choose_profile').click()
sleep(1)
if type == 4492:
try:
driver.find_element_by_id('android:id/button1').click()
sleep(1)
driver.find_element_by_id(package_name + ':id/iv_choose_profile').click()
sleep(1)
except Exception:
sleep(1)
driver.find_element_by_id(package_name + ':id/btn_camera').click()
sleep(2)
driver.find_element_by_id(camera_id_mi).click()
sleep(4)
driver.find_element_by_id(camera_ok_mi).click()
sleep(2)
driver.find_element_by_id(camera_save_mi).click()
else:
driver.find_element_by_id(package_name + ':id/btn_camera').click()
sleep(1)
driver.find_element_by_id(camera_id_zte).click()
sleep(1)
driver.find_element_by_id(camera_ok_zte).click()
sleep(1)
driver.find_element_by_id(camera_save_zte).click()
sleep(20)
driver.back()
sleep(1)
driver.back()
sleep(5)
# 进入游戏
def play_game(driver):
driver.find_element_by_id('com.uc108.mobile.lagt.vivo:id/game_connection').click()
# 选择城市
def choose_city(driver):
driver.find_element_by_id(package_name + ':id/userPortrait').click()
sleep(3)
driver.find_element_by_id(package_name + ':id/rl_area').click()
width = driver.get_window_size().get('width')
height = driver.get_window_size().get('height')
print(width)
print(height)
sleep(3)
# driver.swipe(0, 0, int(width) / 2, int(height) / 4, duration=sleep(1))
scroll(driver, int(width) / 2, int(height) / 4, '新疆')
sleep(3)
driver.find_element_by_xpath("//*[@text='新疆']").click()
sleep(3)
scroll(driver, int(width) / 2, int(height) / 4, '乌鲁木齐')
driver.find_element_by_xpath("//*[@text='乌鲁木齐']").click()
sleep(3)
driver.back()
sleep(1)
# 客服
def ke_fu(driver):
driver.find_element_by_id(package_name + ':id/imageview').click()
sleep(1)
edittext = driver.find_element_by_id(package_name + ':id/inputEt')
edittext.send_keys(u"你好")
sleep(3)
if driver.is_keyboard_shown():
driver.hide_keyboard()
sleep(1)
driver.find_element_by_id(package_name + ':id/sendBtn').click()
sleep(1)
driver.back()
sleep(1)
# 设置
def setting(driver):
driver.find_element_by_xpath("//*[@text='设置']").click()
sleep(1)
el = driver.find_element_by_id(package_name + ':id/setting_tv_show')
action = TouchAction(driver)
action.long_press(el, 2).wait(1).perform()
sleep(3)
driver.back()
sleep(1)
# 合集首页
def home_page(driver):
game_list = driver.find_elements_by_id(package_name + ':id/root_view_click')
print game_list
print len(game_list)
size = len(game_list)
if size == 9:
game_list.__getitem__(6).click()
else:
game_list.__getitem__(3).click()
sleep(5)
driver.find_element_by_id(package_name + ':id/tv_location_city').click()
sleep(1)
driver.back()
sleep(1)
width = driver.get_window_size().get('width')
height = driver.get_window_size().get('height')
driver.swipe(0, height/4, width/2, height/4, duration=sleep(1))
def begin_test(type):
print(threading.currentThread())
print(type)
if type == 4491:
driver = webdriver.Remote('http://localhost:4491/wd/hub', desired_caps_4491)
time.sleep(40)
else:
driver = webdriver.Remote('http://localhost:4492/wd/hub', desired_caps_4492)
time.sleep(2)
driver.find_element_by_id(package_name + ':id/tvOpen').click()
sleep(1)
driver.find_element_by_id('android:id/button1').click()
sleep(1)
driver.find_element_by_id('android:id/button1').click()
sleep(1)
time.sleep(40)
home_activity = driver.current_activity
print home_activity
# setting(driver)
ke_fu(driver)
choose_city(driver)
# take_photo(driver, type)
home_page(driver)
driver.close_app()
return
t = threading.Thread(target=begin_test, name='LoopThread1', args=(4491,))
t.start()
t_two = threading.Thread(target=begin_test, name='LoopThread2', args=(4491,))
t_two.start()