UI自动化测试实战

1 自动化测试流程

步骤:

  1. 需求分析
  2. 挑选适合做自动化测试的功能【人力不足时,选择冒烟测试】
  3. 设计并筛选测试用例
  4. 搭建自动化测试环境
  5. 设计自动化测试项目的架构
  6. 编写代码
  7. 执行测试用例
  8. 生成测试报告并分析结果

在这里插入图片描述

2 项目介绍

2.1 项目功能和技术

  1. 业务特性
  2. 用户和角色
  3. 功能模块
  4. 技术栈

2.2 项目简介

项目名称
TPShop开源商城系统
项目描述
TPShop是一个电子商务B2C电商平台系统,功能强大安全便捷。适合企业及个人快速构建个性化网上商城

包含PC+IOS客户端+Android客户端+微商城,系统PC+后台是基于ThinkPHP MVC构架开发的跨平台开源软件设计得非常灵活,具有模块化架构体系和丰富的功能,易于与第三方应用系统无缝集成,在设计上,包含相当全面,以模块化架构体系,让应用组合变得相当灵活,功能也相当丰富

项目架构
Windows + PHP + Apache + MySQL

2.3 用例设计

编写规则

  1. 自动化测试用例一般只实现核心业务流程或者重复率较高功能
  2. 自动化测试用例的选择一般以“正向”逻辑的验证为主
  3. 不是所有手工测试用例都可以使用自动化测试
  4. 尽量减少多个用例脚本之间的依赖
  5. 自动化测试执行用例完毕后,一般需要回归原点

在这里插入图片描述

2.4 编写代码

2.4.1 公共方法

base.action.py

class BaseAction:
    # 初始化驱动
    def __init__(self, driver):
        self.driver = driver

    # 查找单个元素
    def find_el(self, feature):
        return self.driver.find_element(*feature)

    # 查找多个元素
    def find_els(self, feature):
        return self.driver.find_elements(*feature)

    # 查找按钮元素
    def click(self, feature):
        return self.find_el(feature).click()

    # 查找输入元素
    def input(self, feature, content):
        return self.find_el(feature).send_keys(content)

    # 清空
    def clear(self, feature):
        return self.find_el(feature).clear()

    # 定位数字按钮
    def find_el_num(self, feature, num):
        return self.driver.find_element(feature[0], feature[1].format(str(num)))

    # 切换指定的页面
    def switch_to(self, frame_feature):
        return self.driver.switch_to.frame(self.find_el(frame_feature))

    # 切换回默认页面
    def switch_to_default(self):
        return self.driver.switch_to_default_content()

    # 切换新窗口
    def switch_windows(self):
        handles = self.driver.window_handles()
        return self.driver.switch_to(handles[-1])

driver_utils.py

# 获取/关闭浏览器驱动的类
from selenium import webdriver


class DriverUtils:
    __driver = None
    __switch = True

    # 获取浏览器驱动
    @classmethod
    def get_driver(cls):
        if cls.__driver is None:
            cls.__driver = webdriver.Chrome()
            cls.__driver.maximize_window()
            cls.__driver.implicitly_wait(10)
        return cls.__driver

    # 关闭浏览器驱动
    @classmethod
    def quit_driver(cls):
        if cls.__driver is not None and cls.__switch is False:
            cls.__driver.quit()
            cls.__driver = None

    # 设置浏览器开关
    @classmethod
    def set_switch(cls, switch):
            cls.__switch = switch

read_data.py

# 读取data数据文件
import json


def read_data(filename):
    with open("./data/" + filename, "r", encoding="utf-8") as f:
        list_data = []
        dict_list = json.load(f)
        for value in dict_list.values():
            list_data.append(value)
        return list_data

2.4.2 抽取PO

1. 定义页面对象

首页:index_page.py

# 首页
from selenium.webdriver.common.by import By

from base.base_action import BaseAction


