小小米早餐配送服务测试用例

功能测试

后台端登录

登录页面30条用例

添加购物车功能

接口测试

接口测试

编写测试用例:id,名称,所属模块,优先级,前置条件,准备数据,执行步骤,预期结果,实际结果

id,模块,优先级,用例名称,接口名称,请求url, 请求类型,请求头,请求参数类型,请求参数,预期结果,测试结果

分类接口测试用例:

ID模块用例名称接口名称URL请求方法请求头请求参数类型请求参数预期结果测试结果
1分类模块成功新增早餐分类新增分类接口/categoryPOSTContent-Type: application/jsonJSON{ "name": "面包", "type": "1", "sort": 1 }{"code": 1, "msg": "新增分类成功", "data": null}通过
2分类模块成功新增套餐分类新增分类接口/categoryPOSTContent-Type: application/jsonJSON{ "name": "套餐A", "type": "2", "sort": 2 }{"code": 1, "msg": "新增分类成功", "data": null}通过
3分类模块分类名称为空新增分类接口/categoryPOSTContent-Type: application/jsonJSON{ "name": "", "type": "1", "sort": 3 }{"code": 0, "msg": "请输入分类名称或排序"}通过
4分类模块分类类型缺失新增分类接口/categoryPOSTContent-Type: application/jsonJSON{ "name": "粥", "sort": 4 }{"code": 0, "msg": "分类类型不能为空"}通过
5分类模块排序字段为空新增分类接口/categoryPOSTContent-Type: application/jsonJSON{ "name": "牛奶", "type": "1", "sort": "" }{"code": 0, "msg": "排序值不能为空"}通过
6分类模块排序字段为非数字字符新增分类接口/categoryPOSTContent-Type: application/jsonJSON{ "name": "果汁", "type": "1", "sort": "abc" }{"code": 0, "msg": "排序只能输入数字类型"}通过
7分类模块重复的分类名称和类型新增分类接口/categoryPOSTContent-Type: application/jsonJSON{ "name": "面包", "type": "1", "sort": 5 }{"code": 0, "msg": "分类名称已存在"}通过
8分类模块分类类型无效新增分类接口/categoryPOSTContent-Type: application/jsonJSON{ "name": "水果", "type": "3", "sort": 6 }{"code": 0, "msg": "无效的分类类型"}通过

登录接口测试用例

ID模块用例名称接口名称URL请求方法请求头请求参数类型请求参数预期结果测试结论
1登录模块正常登录login/employee/loginPOSTContent-Type: application/jsonJSON{"username": "admin", "password": "123456"}登录成功通过
2登录模块密码错误login/employee/loginPOSTContent-Type: application/jsonJSON{"username": "admin", "password": "wrongpassword"}登录失败通过
3登录模块用户不存在login/employee/loginPOSTContent-Type: application/jsonJSON{"username": "notexist", "password": "123456"}登录失败通过
4登录模块账号已禁用login/employee/loginPOSTContent-Type: application/jsonJSON{"username": "disabledUser", "password": "123456"}账号已禁用通过

添加早餐接口测试用例

