ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

图书系统软件测试课程设计:等价类到接口UI自动化与报告取证

图书系统软件测试课程设计:等价类到接口UI自动化与报告取证 简介这份《图书系统软件测试》课程设计报告面向软件工程、软件测试相关专业的课程设计与实训任务围绕图书管理系统的测试流程展开可帮助读者理解从需求分析到测试评价的完整写作框架。压缩包内共1个doc文件大小约1.03MB内容涵盖测试需求分析、测试概要、测试计划、测试项目说明、功能结论、测试评价与总结及参考资料并具体设计了系统登录、图书管理、图书查询、系统管理、借书与还书等模块的测试用例。报告涉及黑盒、白盒、集成与系统测试等方法对测试环境准备、覆盖率要求、缺陷与限制、改进建议均有说明适合作为课程设计参考、测试用例模板或实验报告范例。目前已有985人学习下载便于快速搭建报告结构并查漏补缺。1. 图书系统为什么要先定测试策略再写用例课程设计答辩现场最常见的翻车不是代码跑不起来而是老师指着一条用例问“为什么这条是有效等价类”答不上来。图书系统的测试难点不在功能多而在状态耦合一本书从在库到借出再到归还中间还夹着续借、逾期、罚款、库存回滚任何一条用例如果没把前置状态写清楚第二天重跑就是红的。所以软件测试流程里那句“先设计后执行”在这个题目上是真的能省钱——先把测试范围、优先级、用例编号规则定死再往报告里填内容后面写缺陷单和覆盖率才有挂靠的地方。这篇内容按“需求拆解 → 接口自动化 → UI 主流程 → 缺陷与报告取证”的顺序展开适合正在做软件测试课程设计、需要交一份图书系统软件测试报告的同学也适合刚入行、想拿一个完整软件测试项目实战练手的人。面试八股里反复问的等价类、边界值、判定表在课程设计里不是背概念是必须落到用例表里的东西。2. 图书系统测试需求拆解等价类、边界值与判定表怎么落到用例2.1 先画模块状态表别急着写测试用例拿到一份图书系统的需求说明第一件事不是打开 Excel 写用例而是把模块和状态列出来。图书系统的测试对象天然分成四块图书信息、读者账户、借阅事务、罚款结算。每一块都有自己的状态集合而缺陷往往出在状态非法流转上比如“已下架的书还能不能被借”“挂失状态的读者能不能续借”。模块核心状态测试关注点图书管理在库 / 借出 / 下架 / 遗失状态流转合法性、库存扣减与回滚读者管理正常 / 挂失 / 冻结 / 注销异常状态下能否发起借阅、续借借阅事务待借出 / 已借出 / 已归还 / 逾期借阅上限、借期、续借次数罚款结算未缴 / 已缴 / 减免逾期天数与金额的进位规则这张表的作用是给后面的用例定“前置条件”字段。每条用例只要写“前置读者正常、库存1、已借 4 本”执行顺序就固化了。我一般会把状态表直接放进课程设计报告的第三章评审看的就是你有没有把被测对象想清楚而不是用例条数有多少。2.2 借阅上限的等价类与边界值用代码批量生成数据借阅上限是最典型的边界值场景。假设规则是“每位读者最多同时借 5 本借期 30 天可续借 1 次”那么有效等价类是借阅数小于上限无效等价类是已达到上限。边界值要取 4、5、6 三个点还要叠加“库存刚好剩 1 本”和“库存为 0”两个维度。def borrow_limit_cases(max_books5): 依据借阅上限生成边界值测试数据直接喂给参数化用例 cases [] for borrowed in (max_books - 1, max_books, max_books 1): for stock in (1, 0): cases.append({ borrowed: borrowed, stock: stock, # 预期未达上限且有库存才允许借出 expect_ok: borrowed max_books and stock 0 }) return cases for c in borrow_limit_cases(): print(c)这段代码生成 6 组数据覆盖“边界内 有库存”“边界上 无库存”等组合。参数说明max_books从需求文档读不要写死在用例里规则一改只改这个常量expect_ok是预期结果执行阶段用它做断言基准。注意不要把边界值只取上限本身下界借 0 本和上界加一都必须在表里出现这是软件测试面试题里最爱抠的点。2.3 判定表处理“读者状态 借阅数 库存”的组合三个条件两两组合就有 8 条规则用判定表能一次性把逻辑漏洞摊开。图书系统里更隐蔽的是“读者冻结但库存充足”这种组合接口往往返回 200 却借出去了。条件 / 规则12345678读者状态正常YYYYNNNN借阅数未达上限YYNNYYNN库存大于 0YNYNYNYN动作为允许借出√动作为拒绝并提示√√√√√√√规则 1 是唯一有效路径其余全部应为拒绝。把这张表的规则编号写进用例编号比如TC-BORROW-01对应规则 1评审时一查就通。判定表的价值在于它逼你把“提示文案”也写成断言很多同学只验状态码不验提示答辩时被追问一句“用户怎么知道被拒了”就哑了。2.4 需求-用例-缺陷的可追溯矩阵课程设计报告里加一张可追溯矩阵比多写二十条用例更能体现工程素养。矩阵三列需求编号、用例编号、执行结果与缺陷编号。用 Excel 做的话缺陷编号这一列直接跟缺陷管理表做 VLOOKUP改一处全表联动。# 用 pandas 生成可追溯矩阵骨架导出到报告附录 import pandas as pd matrix pd.DataFrame([ {req_id: REQ-BORROW-01, case_id: TC-BORROW-01, defect_id: }, {req_id: REQ-BORROW-02, case_id: TC-BORROW-02, defect_id: BUG-007}, {req_id: REQ-FINE-01, case_id: TC-FINE-01, defect_id: }, ]) matrix.to_excel(trace_matrix.xlsx, indexFalse)逻辑说明defect_id留空说明该需求对应用例通过有值说明发现缺陷并已记录。参数上建议case_id与自动化脚本里的pytest.mark.parametrize的 id 保持一致这样报告、脚本、缺陷单三者能对上号。3. 图书系统接口测试用 pytest requests 搭一套能跑的证据链3.1 接口分层登录、查询、借阅、归还该测哪几类断言接口测试不是把每个 URL 都打一遍就完事。图书系统按风险分层登录鉴权是入口错了后面全废查询接口重点是分页与模糊匹配的边界借阅和归还是写操作要同时验响应体、数据库状态和库存一致性。分层之后断言也分层鉴权层断言 token 有效性和过期行为查询层断言数据集与总数写操作层断言数据库最终状态。3.2 session 级 fixture 复用 token避免每条用例都登录# conftest.py import pytest import requests BASE_URL http://127.0.0.1:8000/api pytest.fixture(scopesession) def token(): resp requests.post( f{BASE_URL}/login, json{username: reader01, password: Test123}, timeout5, ) assert resp.status_code 200, resp.text return resp.json()[data][token] pytest.fixture def client(token): session requests.Session() session.headers.update({Authorization: fBearer {token}}) yield session session.close()逻辑说明token用scopesession只登录一次避免几百条用例把登录接口打爆也避免因登录频繁触发风控。client用函数级作用域每条用例拿到独立的Session防止 cookie 或连接状态串味。参数timeout5必须加否则接口挂起时整个用例集卡死这一点在 CI 上尤其明显。3.3 借书接口参数化把用例表直接变成代码import pytest CASES [ # (book_id, borrowed, stock, expect_code, desc) (1001, 0, 1, 200, 正常借阅), (1002, 5, 1, 409, 已达借阅上限), (1003, 0, 0, 409, 库存不足), (1004, 0, 1, 403, 读者状态冻结), ] pytest.mark.parametrize(book_id, borrowed, stock, expect_code, desc, CASES, ids[c[4] for c in CASES]) def test_borrow(client, book_id, borrowed, stock, expect_code, desc): resp client.post(f{BASE_URL}/borrow, json{book_id: book_id}) assert resp.status_code expect_code, f{desc} 返回异常: {resp.text}逻辑说明ids直接取中文描述拼接pytest 报告里失败项一眼能看懂是哪条业务规则挂了。expect_code要跟后端约定好别把 400 和 409 混用否则断言写不准。前置数据borrowed、stock建议用 fixture 在数据库里造不要依赖上一个用例的执行结果用例之间必须互相独立。3.4 用 SQL 断言库存一致性别只看响应码-- 借阅成功后库存应减 1且流水表新增一条记录 SELECT b.stock, (SELECT COUNT(*) FROM borrow_record r WHERE r.book_id :book_id AND r.status BORROWED) AS open_records FROM book b WHERE b.id :book_id;接口返回 200 只代表请求被接受不代表数据写对了。执行借阅用例后紧接着查这条 SQL断言stock等于借前减一、open_records增加一条。常见坑是并发借同一本书时超卖这条 SQL 也能验出来。注意查询语句别用SELECT *字段写死报告截图时更干净。3.5 执行命令与 HTML 报告的产出# 只跑接口层生成单文件 HTML 报告失败重跑 1 次 pytest tests/api -v \ --htmlreport/api_report.html --self-contained-html \ --reruns 1 -p no:cacheprovider参数说明-v输出每条用例名称报告里能直接看出哪些业务规则失败--self-contained-html把 CSS 内联进 HTML拷给老师或同事不会丢样式--reruns 1用来隔离偶发失败但如果同一条用例重跑才过要在缺陷单里标记为 flaky不能直接忽略。4. 借阅全流程的 UI 自动化Selenium 页面对象与数据驱动4.1 为什么 UI 只覆盖三条主流程接口层已经把业务规则覆盖掉了UI 层的职责是验证“页面能不能把正确结果展示出来、操作路径通不通”。所以 UI 用例不必铺满抓住三条主线登录 → 查书 → 借书、登录 → 我的借阅 → 归还、登录 → 逾期记录 → 查看罚款。这三条跑通页面的核心交互就验证完了。把 UI 用例数量压到 10 条以内执行时间才可控这也是软件测试项目实战里最常被忽略的成本意识。4.2 页面对象模型拆到方法级from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class LoginPage: USER (By.ID, username) PWD (By.ID, password) SUBMIT (By.CSS_SELECTOR, button[typesubmit]) def __init__(self, driver, timeout10): self.driver driver self.wait WebDriverWait(driver, timeout) def login(self, user, pwd): self.wait.until(EC.visibility_of_element_located(self.USER)).send_keys(user) self.driver.find_element(*self.PWD).send_keys(pwd) self.driver.find_element(*self.SUBMIT).click() return self逻辑说明定位符常量化页面改版只改类属性WebDriverWait统一在构造函数注入超时时间避免每个方法各写一套隐式等待。注意send_keys前必须等元素可见图书系统的登录框常被弹窗遮挡直接点会报ElementClickInterceptedException。4.3 显式等待与借阅流程串联class BorrowPage: SEARCH (By.NAME, keyword) FIRST_BORROW_BTN (By.CSS_SELECTOR, tr:first-child .borrow-btn) TOAST (By.CSS_SELECTOR, .el-message--success) def __init__(self, driver, timeout10): self.driver driver self.wait WebDriverWait(driver, timeout) def borrow(self, keyword): box self.wait.until(EC.visibility_of_element_located(self.SEARCH)) box.clear() box.send_keys(keyword) self.wait.until(EC.element_to_be_clickable(self.FIRST_BORROW_BTN)).click() return self.wait.until(EC.visibility_of_element_located(self.TOAST)).text逻辑说明element_to_be_clickable比presence_of_element_located更稳因为它同时校验可见和可点击。返回提示文案用于断言别返回布尔值。参数timeout10是经验值前端首屏加载慢的图书系统可以调到 20但不要用time.sleep硬等。4.4 数据驱动用例表读进 pytestimport csv import pytest def load_cases(pathdata/borrow_cases.csv): with open(path, newline, encodingutf-8) as f: return [row for row in csv.DictReader(f)] pytest.mark.parametrize(case, load_cases(), idslambda c: c[case_id]) def test_borrow_flow(driver, case): LoginPage(driver).login(case[user], case[pwd]) msg BorrowPage(driver).borrow(case[keyword]) assert case[expect_msg] in msgCSV 表头建议包含case_id, user, pwd, keyword, expect_msg跟第 2 章的用例编号对齐。这样改数据不用动代码课程设计报告里的用例表可以直接导出成 CSV 复用省一遍誊抄。4.5 失败截图和 flaky 用例的隔离import pytest pytest.hookimpl(tryfirstTrue, hookwrapperTrue) def pytest_runtest_makereport(item, call): outcome yield report outcome.get_result() if report.when call and report.failed: driver item.funcargs.get(driver) if driver: driver.save_screenshot(freport/{item.name}.png)逻辑说明钩子挂在call阶段只对执行过程中的失败截图setup 阶段报错不截。item.funcargs里取 driver键名跟 fixture 名字一致。截出来的图片按用例名命名直接贴进缺陷单比文字描述“点击后无响应”有说服力得多。flaky 用例要单独打pytest.mark.flaky并从主回归集里挪出去不然一次全量执行总结里全是红灯看不出真实通过率。5. 缺陷单、覆盖率与课程设计报告的取证技巧5.1 一条能复现的缺陷单长什么样字段示例缺陷编号BUG-007关联用例TC-BORROW-05前置条件reader01 已借 4 本图书 1003 库存为 0复现步骤1. 登录 2. 搜索“数据结构” 3. 点击借阅实际结果提示“借阅成功”库存变为 -1预期结果拒绝借阅并提示“库存不足”附件borrow_fail.png、接口响应 JSON复现步骤写三到五步每步一个动作。实际结果里必须带可观测数据比如“库存变为 -1”而不是“借阅出错”。这条缺陷的严重级别要看是否影响库存超卖属于严重提示文案不友好属于轻微分级依据写进报告的缺陷统计表。5.2 用 pytest-cov 统计接口用例打到多少代码pytest tests/api \ --covapp.api \ --cov-reportterm-missing \ --cov-reporthtml:report/coverage参数说明--covapp.api只统计接口层包避免把 ORM 和配置文件算进来稀释数字term-missing在终端列出未覆盖的行号HTML 报告用于截图进课程设计。课程设计里不必追求 90%但要能解释缺口未覆盖的行是异常分支还是防御性代码说清楚比数字高低更加分。5.3 报告附录里最抗问的三类证据第一类是执行记录带时间戳的 HTML 报告和失败截图证明用例真的跑过第二类是可追溯矩阵需求、用例、缺陷三列对齐证明覆盖是有设计而不是凑数第三类是缺陷闭环每条缺陷从发现到复测通过有两次执行记录证明测试流程走完整了。把这三类证据按执行时间顺序装订在附录里翻到任意一页都能和正文的用例编号对上问“这条用例当时什么结果”时可以直接指出对应截图。本文还有配套的精品资源点击获取
返回列表