class IndexPage(BaseAction):
    # 登录链接
    login_link_btn = By.CLASS_NAME, "red"
    # 搜索框
    search_input = By.ID, "q"
    # 搜索 按钮
    search_btn = By.CLASS_NAME, "ecsc-search-button"
    # 购物车 链接
    my_cart_link = By.CLASS_NAME, "c-n"
    # 我的订单 链接
    my_order_link = By.XPATH, "/html/body/div[1]/div[1]/div/ul/li[1]/a"

    # 点击首页的"登录"链接, 进入登录页面
    def click_login_link(self):
        return self.click(self.login_link_btn)

    # 输入关键字,进行搜索商品
    def input_keywords(self, content):
        return self.input(self.search_input, content)

    # 点击搜索按钮
    def click_search_btn(self):
        return self.click(self.search_btn)

    # 点击"我的订单"链接
    def click_my_order_link(self):
        return self.click(self.my_order_link)

    # 点击"我的购物车"链接
    def click_my_cart_link(self):
        return self.click(self.my_cart_link)

登录页:login_page.py

# 登录页面
from selenium.webdriver.common.by import By
from base.base_action import BaseAction


class LoginPage(BaseAction):
    # 登录链接 按钮
    login_link_btn = By.CLASS_NAME, "red"
    # 用户名 输入框
    username_input = By.ID, "username"
    # 密码 输入框
    password_input = By.ID, "password"
    # 验证码 输入框
    verify_code_input = By.ID, "verify_code"
    # 登录 按钮
    login_btn = By.NAME, "sbtbutton"

    # 点击首页的"登录"链接, 进入登录页面
    def click_login_link(self):
        return self.click(self.login_link_btn)

    # 输入用户名
    def input_username(self, content):
        return self.input(self.username_input, content)

    # 输入密码
    def input_password(self, content):
        return self.input(self.password_input, content)

    # 输入验证码
    def input_verify_code(self, content):
        return self.input(self.verify_code_input, content)

    # 点击登录按钮
    def click_login_btn(self):
        return self.click(self.login_btn)

个人中心页:home_page.py (登录成功之后会跳转到该页面)

# 个人中心页面
from selenium.webdriver.common.by import By

from base.base_action import BaseAction


class HomePage(BaseAction):
    # 立即支付 按钮
    pay_btn = By.CLASS_NAME, "ps_lj"
    # 待付款标签
    pend_pay = By.XPATH, "//*[text()='待付款']"

    # 点击立即付款按钮
    def click_immed_pay_btn(self):
        return self.click(self.pay_btn)

    # 点击付款链接
    def click_pay_btn(self):
        return self.click(self.pend_pay)

商品搜索页:goods_search_page.py(搜索商品之后的页面,即搜索后的列表)

# 商品搜索页面
from selenium.webdriver.common.by import By
from base.base_action import BaseAction


class GoodsSearchPage(BaseAction):
    # 加入购物车
    add_cart_btn = By.XPATH, "/html/body/div[4]/div/div[2]/div[2]/ul/li[1]/div/div[5]/div[2]/a"

    # 点击加入购物车按钮
    def click_add_cart_btn(self):
        return self.click(self.add_cart_btn)

商品详情页:goods_detail_page.py

# 商品详情页面
from selenium.webdriver.common.by import By
from base.base_action import BaseAction


class GoodsDetailPage(BaseAction):
    # 加入购物车
    details_add_cart_btn = By.CSS_SELECTOR, ".addcar"

    # iframe
    cart_iframe = By.CSS_SELECTOR, "[id*='layui-layer-iframe']]"

    # 加入购物车成提示语
    result_msg = By.CSS_SELECTOR, "#addCartBox > div.colect-top > div > span"

    # 点击加入购物车 按钮
    def click_details_add_cart_btn(self):
        return self.click(self.details_add_cart_btn)

    # 获取弹窗框的结果
    def get_result(self):
        # 切换到iframe中,再获取结果
        self.switch_to(self.cart_iframe)
        return self.find_el(self.result_msg).text

购物车页:cart_page.py

# 购物车页面
from selenium.webdriver.common.by import By
from base.base_action import BaseAction


class CartPage(BaseAction):
    # 结算按钮
    go_to_btn = By.CLASS_NAME, "gwc-qjs"

    # 点击结算按钮
    def click_go_to_btn(self):
        return self.click(self.go_to_btn)

下订单页:order_page.py

# 下订单页面
from selenium.webdriver.common.by import By
from base.base_action import BaseAction


class OrderPage(BaseAction):
    # 提交订单按钮
    submit_btn = By.CLASS_NAME, "Sub-orders"

    # 点击提交订单按钮
    def click_submitr_btn(self):
        return self.click(self.submit_btn)