ID模块优先级用例名称接口名称请求URL请求类型请求头请求参数类型请求参数预期结果测试结果
TC01早餐管理添加早餐成功添加早餐/dishPOSTContent-Type: application/jsonJSON{"name": "鸡蛋饼", "price": 15.5, "categoryId": 3, "description": "美味的鸡蛋饼", "status": 1, "flavors": [{"name": "甜", "value": "加糖"}, {"name": "辣", "value": "加辣椒"}]}响应状态码为200,返回成功消息 "新增菜品成功"通过
TC02早餐管理添加早餐 - 缺少必填字段添加早餐/dishPOSTContent-Type: application/jsonJSON{"price": 15.5, "categoryId": 3, "description": "美味的鸡蛋饼", "status": 1}响应状态码为400,返回错误消息 "请求参数错误"通过
TC03早餐管理添加早餐 - 价格为负数添加早餐/dishPOSTContent-Type: application/jsonJSON{"name": "鸡蛋饼", "price": -5, "categoryId": 3, "description": "美味的鸡蛋饼", "status": 1}响应状态码为400,返回错误消息 "请求参数错误"通过
TC04早餐管理添加早餐 - 状态为无效值添加早餐/dishPOSTContent-Type: application/jsonJSON{"name": "鸡蛋饼", "price": 15.5, "categoryId": 3, "description": "美味的鸡蛋饼", "status": 2}响应状态码为400,返回错误消息 "请求参数错误"通过
TC05早餐管理添加早餐 - 口味信息为空添加早餐/dishPOSTContent-Type: application/jsonJSON{"name": "鸡蛋饼", "price": 15.5, "categoryId": 3, "description": "美味的鸡蛋饼", "status": 1, "flavors": []}响应状态码为200,返回成功消息 "新增菜品成功"通过
TC06早餐管理添加早餐 - 口味名称缺失添加早餐/dishPOSTContent-Type: application/jsonJSON{"name": "鸡蛋饼", "price": 15.5, "categoryId": 3, "description": "美味的鸡蛋饼", "status": 1, "flavors": [{"value": "加糖"}]}响应状态码为400,返回错误消息 "请求参数错误"通过
TC07早餐管理添加早餐 - 大批量数据测试添加早餐/dishPOSTContent-Type: application/jsonJSON大量菜品数据(例如 1000 条记录)响应状态码为200,所有菜品正确添加通过
TC08早餐管理添加早餐 - 重复菜品名称添加早餐/dishPOSTContent-Type: application/jsonJSON{"name": "鸡蛋饼", "price": 15.5, "categoryId": 3, "description": "重复的鸡蛋饼", "status": 1}响应状态码为200,返回成功消息 "新增菜品成功"通过
TC09早餐管理添加早餐 - 特殊字符输入添加早餐/dishPOSTContent-Type: application/jsonJSON{"name": "<鸡蛋饼>", "price": 15.5, "categoryId": 3, "description": "包含特殊字符的描述!@#$%^&*()", "status": 1}响应状态码为200,返回成功消息 "新增菜品成功"通过
TC10早餐管理添加早餐 - 长字段测试添加早餐/dishPOSTContent-Type: application/jsonJSON{"name": "鸡蛋饼", "price": 15.5, "categoryId": 3, "description": "非常长的描述" * 1000, "status": 1}响应状态码为200,返回成功消息 "新增菜品成功"通过

这个表格涵盖了各种测试场景,包括正常情况和异常情况,确保接口的稳定性和可靠性。

接口设计用例

1.基本正向用例(查看接口,证明接口能够跑通)

2.带可选参数的扩展正向用例(必填跑通后试一下可选参数)

3.反向用例(错误的账号密码,有效无效)

4.破坏性的测试(sql注入,数据包大会不会崩溃)

执行用例

postman执行测试

ui自动化测试

登录:

pom代码

from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

class LoginPage:
    def __init__(self, driver: WebDriver):
        self.driver = driver
        self.username_input = (By.CSS_SELECTOR, 'input[placeholder="账号"]')
        self.password_input = (By.CSS_SELECTOR, 'input[placeholder="密码"]')
        self.login_button = (By.XPATH, '//span[text()="登录"]')

    def enter_username(self, username):
        self.driver.find_element(*self.username_input).send_keys(username)

    def enter_password(self, password):
        self.driver.find_element(*self.password_input).send_keys(password)

    def click_login(self):
        self.driver.find_element(*self.login_button).click()
    def wait_for_element_visible(self, by_locator, timeout=10):
        """显式等待,直到元素可见"""
        WebDriverWait(self.driver, timeout).until(
            EC.visibility_of_element_located(by_locator)
        )


    def wait_for_element_clickable(self, by_locator, timeout=10):
        """显式等待,直到元素可点击"""
        WebDriverWait(self.driver, timeout).until(
            EC.element_to_be_clickable(by_locator)
        )

    def implicit_wait(self, timeout=5):
        """隐式等待"""
        self.driver.implicitly_wait(timeout)

    def force_wait(self, seconds):
        """强制等待"""
        time.sleep(seconds)
    #全屏
    def full_screen(self):
        self.driver.maximize_window()

test:
 

from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

class LoginPage:
    def __init__(self, driver: WebDriver):
        self.driver = driver
        self.username_input = (By.CSS_SELECTOR, 'input[placeholder="账号"]')
        self.password_input = (By.CSS_SELECTOR, 'input[placeholder="密码"]')
        self.login_button = (By.XPATH, '//span[text()="登录"]')

    def enter_username(self, username):
        self.driver.find_element(*self.username_input).send_keys(username)

    def enter_password(self, password):
        self.driver.find_element(*self.password_input).send_keys(password)

    def click_login(self):
        self.driver.find_element(*self.login_button).click()
    def wait_for_element_visible(self, by_locator, timeout=10):
        """显式等待,直到元素可见"""
        WebDriverWait(self.driver, timeout).until(
            EC.visibility_of_element_located(by_locator)
        )


    def wait_for_element_clickable(self, by_locator, timeout=10):
        """显式等待,直到元素可点击"""
        WebDriverWait(self.driver, timeout).until(
            EC.element_to_be_clickable(by_locator)
        )

    def implicit_wait(self, timeout=5):
        """隐式等待"""
        self.driver.implicitly_wait(timeout)

    def force_wait(self, seconds):
        """强制等待"""
        time.sleep(seconds)
    #全屏
    def full_screen(self):
        self.driver.maximize_window()
