多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

从零构建ECShop测试体系:环境部署、接口用例设计与Python自动化实战

从零构建ECShop测试体系:环境部署、接口用例设计与Python自动化实战 1. 项目概述从零构建一个完整的ECShop测试体系最近在带新人做软件测试的实战项目选了个老牌但依然有生命力的靶子——ECShop电子商务系统。这个项目标题“ECShop电子商务系统__软件测试作业”背后其实是一个相当经典的测试工程师能力闭环从环境搭建、文档梳理到用例设计、脚本实现。它考察的绝不仅仅是点点页面而是对一个软件系统进行系统性质量保障的完整流程。无论是学生做课程设计还是初级测试工程师想夯实基础把这个流程走通一遍价值远超单独学习某个测试工具。简单来说这个“作业”要求你完成四件核心事第一把ECShop这个系统在自己本地或测试服务器上成功跑起来这是所有测试活动的基石第二针对其提供的API接口设计出结构清晰、覆盖全面的测试用例第三整理或理解系统的接口文档这是你设计用例和编写脚本的“地图”第四将设计好的用例转化为可执行的自动化测试脚本实现效率提升。整个过程你会涉及到环境配置、需求理解、用例设计、自动化编程、缺陷分析等多个测试核心技能点。接下来我就以一个老测试的身份带你一步步拆解这个项目分享其中容易踩坑的细节和提升效率的技巧。2. 环境搭建与系统部署打造稳定的测试基石测试工作的第一步永远是准备一个独立、干净、可控的测试环境。对于ECShop这类基于LAMPLinuxApacheMySQLPHP的传统电商系统环境搭建是第一个小考。2.1 基础运行环境准备我强烈建议使用集成环境包来快速搭建这能避免在PHP版本、扩展模块、数据库配置上耗费过多时间。对于Windows用户XAMPP或PHPStudy是首选macOS用户可以用MAMP追求原生或使用Linux的可以直接安装Apache、MySQL和PHP。这里以PHPStudy为例因为它对国内用户更友好切换PHP版本非常方便。首先去官网下载最新版的PHPStudy并安装。安装完成后启动软件你会看到它集成了Apache和MySQL服务。点击“启动”按钮确保两者状态都变为绿色“运行中”。接着你需要关注PHP版本。ECShop的不同版本对PHP有要求比如ECShop v2.7.3兼容PHP 5.3-5.6而一些修改版可能支持PHP 7.x。在PHPStudy的“软件管理”或“版本”选项中选择安装一个合适的PHP版本例如PHP 5.6并确保必要的扩展被启用尤其是mysql或mysqli用于数据库连接、gd用于图像处理如验证码、curl可能用于支付接口等。注意很多新手在这里会忽略扩展配置导致安装ECShop时出现“无法连接数据库”或“gd库不支持”的错误。在PHPStudy中切换到对应PHP版本设置在“扩展”列表里勾选php_mysqli和php_gd2然后重启服务。数据库方面PHPStudy自带的MySQL通常版本够用。你需要记住默认的root密码初始可能为空或root并登录phpMyAdmin通常访问http://localhost/phpmyadmin创建一个新的数据库比如命名为ecshop_test字符集选择utf8mb4排序规则选utf8mb4_general_ci以更好地支持中文和Emoji。2.2 ECShop源码获取与部署接下来是获取ECShop源码。你可以从其官方或开源社区下载。将下载的压缩包解压你会得到一个包含许多文件和文件夹的目录如includes、themes、admin等。将这个目录下的所有文件复制到PHPStudy的网站根目录下。这个根目录通常是PHPStudy安装目录/PHPTutorial/WWW/。你可以选择直接粘贴或者为了更好地管理在WWW下新建一个文件夹如ecshop再把源码放进去。这样你后续访问系统的地址就是http://localhost/ecshop。复制完成后在浏览器中访问这个地址。如果环境配置正确你应该会看到ECShop的安装向导界面。安装过程一般是图形化的第一步是检查环境确保目录权限、PHP扩展都符合要求第二步是配置数据库填写你刚才创建的数据库名ecshop_test、用户名root、密码、数据库主机通常是localhost以及表前缀默认ecs_即可第三步是设置管理员账号和网站基本信息。点击“立即安装”等待进度条完成。安装成功后务必按照提示删除或重命名安装目录通常是根目录下的install文件夹。这是一个重要的安全步骤防止他人重新安装覆盖你的测试数据。完成这些你的ECShop测试环境就基本就绪了。在开始测试前我习惯先以管理员身份登录后台http://localhost/ecshop/admin熟悉一下商品管理、订单处理、会员中心等基本功能这有助于后续理解业务逻辑和接口设计。3. 接口文档分析与测试用例设计系统跑起来了接下来就要搞清楚“测什么”。对于接口测试接口文档就是我们的作战地图。ECShop可能不提供非常规范的Swagger文档但我们可以通过分析源码、抓包和查看其自带的API文件来梳理。3.1 梳理核心接口与业务流一个典型的电商系统其接口通常围绕几个核心模块展开。我们可以通过浏览ECShop的前端页面和后台功能配合浏览器开发者工具的“网络Network”面板进行抓包来识别主要的API接口。用户模块这是最基础的。包括用户注册、登录、退出、获取用户信息、修改密码等接口。例如登录操作可能会请求一个类似/user.php?actlogin的地址方法为POST携带用户名和密码参数。商品模块涉及商品列表获取、商品详情查询、商品搜索、分类浏览等。例如首页商品列表可能通过/goods.php?actindex获取商品详情则是/goods.php?idxxx。购物车与订单模块这是电商的核心。包括添加商品到购物车、查看购物车、更新购物车商品数量、删除购物车商品、生成订单、订单列表查询、订单详情查询等。添加购物车接口可能需要商品ID、数量等参数。支付与配送模块虽然ECShop内置的支付接口如支付宝、微信支付在测试环境可能无法真实调用但其回调接口和状态更新接口是需要关注的。此外获取配送方式列表、计算运费等接口也属于此列。通过抓包你可以记录下每个请求的URL、HTTP方法GET/POST、请求参数包括Headers和Body、以及响应数据的格式通常是JSON或HTML片段。将这些信息整理成表格这就是最原始的“接口文档”。同时查看ECShop源码中api、includes等目录下的.php文件也能发现一些接口定义的线索。3.2 设计结构化测试用例有了接口地图就可以开始设计测试用例了。设计用例不是简单地罗列接口而是要运用测试方法论确保覆盖全面。这里推荐使用“测试用例八大要素”作为模板框架用例编号、测试模块、用例标题、前置条件、测试步骤、测试数据、预期结果、实际结果执行时填写。我们可以利用AI工具辅助生成基础用例但必须人工进行业务逻辑校验和补充。以“用户登录”这个接口为例我们来设计一组测试用例用例编号测试模块用例标题前置条件测试步骤测试数据用户名/密码预期结果TC-USER-LOGIN-001用户模块使用正确的用户名和密码登录1. 用户“test_user”已注册且未锁定。2. 系统运行正常。1. 调用登录接口。2. 传入正确的用户名和密码。test_user / 1234561. HTTP状态码为200。2. 响应中包含登录成功的标识如”success”: true。3. 返回的JSON中包含用户基本信息如user_id, username。4. 服务器Session或Token被正确设置。TC-USER-LOGIN-002用户模块使用错误的密码登录用户“test_user”已注册。1. 调用登录接口。2. 传入正确的用户名和错误的密码。test_user / wrong_pwd1. HTTP状态码为200或401。2. 响应中包含登录失败的标识和错误信息如”success”: false, “msg”: “密码错误”。TC-USER-LOGIN-003用户模块使用不存在的用户名登录无1. 调用登录接口。2. 传入数据库中不存在的用户名。not_exist_user / any_pwd1. HTTP状态码为200或404。2. 响应提示用户不存在。TC-USER-LOGIN-004用户模块用户名为空时尝试登录无1. 调用登录接口。2. 密码字段填写有效值用户名字段留空或传空字符串。(空) / 1234561. 接口应能处理返回明确的参数错误提示。TC-USER-LOGIN-005用户模块密码为空时尝试登录用户“test_user”已注册。1. 调用登录接口。2. 用户名字段填写有效值密码字段留空。test_user / (空)1. 接口应能处理返回明确的参数错误提示。TC-USER-LOGIN-006用户模块使用已锁定/禁用账号登录用户“locked_user”状态为已锁定。1. 调用登录接口。2. 传入该用户的正确凭证。locked_user / its_pwd1. 登录失败并返回账号已被锁定的提示信息。设计用例时要综合运用等价类划分和边界值分析。比如对于“商品数量”这个参数有效等价类是大于0的整数无效等价类包括0、负数、小数、非数字字符、超大数可能触发库存或数据类型溢出。边界值则可以测1最小有效值、库存最大值、库存最大值1等。实操心得不要只设计“正向用例”。一个健壮的测试集异常用例和边界用例往往能发现更多潜在缺陷。例如在测试“添加购物车”时除了添加正常库存内的商品一定要测试添加数量为0、为负、超过库存、商品ID不存在等情况。这些场景在用户误操作或恶意请求时很可能发生。4. 接口测试脚本开发与自动化设计好用例后手动执行一遍可以熟悉流程但要想高效回归测试就必须将其自动化。这里我们选择最主流和易上手的组合Postman用于接口调试和集合管理和基于Python Requests的脚本用于持续集成和复杂逻辑。4.1 使用Postman构建可复用的测试集合Postman是一个强大的API调试工具它的“集合Collection”和“环境变量Environment”功能非常适合管理我们的测试用例。首先为ECShop测试项目创建一个新的Collection命名为“ECShop_API_Test”。然后根据之前梳理的模块在集合内创建文件夹Folder如“用户模块”、“商品模块”、“购物车订单模块”。接下来开始添加具体的请求。以“用户登录”为例新建一个请求命名为“TC-USER-LOGIN-001 正常登录”。选择请求方法为POST。输入请求URL。这里我们可以使用环境变量来管理基础URL。先创建一个环境比如叫“ECShop_Local”添加一个变量base_url值为http://localhost/ecshop。在请求URL中填写{{base_url}}/user.php?actlogin。在Body标签页选择x-www-form-urlencoded添加参数username和password并填入正确的测试账号。在Tests标签页编写JavaScript代码来断言响应。例如// 检查状态码为200 pm.test(Status code is 200, function () { pm.response.to.have.status(200); }); // 解析响应JSON检查success字段为true pm.test(Login successful, function () { var jsonData pm.response.json(); pm.expect(jsonData.success).to.be.true; }); // 将返回的session_id或token保存为环境变量供后续请求使用 var jsonData pm.response.json(); if (jsonData jsonData.data jsonData.data.session_id) { pm.environment.set(session_id, jsonData.data.session_id); }点击“Send”发送请求你可以在下方看到响应结果和测试结果。按照这个模式将设计的所有测试用例都在Postman中实现。你可以利用Postman的“Runner”功能批量运行整个集合或某个文件夹下的所有请求并生成漂亮的测试报告。4.2 编写Python自动化测试脚本虽然Postman很棒但对于需要集成到CI/CD流水线、或者处理复杂数据驱动和业务链路的场景用Python编写脚本更灵活。我们使用requests库发送HTTP请求用pytest作为测试框架来组织和运行用例。首先安装必要的库pip install requests pytest。然后规划你的项目目录结构ecshop_api_test/ ├── conftest.py # pytest配置如定义fixture ├── test_data/ # 存放测试数据文件如JSON, YAML ├── utils/ # 工具类如读取配置、封装HTTP请求 │ └── http_client.py ├── test_user.py # 用户模块测试用例 ├── test_goods.py # 商品模块测试用例 └── config.ini # 配置文件基础URL、数据库连接等在utils/http_client.py中封装一个通用的请求类import requests from configparser import ConfigParser class ApiClient: def __init__(self, base_urlNone): config ConfigParser() config.read(config.ini) self.base_url base_url or config.get(environment, base_url) self.session requests.Session() # 可以在这里添加默认headers如User-Agent self.session.headers.update({User-Agent: ECShop-AutoTest/1.0}) def post(self, endpoint, dataNone, jsonNone, **kwargs): url f{self.base_url}{endpoint} response self.session.post(url, datadata, jsonjson, **kwargs) return response def get(self, endpoint, paramsNone, **kwargs): url f{self.base_url}{endpoint} response self.session.get(url, paramsparams, **kwargs) return response # 类似地封装put, delete等方法在conftest.py中定义一个pytest fixture为每个测试用例提供初始化好的客户端并处理登录态import pytest from utils.http_client import ApiClient pytest.fixture(scopemodule) def api_client(): client ApiClient() # 模块级别的登录所有该模块内的测试共用登录态 login_data {username: test_user, password: 123456, act: login} resp client.post(/user.php, datalogin_data) assert resp.status_code 200 # 假设登录后需要设置一个cookie或token # 这里简化处理实际应根据接口返回设置client.session的cookies或headers yield client # 测试结束后可以执行清理操作如退出登录 # client.post(/user.php?actlogout)最后编写具体的测试用例文件test_user.pyimport pytest class TestUserLogin: 测试用户登录接口 def test_login_success(self, api_client): 测试正常登录 data {username: test_user, password: 123456, act: login} response api_client.post(/user.php, datadata) assert response.status_code 200 resp_json response.json() assert resp_json[success] is True assert user_id in resp_json.get(data, {}) def test_login_with_wrong_password(self, api_client): 测试密码错误 data {username: test_user, password: wrong, act: login} response api_client.post(/user.php, datadata) assert response.status_code 200 # 业务接口通常返回200错误信息在body里 resp_json response.json() assert resp_json[success] is False assert 密码错误 in resp_json.get(msg, ) pytest.mark.parametrize(username, password, [ (, 123456), (test_user, ), (None, 123456), ]) def test_login_with_invalid_params(self, api_client, username, password): 测试参数异常-使用参数化 data {username: username, password: password, act: login} # 过滤掉None值因为requests不会发送None的键 data {k: v for k, v in data.items() if v is not None} response api_client.post(/user.php, datadata) # 这里不断言具体状态码因为不同系统处理方式不同但应该能妥善处理而不崩溃 assert response.status_code in [200, 400, 422] # 可以进一步断言响应中包含错误提示运行测试只需在命令行执行pytest -v。pytest会自动发现并运行所有以test_开头的文件和函数并输出详细的报告。对于购物车、订单等有前后依赖的流程你可以在fixture中编排好“注册用户 - 登录 - 添加商品 - 生成订单”的步骤确保每个测试用例都有干净的上下文。5. 测试执行、问题定位与报告生成脚本写好了真正的挑战在于执行过程中问题的定位和解决。自动化测试不是一劳永逸的它需要维护并能清晰地告诉你“哪里出了问题”。5.1 执行策略与结果分析对于ECShop这样的系统我建议建立分层的测试执行策略冒烟测试Smoke Test每天或每次构建后运行最核心的流程如首页访问、用户登录、浏览商品。这能快速验证系统基本功能是否可用。你可以用Postman的Monitor功能定时运行或者用Jenkins触发pytest执行一个标记为smoke的测试集。回归测试Regression Test在开发完成一个功能模块或修复一批Bug后执行全量的接口测试用例确保新代码没有破坏原有功能。这应该是自动化脚本的主力战场。集成流程测试手动或通过更复杂的脚本测试跨模块的完整业务流程例如“用户注册 - 搜索商品 - 加入购物车 - 修改数量 - 下单 - 支付回调 - 查看订单状态”。这能发现模块间接口协作的问题。当测试失败时不要只看断言失败的那一行。首先检查响应状态码。如果是5xx如500很可能是服务器内部错误需要查看服务端日志。如果是4xx如404、400检查请求的URL和参数是否正确。如果是200但业务逻辑失败success: false则需分析返回的错误信息。其次打印详细的请求和响应信息。在pytest中你可以使用-s参数禁止捕获输出或者在测试函数中直接打印response.url,response.request.body,response.text。在Postman的Tests标签里也可以用console.log()输出调试信息。5.2 常见问题排查与修复根据经验ECShop接口测试中常见的问题有Session/Cookie问题后续接口需要携带登录态。确保你的HTTP客户端如requests.Session()自动管理cookies或者在每个请求的header中手动添加从登录响应中获取的token或session_id。参数格式或编码问题特别是包含中文或特殊字符的参数。确保发送时使用正确的编码通常是UTF-8。在Python中requests库默认会处理在Postman中检查Body的编码格式。依赖数据问题测试“删除商品”接口但商品ID可能不存在或已被删除。这就需要你在测试前置条件setup中通过调用其他接口如“添加商品”来创建测试所需的数据并在测试后teardown进行清理。这就是测试数据管理。接口响应结构变化开发修改了API返回的JSON结构导致你的断言失败。这时需要更新测试脚本中的解析逻辑。为了增强脚本的健壮性在断言时不要过于严格地检查所有字段可以只检查关键字段如success或者使用resp_json.get(‘data’, {})这样的方式避免KeyError。注意事项永远不要在生产环境运行自动化测试脚本。你的脚本可能会创建大量测试数据、发送大量请求对生产服务器造成压力甚至破坏真实数据。确保你的base_url指向的是专门的测试环境或本地开发环境。5.3 生成有价值的测试报告清晰的测试报告是测试工作的最终产出物。pytest原生支持多种报告格式使用pytest —htmlreport.html可以生成一个美观的HTML报告里面包含了用例执行结果、失败原因、甚至截图需要配合pytest-html插件和额外的配置。对于团队协作可以将测试报告集成到持续集成工具如Jenkins、GitLab CI中。每次代码提交触发自动化测试测试报告会自动生成并发布到内部网站或通过邮件、钉钉/企业微信机器人通知给相关开发人员和测试人员。报告的核心价值在于快速定位失败用例、直观展示测试通过率、以及通过历史趋势图反映系统质量的波动。最后别忘了维护你的测试资产。随着ECShop系统的迭代如果这是一个持续的项目接口可能会增减或变更。你需要定期回顾和更新你的接口文档、测试用例和自动化脚本让它们与系统保持同步。一个好的做法是将测试代码也纳入版本控制如Git并为每次重要的测试集变更编写清晰的提交说明。这样整个“ECShop软件测试作业”就从一个静态的任务变成了一个可维护、可演进、真正能为软件质量保驾护航的活资产。这个过程积累的经验无论是环境部署中的排错、用例设计中的思维还是脚本编写中的技巧都将是你测试职业生涯中非常扎实的基础。
返回列表