订单支付页:order_pay_page.py

# 订单支付页面
from selenium.webdriver.common.by import By
from base.base_action import BaseAction


class OrderPayPage(BaseAction):
    # 订单状态信息
    tips_info = By.XPATH, "/html/body/div[2]/div/div[2]/div[1]/h3"
    # 货到付款选择
    arrived_pay = By.XPATH, "//input[@value='pay_code=cod']"
    # 确认支付方式 按钮
    pay_btn = By.CLASS_NAME, "button-confirm-payment"

    # 获取订单状态信息
    def click_tips_info(self):
        return self.find_el(self.tips_info).text

    # 点击货到付款选框
    def click_arrived_pay(self):
        return self.click(self.arrived_pay)

    # 确认支付方式 按钮
    def click_pay_btn(self):
        return self.click(self.pay_btn)

总结: 首先根据测试流程,简写出每一步关键词(流程),根据页面再写出属性和方法

2. 编写测试脚本

登录模块:test_login.py

# 导包
import json
import time
import pytest
from page.index_page import IndexPage
from page.login_page import LoginPage
from utils.driver_utils import DriverUtils
from utils.read_data import read_data


# 定义测试类
class TestLogin:

    def setup_method(self):
        self.driver = DriverUtils.get_driver()
        DriverUtils.set_switch(True)
        self.login_page = LoginPage(self.driver)
        self.index_page = IndexPage(self.driver)
        self.driver.get("http://192.168.157.137")

    def teardown_method(self):
        time.sleep(5)
        DriverUtils.quit_driver()

    @pytest.mark.parametrize("params", read_data("login_data.json"))
    def test_login(self, params):
        # 1. 点击首页的"登录"链接, 进入登录页面
        self.index_page.click_login_link()
        # 2. 输入用户名
        self.login_page.input_username(params["username"])
        # 3. 输入一个错误密码
        self.login_page.input_password(params["password"])
        # 4. 输入验证码
        self.login_page.input_verify_code(params["code"])
        # 5. 点击登录按钮
        self.login_page.click_login_btn()
        # 暂停5秒,等待跳转
        time.sleep(5)
        # 断言,判断页面的title,是否一致
        assert params["msg"] in self.driver.title

购物车模块:test_cart.py

import logging
import time
import pytest

from page.cart_page import CartPage
from page.goods_detail_page import GoodsDetailPage
from page.goods_search_page import GoodsSearchPage
from page.index_page import IndexPage
from utils.driver_utils import DriverUtils
from utils.read_data import read_data


class TestCart:
    def setup_method(self):
        self.driver = DriverUtils.get_driver()
        self.index_page = IndexPage(self.driver)
        self.goods_search_page = GoodsSearchPage(self.driver)
        self.goods_detail_page = GoodsDetailPage(self.driver)
        self.driver.get("http://192.168.157.137")

    def teardown_method(self):
        time.sleep(5)
        DriverUtils.quit_driver()

    @pytest.mark.parametrize("params", read_data("cart_data.json"))
    def test_search_to_cart(self, params):
        # 1. 点击首页搜索框输入关键字
        self.index_page.input_keywords(params["keywords"])
        # 2. 点击搜索按钮
        self.index_page.click_search_btn()
        logging.info("search XiaoMiPhone")
        # 3. 点击搜索列表“加入购物车”按钮
        self.goods_search_page.click_add_cart_btn()
        # 4. 在商品详情页面,点击添加购物车
        self.goods_detail_page.click_details_add_cart_btn()
        # 等待弹窗,5秒之后
        time.sleep(5)
        logging.info("wait 5s for the page to display")
        # 断言,查看是否"添加成功"字样
        assert params["msg"] == self.goods_detail_page.get_result()	

订单模块:testt_order.py

import logging
import time
import pytest

from page.cart_page import CartPage
from page.home_page import HomePage
from page.index_page import IndexPage
from page.order_page import OrderPage
from page.order_pay_page import OrderPayPage
from utils.driver_utils import DriverUtils
from utils.read_data import read_data


