【从 0 - 1 实现永辉生活 APP UI 自动化测试的详细教程-直接上实战教程】

项目结构

yonghui_app_ui_test/
├── config/
│   └── config.py
├── pages/
│   ├── base_page.py
│   ├── home_page.py
│   ├── search_page.py
│   ├── category_page.py
│   ├── cart_page.py
│   ├── personal_center_page.py
│   └── product_detail_page.py
├── tests/
│   ├── test_home.py
│   ├── test_search.py
│   ├── test_category.py
│   ├── test_cart.py
│   ├── test_personal_center.py
│   └── ...
├── utils/
│   ├── logger.py
│   └── ...
└── run_tests.py

1. 配置文件(config/config.py

# 配置 Appium 所需的参数
DESIRED_CAPS = {
    "platformName": "Android",  # 或 "iOS"
    "platformVersion": "你的 Android 版本",
    "deviceName": "你的设备名称",
    "appPackage": "com.yonghui.mall",  # 永辉生活 APP 包名
    "appActivity": "你的启动 Activity",
    "noReset": True
}

# Appium 服务器地址
APPIUM_SERVER_URL = 'http://localhost:4723/wd/hub'

2. 日志工具(utils/logger.py

import logging

def setup_logger():
    logger = logging.getLogger(__name__)
    logger.setLevel(logging.DEBUG)

    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

    # 控制台输出
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)
    console_handler.setFormatter(formatter)
    logger.addHandler(console_handler)

    # 文件输出
    file_handler = logging.FileHandler('test.log')
    file_handler.setLevel(logging.DEBUG)
    file_handler.setFormatter(formatter)
    logger.addHandler(file_handler)

    return logger

logger = setup_logger()

3. 基础页面类(pages/base_page.py

from appium import webdriver
from utils.logger import logger
from config.config import DESIRED_CAPS, APPIUM_SERVER_URL

class BasePage:
    def __init__(self):
        self.driver = webdriver.Remote(APPIUM_SERVER_URL, DESIRED_CAPS)
        logger.info("Appium 驱动已初始化")

    def find_element(self, by, value):
        try:
            element = self.driver.find_element(by, value)
            logger.info(f"成功找到元素: {by}={value}")
            return element
        except Exception as e:
            logger.error(f"未找到元素: {by}={value}, 错误信息: {e}")
            raise

    def click(self, by, value):
        element = self.find_element(by, value)
        element.click()
        logger.info(f"点击元素: {by}={value}")

    def send_keys(self, by, value, text):
        element = self.find_element(by, value)
        element.send_keys(text)
        logger.info(f"向元素 {by}={value} 输入文本: {text}")

    def is_element_displayed(self, by, value):
        try:
            element = self.find_element(by, value)
            return element.is_displayed()
        except Exception:
            return False

    def close_app(self):
        self.driver.quit()
        logger.info("Appium 驱动已关闭")

    def assert_element_displayed(self, by, value, message):
        result = self.is_element_displayed(by, value)
        assert result, message
        logger.info(f"断言成功: {message}")

4. 首页页面类(pages/home_page.py

from pages.base_page import BasePage
from appium.webdriver.common.by import By

class HomePage(BasePage):
    # 首页广告位
    ADVERTISEMENT = (By.ID, "com.yonghui.mall:id/advertisement")
    # 分享按钮
    SHARE_BUTTON = (By.ID, "com.yonghui.mall:id/share_button")
    # 返回首页按钮
    BACK_HOME_BUTTON = (By.ID, "com.yonghui.mall:id/back_home_button")
    # 商品元素
    PRODUCT = (By.ID, "com.yonghui.mall:id/product")

    def click_advertisement(self):
        self.click(*self.ADVERTISEMENT)
        # 可根据广告页面特征元素添加断言
        # 这里假设广告页面有个特定标题元素
        AD_TITLE = (By.ID, "com.yonghui.mall:id/ad_title")
        self.assert_element_displayed(*AD_TITLE, "点击广告后广告页面标题元素未显示")

    def click_share_button(self):
        self.click(*self.SHARE_BUTTON)
        # 假设分享弹窗有个分享渠道列表元素
        SHARE_CHANNEL_LIST = (By.ID, "com.yonghui.mall:id/share_channel_list")
        self.assert_element_displayed(*SHARE_CHANNEL_LIST, "点击分享按钮后分享渠道列表未显示")

    def click_back_home(self):
        self.click(*self.BACK_HOME_BUTTON)
        # 假设首页有个特定的 logo 元素
        HOME_LOGO = (By.ID, "com.yonghui.mall:id/home_logo")
        self.assert_element_displayed(*HOME_LOGO, "点击返回首页后首页 logo 未显示")

    def click_product(self):
        self.click(*self.PRODUCT)
        # 假设商品详情页有个商品名称元素
        PRODUCT_NAME = (By.ID, "com.yonghui.mall:id/product_name")
        self.assert_element_displayed(*PRODUCT_NAME, "点击商品后商品详情页商品名称未显示")

5. 商品详情页页面类(pages/product_detail_page.py

from pages.base_page import BasePage
from appium.webdriver.common.by import By

class ProductDetailPage(BasePage):
    # 加购按钮
    ADD_TO_CART_BUTTON = (By.ID, "com.yonghui.mall:id/add_to_cart_button")
    # 返回按钮
    BACK_BUTTON = (By.ID, "com.yonghui.mall:id/back_button")
    # 加购成功提示元素
    ADD_SUCCESS_TIP = (By.ID, "com.yonghui.mall:id/add_success_tip")

    def add_to_cart(self):
        self.click(*self.ADD_TO_CART_BUTTON)
        self.assert_element_displayed(*self.ADD_SUCCESS_TIP, "加购商品后加购成功提示未显示")

    def click_back(self):
        self.click(*self.BACK_BUTTON)
        # 假设返回后回到首页,检查首页 logo
        HOME_LOGO = (By.ID, "com.yonghui.mall:id/home_logo")
        self.assert_element_displayed(*HOME_LOGO, "点击返回后首页 logo 未显示")

6. 分类页页面类(pages/category_page.py

from pages.base_page import BasePage
from appium.webdriver.common.by import By

class CategoryPage(BasePage):
    # 一级分类
    FIRST_CATEGORY = (By.ID, "com.yonghui.mall:id/first_category")
    # 二级分类
    SECOND_CATEGORY = (By.ID, "com.yonghui.mall:id/second_category")
    # 三级分类
    THIRD_CATEGORY = (By.ID, "com.yonghui.mall:id/third_category")
    # 分类商品加购按钮
    CATEGORY_PRODUCT_ADD_TO_CART = (By.ID, "com.yonghui.mall:id/category_product_add_to_cart")
    # 分类商品取消加购按钮
    CATEGORY_PRODUCT_REMOVE_FROM_CART = (By.ID, "com.yonghui.mall:id/category_product_remove_from_cart")
    # 二级分类列表元素
    SECOND_CATEGORY_LIST = (By.ID, "com.yonghui.mall:id/second_category_list")
    # 三级分类列表元素
    THIRD_CATEGORY_LIST = (By.ID, "com.yonghui.mall:id/third_category_list")
    # 加购成功提示元素
    ADD_SUCCESS_TIP = (By.ID, "com.yonghui.mall:id/add_success_tip")
    # 取消加购成功提示元素
    REMOVE_SUCCESS_TIP = (By.ID, "com.yonghui.mall:id/remove_success_tip")

    def click_first_category(self):
        self.click(*self.FIRST_CATEGORY)
        self.assert_element_displayed(*self.SECOND_CATEGORY_LIST, "点击一级分类后二级分类列表未显示")

    def click_second_category(self):
        self.click(*self.SECOND_CATEGORY)
        self.assert_element_displayed(*self.THIRD_CATEGORY_LIST, "点击二级分类后三级分类列表未显示")

    def click_third_category(self):
        self.click(*self.THIRD_CATEGORY)
        # 假设点击三级分类后有个商品列表元素
        PRODUCT_LIST = (By.ID, "com.yonghui.mall:id/product_list")
        self.assert_element_displayed(*PRODUCT_LIST, "点击三级分类后商品列表未显示")

    def add_product_from_category(self):
        self.click(*self.CATEGORY_PRODUCT_ADD_TO_CART)
        self.assert_element_displayed(*self.ADD_SUCCESS_TIP, "分类页加购商品后加购成功提示未显示")

    def remove_product_from_category(self):
        self.click(*self.CATEGORY_PRODUCT_REMOVE_FROM_CART)
        self.assert_element_displayed(*self.REMOVE_SUCCESS_TIP, "分类页取消加购商品后取消加购成功提示未显示")

7. 购物车页页面类(pages/cart_page.py

from pages.base_page import BasePage
from appium.webdriver.common.by import By

class CartPage(BasePage):
    # 删除商品按钮
    DELETE_PRODUCT_BUTTON = (By.ID, "com.yonghui.mall:id/delete_product_button")
    # 添加商品按钮
    ADD_PRODUCT_IN_CART = (By.ID, "com.yonghui.mall:id/add_product_in_cart")
    # 切换地址按钮
    SWITCH_ADDRESS_BUTTON = (By.ID, "com.yonghui.mall:id/switch_address_button")
    # 去结算按钮
    CHECKOUT_BUTTON = (By.ID, "com.yonghui.mall:id/checkout_button")
    # 删除成功提示元素
    DELETE_SUCCESS_TIP = (By.ID, "com.yonghui.mall:id/delete_success_tip")
    # 商品数量增加提示元素
    ADD_QUANTITY_TIP = (By.ID, "com.yonghui.mall:id/add_quantity_tip")
    # 地址选择页面元素
    ADDRESS_SELECT_PAGE = (By.ID, "com.yonghui.mall:id/address_select_page")

    def delete_product(self):
        self.click(*self.DELETE_PRODUCT_BUTTON)
        self.assert_element_displayed(*self.DELETE_SUCCESS_TIP, "购物车删除商品后删除成功提示未显示")

    def add_product_in_cart(self):
        self.click(*self.ADD_PRODUCT_IN_CART)
        self.assert_element_displayed(*self.ADD_QUANTITY_TIP, "购物车添加商品后商品数量增加提示未显示")

    def switch_address(self):
        self.click(*self.SWITCH_ADDRESS_BUTTON)
        self.assert_element_displayed(*self.ADDRESS_SELECT_PAGE, "点击切换地址后地址选择页面未显示")

    def go_to_checkout(self):
        self.click(*self.CHECKOUT_BUTTON)
        # 由于跳过真实支付,这里可根据结算页面特征元素添加断言
        CHECKOUT_PAGE_TITLE = (By.ID, "com.yonghui.mall:id/checkout_page_title")
        self.assert_element_displayed(*CHECKOUT_PAGE_TITLE, "点击去结算后结算页面标题未显示")

8. 个人中心页页面类(pages/personal_center_page.py

from pages.base_page import BasePage
from appium.webdriver.common.by import By

class PersonalCenterPage(BasePage):
    # 个人中心信息
    PERSONAL_INFO = (By.ID, "com.yonghui.mall:id/personal_info")
    # 头像
    AVATAR = (By.ID, "com.yonghui.mall:id/avatar")
    # 优惠券
    COUPONS = (By.ID, "com.yonghui.mall:id/coupons")
    # 永辉卡
    YONGHUI_CARD = (By.ID, "com.yonghui.mall:id/yonghui_card")
    # 个人信息页面元素
    PERSONAL_INFO_PAGE = (By.ID, "com.yonghui.mall:id/personal_info_page")
    # 优惠券列表元素
    COUPON_LIST = (By.ID, "com.yonghui.mall:id/coupon_list")
    # 永辉卡页面元素
    YONGHUI_CARD_PAGE = (By.ID, "com.yonghui.mall:id/yonghui_card_page")

    def click_personal_info(self):
        self.click(*self.PERSONAL_INFO)
        self.assert_element_displayed(*self.PERSONAL_INFO_PAGE, "点击个人中心信息后个人信息页面未显示")

    def click_avatar(self):
        self.click(*self.AVATAR)
        # 假设点击头像后有个头像设置相关元素
        AVATAR_SETTING = (By.ID, "com.yonghui.mall:id/avatar_setting")
        self.assert_element_displayed(*AVATAR_SETTING, "点击头像后头像设置元素未显示")

    def click_coupons(self):
        self.click(*self.COUPONS)
        self.assert_element_displayed(*self.COUPON_LIST, "点击优惠券后优惠券列表未显示")

    def click_yonghui_card(self):
        self.click(*self.YONGHUI_CARD)
        self.assert_element_displayed(*self.YONGHUI_CARD_PAGE, "点击永辉卡后永辉卡页面未显示")

9. 测试用例

首页测试用例(tests/test_home.py
import unittest
from pages.home_page import HomePage
from pages.product_detail_page import ProductDetailPage
from utils.logger import logger

class TestHome(unittest.TestCase):
    def setUp(self):
        self.home_page = HomePage()

    def test_home_functions(self):
        try:
            # 点击广告位
            self.home_page.click_advertisement()
            # 点击分享按钮
            self.home_page.click_share_button()
            # 返回首页
            self.home_page.click_back_home()
            # 点击商品进入详情页
            self.home_page.click_product()
            product_detail_page = ProductDetailPage()
            # 加购商品
            product_detail_page.add_to_cart()
            # 返回首页
            product_detail_page.click_back()
            logger.info("首页功能测试通过")
        except AssertionError as e:
            logger.error(f"首页功能测试断言失败: {e}")
            self.fail(f"首页功能测试断言失败: {e}")
        except Exception as e:
            logger.error(f"首页功能测试出现异常: {e}")
            self.fail(f"首页功能测试出现异常: {e}")

    def tearDown(self):
        self.home_page.close_app()

分类页测试用例(tests/test_category.py
import unittest
from pages.category_page import CategoryPage
from utils.logger import logger

class TestCategory(unittest.TestCase):
    def setUp(self):
        self.category_page = CategoryPage()

    def test_category_functions(self):
        try:
            # 切换一级分类
            self.category_page.click_first_category()
            # 切换二级分类
            self.category_page.click_second_category()
            # 切换三级分类
            self.category_page.click_third_category()
            # 加购商品
            self.category_page.add_product_from_category()
            # 取消加购
            self.category_page.remove_product_from_category()
            logger.info("分类页功能测试通过")
        except AssertionError as e:
            logger.error(f"分类页功能测试断言失败: {e}")
            self.fail(f"分类页功能测试断言失败: {e}")
        except Exception as e:
            logger.error(f"分类页功能测试出现异常: {e}")
            self.fail(f"分类页功能测试出现异常: {e}")

    def tearDown(self):
        self.category_page.close_app()

购物车页测试用例(tests/test_cart.py
import unittest
from pages.cart_page import CartPage
from utils.logger import logger

class TestCart(unittest.TestCase):
    def setUp(self):
        self.cart_page = CartPage()

    def test_cart_functions(self):
        try:
            # 删除商品
            self.cart_page.delete_product()
            # 添加商品
            self.cart_page.add_product_in_cart()
            # 切换地址
            self.cart_page.switch_address()
            # 由于跳过真实支付,不去点击去结算
            logger.info("购物车页功能测试通过")
        except AssertionError as e:
            logger.error(f"购物车页功能测试断言失败: {e}")
            self.fail(f"购物车页功能测试断言失败: {e}")
        except
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

生活De°咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值