添加早餐分类并将测试环境中的早餐数据删除
pytest
from time import sleep

import pytest
import yaml
from selenium import webdriver
from pythontest.smallmi.pages.login_page2 import LoginPage
from pythontest.smallmi.pages.breakfast_category_page import CategoryPage

@pytest.fixture(scope="module")
def driver():
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    yield driver
    driver.quit()


def test_login(driver):

    with open('E:/breakfast/samllsamllmibase/mi/pythontest/smallmi/data/test_data.yaml',encoding='utf-8') as f:
        data = yaml.safe_load(f)

    login_page = LoginPage(driver)
    category_page = CategoryPage(driver)
    category_page.full_screen()

    driver.get(data['login']['url'])
    login_page.click_login_button()

    assert login_page.assert_login_success()

    category_page.click_category()
    print(driver.current_window_handle)
    category_page.switch_to_iframe()
    print(driver.current_window_handle)
    category_page.click_add_button()
    category_page.enter_category_name(data['category']['name'])
    category_page.enter_sort_order(data['category']['sort_order'])
    category_page.click_confirm()
    # 验证添加是否成功
    assert category_page.is_category_present(data['category']['name'])
    category_page = CategoryPage(driver)
    category_page.full_screen()
    assert category_page.is_category_present(data['category']['name'])
    sleep(5)
    category_name = data['category']['name']
    try:
        # 尝试删除类别
        category_page.delete_category(category_name)
        sleep(5)
        # 验证类别是否仍然存在
        assert not category_page.is_category_present(category_name)
        print(f"Category '{category_name}' successfully deleted.")
    except Exception as e:
        print(f"Failed to delete category '{category_name}': {e}")
        # # 打印页面源代码片段,帮助调试
        # print("Page source snippet after failure:")
        # print(driver.page_source[:1000])
    # 关闭浏览器
    driver.quit()

from time import sleep

from selenium.webdriver.support import expected_conditions as EC
from selenium.common import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


class CategoryPage:
    def __init__(self, driver):
        self.driver = driver

    def click_category(self):
        self.driver.find_element(By.XPATH, '//*[@id="app"]/div/div[1]/div[2]/div[1]/div/ul/div[2]/li/span').click()

    def switch_to_iframe(self):
        try:
            WebDriverWait(self.driver, 30).until(
                EC.frame_to_be_available_and_switch_to_it((By.ID,"cIframe"))
            )
        except TimeoutException:
            print("Timeout while waiting for iframe 'cIframe'.")
            self.driver.save_screenshot('iframe_wait_timeout.png')
            raise
    def click_add_button(self):
        self.driver.find_element(By.XPATH, '//*[@id="category-app"]/div[1]/div[1]/button[1]/span').click()

    def enter_category_name(self, name):
        self.driver.find_element(By.XPATH, "//input[@placeholder='请输入分类名称']").send_keys(name)

    def enter_sort_order(self, order):
        self.driver.find_element(By.XPATH, "//input[@placeholder='请输入排序']").send_keys(order)

    def click_confirm(self):
        self.driver.find_element(By.XPATH, "//span[text()='确 定']").click()

    def is_category_present(self, category_name):
        elements = self.driver.find_elements(By.XPATH, f"//div[text()='{category_name}']")
        print(f"Found {len(elements)} elements with the name '{category_name}'")  # 调试信息
        return len(elements) > 0
    #全屏
    def full_screen(self):
        self.driver.maximize_window()

    def delete_category(self, category_name):
        try:
            # 定位“删除”按钮并点击
            delete_button_xpath = f"//tr[td/div[normalize-space(text())='{category_name}']]//button[span[normalize-space(text())='删除']]"
            delete_button = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable((By.XPATH, delete_button_xpath))
            )
            delete_button.click()
            sleep(3)
            # 等待确认对话框的出现
            confirm_button = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable(
                    (By.XPATH, "/html/body/div[2]/div/div[3]/button[2]/span"))
            )
            confirm_button.click()

            print(f"Successfully deleted category {category_name}.")
        except Exception as e:
            print(f"Failed to delete category {category_name}: {e}")

yaml
 

login:
  url: 'http://localhost:8080/backend/page/login/login.html'

category:
  name: '测试三分类'
  sort_order: '1'
更多关于此项目的ui自动化的代码到我的码云上查看sunrise/basemi (gitee.com)
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值