class TestOrder:
    def setup_method(self):
        self.driver = DriverUtils.get_driver()
        self.index_page = IndexPage(self.driver)
        self.order_page = OrderPage(self.driver)
        self.order_pay_page = OrderPayPage(self.driver)
        self.cart_page = CartPage(self.driver)
        self.home_page = HomePage(self.driver)
        self.driver.get("http://192.168.157.137")

    def teardown_method(self):
        time.sleep(5)
        self.driver.get_screenshot_as_file("./screenshot/tpshop.png")
        DriverUtils.quit_driver()

    @pytest.mark.parametrize("params", read_data("order_data.json"))
    def test_submit_order(self, params):
        # 1. 首页点击"我的购物车"
        self.index_page.click_my_cart_link()
        # 2. 点击去结算
        self.cart_page.click_go_to_btn()
        logging.info("go settle")
        # 等待5秒
        time.sleep(5)
        logging.info("wait 5s for the page to display")
        # 1. 点击提交订单按钮
        self.order_page.click_submitr_btn()
        logging.info("submit order")
        # 断言,判断状态信息是否正确
        assert params["msg"] == self.order_pay_page.click_tips_info()

    @pytest.mark.parametrize("params", read_data("pay_data.json"))
    def test_pay(self, params):
        # 1. 点击"我的订单"
        self.index_page.click_my_order_link()
        time.sleep(5)
        # 2. 在个人中心点击”待付款“
        self.home_page.click_immed_pay_btn()
        time.sleep(5)
        # 3. 点击立即支付按钮
        self.home_page.click_pay_btn()
        time.sleep(5)
        # 4. 点击选择货到付款
        self.order_pay_page.click_arrived_pay()
        # 5. 点击确认支付方式按钮
        self.order_pay_page.click_pay_btn()
        logging.info("Confirm payment")
        time.sleep(5)
        logging.info("wait 5s for the page to display")
        # 断言 状态
        assert params["msg"] == self.order_pay_page.click_tips_info()

注意: 建议每个功能模块对应一个py文件

3. 日志配置类

import logging.handlers


def set_log_config():
    # 创建日志器对象
    logger = logging.getLogger()
    # 设置日志器级别
    logger.setLevel(level=logging.DEBUG)
    # 创建处理器对象 输出到控制台
    ls = logging.StreamHandler()
    lf = logging.handlers.TimedRotatingFileHandler(filename="./log/tshop.log", when="d", backupCount=3)
    # 创建格式器对象
    fmt = "%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(funcName)s:%(lineno)d] - %(message)s"
    formartter = logging.Formatter(fmt=fmt)
    # 将格式器添加到处理器
    ls.setFormatter(formartter)
    lf.setFormatter(formartter)
    # 将处理器添加到日志器
    logger.addHandler(ls)
    logger.addHandler(lf)

2.5 视频

在这里插入图片描述

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
pytest ui自动化测试实战主要包括安装并配置环境、练习pytest基本使用、练习selenium基本使用以及使用pytest和selenium实现UI自动化测试四个部分。在练习pytest基本使用中,我们可以通过编写简单的用例格式来实现对测试目的和要求的覆盖。而在练习selenium基本使用中,我们可以使用脚本语言来模拟用户行为操作,接近真实用户场景,实现对web页面的自动化测试。通过这些实践,我们可以了解基于pytest和seleniumUI自动化测试的基本思路,并熟悉这两种测试工具的基本操作。此外,pytest还是一个非常成熟的Python测试框架,它具有简单的用例编写格式和丰富的插件,如pytest-html和pytest-rerunfailures等,可以生成漂亮的测试报告并实现失败用例的重复执行。通过实战,我们可以基本掌握pytest的使用方法。另外,还可以基于pytest实现测试用例收集方案、自定义参数化方案、页面元素定位数据存储方案、测试用例数据存储和维护方案等,以避免重复设计和维护复杂的问题。此外,还可以修改定制并汉化html测试报告,使其更加简洁、美观、易读。同时,还可以封装集成selenium、appium、minium和WinAppDriver等工具,以更好地支持不同平台和应用的自动化测试。总之,通过pytest ui自动化测试实战,我们可以全面了解和掌握UI自动化测试的基本原理和实践技巧。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [软件测试案例|使用 pytest+selenium 进行UI自动化测试](https://blog.csdn.net/qq_41640218/article/details/124031645)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [基于pytest设计自动化测试框架实战](https://blog.csdn.net/hotswwkyo/article/details/103211805)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值