本文目录导读:

我来为您提供几个常用的Appium自动化测试案例,涵盖不同的应用场景。
登录功能测试
场景:测试iOS/Android登录功能
# login_test.py
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
class LoginTest:
def __init__(self):
# Android设备配置
self.desired_caps = {
'platformName': 'Android',
'platformVersion': '10.0',
'deviceName': 'Android Emulator',
'appPackage': 'com.example.app',
'appActivity': '.MainActivity',
'noReset': True,
'automationName': 'UiAutomator2'
}
# iOS设备配置(如果测试iOS)
# self.desired_caps = {
# 'platformName': 'iOS',
# 'platformVersion': '14.0',
# 'deviceName': 'iPhone 12',
# 'app': '/path/to/app.app',
# 'automationName': 'XCUITest'
# }
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', self.desired_caps)
self.wait = WebDriverWait(self.driver, 10)
def test_valid_login(self):
"""测试正常登录"""
try:
# 等待登录页面元素加载
username_field = self.wait.until(
EC.presence_of_element_located((AppiumBy.ID, 'com.example.app:id/username'))
)
password_field = self.wait.until(
EC.presence_of_element_located((AppiumBy.ID, 'com.example.app:id/password'))
)
# 输入用户名和密码
username_field.clear()
username_field.send_keys('testuser@example.com')
password_field.clear()
password_field.send_keys('password123')
# 点击登录按钮
login_button = self.driver.find_element(AppiumBy.ID, 'com.example.app:id/login_btn')
login_button.click()
# 等待登录成功提示
success_message = self.wait.until(
EC.presence_of_element_located((AppiumBy.ID, 'com.example.app:id/success_message'))
)
assert success_message.text == "登录成功"
print("✅ Test passed: 正常登录")
except Exception as e:
print(f"❌ Test failed: {str(e)}")
self.take_screenshot('login_failure')
def test_invalid_login(self):
"""测试无效登录"""
try:
username_field = self.wait.until(
EC.presence_of_element_located((AppiumBy.ID, 'com.example.app:id/username'))
)
password_field = self.wait.until(
EC.presence_of_element_located((AppiumBy.ID, 'com.example.app:id/password'))
)
# 输入错误的凭据
username_field.clear()
username_field.send_keys('invaliduser@test.com')
password_field.clear()
password_field.send_keys('wrongpassword')
login_button = self.driver.find_element(AppiumBy.ID, 'com.example.app:id/login_btn')
login_button.click()
# 验证错误提示
error_message = self.wait.until(
EC.presence_of_element_located((AppiumBy.ID, 'com.example.app:id/error_message'))
)
assert "无效" in error_message.text or "错误" in error_message.text
print("✅ Test passed: 无效登录错误处理")
except Exception as e:
print(f"❌ Test failed: {str(e)}")
def take_screenshot(self, filename):
"""保存截图"""
timestamp = time.strftime("%Y%m%d_%H%M%S")
self.driver.save_screenshot(f"./screenshots/{filename}_{timestamp}.png")
def teardown(self):
"""清理测试环境"""
self.driver.quit()
if __name__ == "__main__":
test = LoginTest()
try:
test.test_valid_login()
test.test_invalid_login()
finally:
test.teardown()
微信朋友圈发布测试
场景:自动化测试微信朋友圈功能
// WeChatMomentsTest.java
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.net.MalformedURLException;
import java.net.URL;
public class WeChatMomentsTest {
private AndroidDriver<MobileElement> driver;
public void setup() throws MalformedURLException {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("platformName", "Android");
caps.setCapability("platformVersion", "11.0");
caps.setCapability("deviceName", "emulator-5554");
caps.setCapability("appPackage", "com.tencent.mm");
caps.setCapability("appActivity", ".ui.LauncherUI");
caps.setCapability("noReset", true);
driver = new AndroidDriver<>(new URL("http://localhost:4723/wd/hub"), caps);
}
public void postMoment(String text, String imagePath) {
WebDriverWait wait = new WebDriverWait(driver, 10);
try {
// 打开"发现"页面
clickElementByText("发现");
// 点击"朋友圈"
clickElementByText("朋友圈");
// 长按发布按钮进入发布界面
WebElement publishBtn = wait.until(
ExpectedConditions.elementToBeClickable(By.xpath("//*[@content-desc='发布']"))
);
longPress(publishBtn);
// 输入文字
WebElement textInput = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@text='这一刻的想法...']"))
);
textInput.click();
textInput.sendKeys(text);
// 选择图片(如果在真机上执行,需要处理相册权限)
if (imagePath != null) {
addImageFromGallery(imagePath);
}
// 点击发布按钮
WebElement postBtn = driver.findElement(By.xpath("//*[@text='发表']"));
postBtn.click();
// 等待发布成功
Thread.sleep(2000);
System.out.println("✅ 朋友圈发布成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("❌ 朋友圈发布失败");
}
}
private void clickElementByText(String text) {
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(
ExpectedConditions.elementToBeClickable(By.xpath("//*[@text='" + text + "']"))
);
element.click();
}
private void longPress(WebElement element) {
// 使用TouchAction模拟长按
new io.appium.java_client.touch.TouchAction(driver)
.longPress(io.appium.java_client.touch.offset.ElementOption.element(element))
.release()
.perform();
}
private void addImageFromGallery(String imagePath) {
// 具体实现取决于图片选择流程
System.out.println("选择图片: " + imagePath);
}
public void teardown() {
if (driver != null) {
driver.quit();
}
}
public static void main(String[] args) throws MalformedURLException {
WeChatMomentsTest test = new WeChatMomentsTest();
test.setup();
test.postMoment("自动化测试发布的朋友圈", null);
test.teardown();
}
}
电商App购物流程测试
场景:测试完整的购物流程
# ShoppingFlowTest.py
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.common.touch_action import TouchAction
import unittest
import time
class ShoppingFlowTest(unittest.TestCase):
def setUp(self):
"""初始化测试环境"""
desired_caps = {
'platformName': 'Android',
'platformVersion': '9.0',
'deviceName': 'Pixel_3',
'appPackage': 'com.shop.app',
'appActivity': '.MainActivity',
'automationName': 'UiAutomator2',
'noReset': True
}
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
self.wait = WebDriverWait(self.driver, 10)
def test_complete_shopping_flow(self):
"""完整购物流程测试"""
try:
# 1. 搜索商品
self.search_product("无线耳机")
# 2. 选择商品
self.select_product()
# 3. 添加到购物车
self.add_to_cart()
# 4. 查看购物车
self.view_cart()
# 5. 结算
self.checkout()
# 6. 选择支付方式
self.select_payment()
print("✅ 完整购物流程测试通过")
except Exception as e:
self.take_screenshot("shopping_flow_failure")
self.fail(f"测试失败: {str(e)}")
def search_product(self, keyword):
"""搜索商品"""
search_box = self.wait.until(
EC.element_to_be_clickable((AppiumBy.ID, "com.shop.app:id/search_icon"))
)
search_box.click()
input_box = self.wait.until(
EC.presence_of_element_located((AppiumBy.ID, "com.shop.app:id/search_input"))
)
input_box.send_keys(keyword)
# 点击搜索按钮
self.driver.find_element(AppiumBy.ID, "com.shop.app:id/search_btn").click()
time.sleep(2)
def select_product(self):
"""选择商品"""
first_product = self.wait.until(
EC.element_to_be_clickable((AppiumBy.XPATH,
"//*[@resource-id='com.shop.app:id/product_list']//*[@class='android.widget.RelativeLayout'][1]"))
)
first_product.click()
time.sleep(1)
def add_to_cart(self):
"""添加到购物车"""
add_cart_btn = self.wait.until(
EC.element_to_be_clickable((AppiumBy.ID, "com.shop.app:id/add_cart_btn"))
)
add_cart_btn.click()
# 确认添加到购物车
confirm_btn = self.wait.until(
EC.element_to_be_clickable((AppiumBy.ID, "com.shop.app:id/confirm_btn"))
)
confirm_btn.click()
def view_cart(self):
"""查看购物车"""
cart_icon = self.wait.until(
EC.element_to_be_clickable((AppiumBy.ID, "com.shop.app:id/cart_icon"))
)
cart_icon.click()
# 验证商品在购物车中
assert "无线耳机" in self.driver.page_source, "购物车中没有找到商品"
def checkout(self):
"""结算"""
checkout_btn = self.wait.until(
EC.element_to_be_clickable((AppiumBy.ID, "com.shop.app:id/checkout_btn"))
)
checkout_btn.click()
def select_payment(self):
"""选择支付方式"""
# 选择微信支付
wechat_pay = self.wait.until(
EC.element_to_be_clickable((AppiumBy.XPATH, "//*[@text='微信支付']"))
)
wechat_pay.click()
# 确认支付
pay_btn = self.wait.until(
EC.element_to_be_clickable((AppiumBy.ID, "com.shop.app:id/pay_btn"))
)
pay_btn.click()
def take_screenshot(self, filename):
self.driver.save_screenshot(f"./screenshots/{filename}_{time.time()}.png")
def tearDown(self):
self.driver.quit()
if __name__ == "__main__":
unittest.main()
滑动和手势测试
场景:手势操作测试
# GesturesTest.py
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.common.touch_action import TouchAction
from appium.webdriver.common.touch import Touch
import time
class GesturesTest:
def __init__(self):
self.driver = self.setup_driver()
def setup_driver(self):
# iOS设备配置
desired_caps = {
'platformName': 'iOS',
'platformVersion': '14.0',
'deviceName': 'iPhone 12',
'app': '/path/to/app.app',
'automationName': 'XCUITest',
'udid': 'DEVICE_UDID'
}
return webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
def swipe_test(self):
"""测试滑动操作"""
try:
# 向上滑动(下拉刷新)
TouchAction(self.driver).\
press(x=200, y=800).\
move_to(x=200, y=200).\
release().perform()
time.sleep(2)
# 向下滑动(查看更多)
TouchAction(self.driver).\
press(x=200, y=300).\
move_to(x=200, y=700).\
release().perform()
time.sleep(2)
# 向左滑动(切换页面)
TouchAction(self.driver).\
press(x=350, y=500).\
move_to(x=50, y=500).\
release().perform()
time.sleep(2)
print("✅ 滑动操作测试通过")
except Exception as e:
print(f"❌ 滑动操作测试失败: {str(e)}")
def pinch_zoom_test(self):
"""测试缩放手势"""
try:
element = self.driver.find_element(AppiumBy.ID, "image_viewer")
# 放大操作
TouchAction(self.driver).\
press(element, element.X + 50, element.Y).\
wait(1000).\
move_to(element.X + 150, element.Y).\
release().\
press(element, element.X - 50, element.Y).\
wait(1000).\
move_to(element.X - 150, element.Y).\
release().perform()
time.sleep(2)
# 缩小操作
TouchAction(self.driver).\
press(element, element.X + 150, element.Y).\
wait(1000).\
move_to(element.X + 50, element.Y).\
release().\
press(element, element.X - 150, element.Y).\
wait(1000).\
move_to(element.X - 50, element.Y).\
release().perform()
print("✅ 缩放手势测试通过")
except Exception as e:
print(f"❌ 缩放手势测试失败: {str(e)}")
def tap_and_hold_test(self):
"""测试长按手势"""
try:
element = self.driver.find_element(AppiumBy.ID, "long_press_element")
# 长按操作
TouchAction(self.driver).\
long_press(element, duration=3000).\
release().perform()
time.sleep(1)
# 验证长按后的效果
context_menu = self.driver.find_element(AppiumBy.ID, "context_menu")
assert context_menu.is_displayed(), "长按菜单未弹出"
print("✅ 长按手势测试通过")
except Exception as e:
print(f"❌ 长按手势测试失败: {str(e)}")
def teardown(self):
self.driver.quit()
if __name__ == "__main__":
test = GesturesTest()
try:
test.swipe_test()
test.pinch_zoom_test()
test.tap_and_hold_test()
finally:
test.teardown()
测试框架和配置
Page Object Model 测试框架
# pages/base_page.py
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class BasePage:
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(self.driver, 10)
def find_element(self, by, value):
return self.wait.until(
EC.presence_of_element_located((by, value))
)
def click_element(self, by, value):
element = self.find_element(by, value)
element.click()
def input_text(self, by, value, text):
element = self.find_element(by, value)
element.clear()
element.send_keys(text)
def get_text(self, by, value):
element = self.find_element(by, value)
return element.text
def is_element_present(self, by, value):
try:
self.find_element(by, value)
return True
except:
return False
# pages/login_page.py
class LoginPage(BasePage):
def __init__(self, driver):
super().__init__(driver)
self.username_input = (AppiumBy.ID, "com.example.app:id/username")
self.password_input = (AppiumBy.ID, "com.example.app:id/password")
self.login_button = (AppiumBy.ID, "com.example.app:id/login_btn")
def login(self, username, password):
self.input_text(*self.username_input, username)
self.input_text(*self.password_input, password)
self.click_element(*self.login_button)
# tests/test_login_flow.py
import unittest
from pages.login_page import LoginPage
class TestLoginFlow(unittest.TestCase):
def test_initial_setup(self):
# 初始化drivers和页面对象
self.driver = setup_driver()
self.login_page = LoginPage(self.driver)
def test_valid_login(self):
self.login_page.login("testuser@example.com", "password123")
# 验证登录成功
assert "登录成功" in self.driver.page_source
def test_invalid_login(self):
self.login_page.login("invalid@test.com", "wrongpass")
# 验证错误信息
assert "无效" in self.driver.page_source
运行测试
命令行运行
# 运行特定测试 python -m pytest test_login.py -v # 运行Page Object框架测试 python -m pytest tests/test_login_flow.py -v # 生成测试报告 python -m pytest test_*.py -v --html=report.html
并行执行测试
# conftest.py
import pytest
from appium import webdriver
@pytest.fixture(scope="function")
def android_driver():
caps = {...
}
driver = webdriver.Remote('http://localhost:4723/wd/hub', caps)
yield driver
driver.quit()
@pytest.fixture(scope="function")
def ios_driver():
caps = {...}
driver = webdriver.Remote('http://localhost:4723/wd/hub', caps)
yield driver
driver.quit()
这些案例涵盖了Appium自动化测试的常见场景,包括:
- 基本功能测试(登录、注册)
- 复杂流程测试(购物流程)
- 手势操作测试(滑动、缩放、长按)
- 页面对象模型(POM框架)
- 多平台支持(Android和iOS)
每个案例都考虑了异常处理和最佳实践,您可以根据具体的应用场景调整和扩展这些代码。