自动化测试面试翻车复盘:我才明白,找到 Bug 只是开始

发布时间:2026/7/5 13:28:07
自动化测试面试翻车复盘:我才明白,找到 Bug 只是开始 一次自动化测试面试题复盘从手工发现 Bug 到自动化交付闭环这次面试给我的提醒很直接自动化测试工程师面试里的“找 Bug”并不只是把问题点出来更重要的是把问题沉淀成可重复执行、可生成结果、可被别人接手运行的自动化用例。面试题本身是一个 Web 登录/注册表单测试任务。面试官提供了一个公共网站作为测试入口也给了一些表单规则限制要求我在限定时间内测试页面里的缺陷。我后来在本地用selenium_demo复刻了这个场景当前项目使用 Selenium Pytest Page Object Model 访问 SauceDemo 登录页https://www.saucedemo.com/并已经完成了登录成功跳转的自动化用例。这篇复盘不是为了证明当时哪里做错了而是把这次暴露出来的问题整理成经验下次遇到类似自动化测试题时应该怎么从测试分析、用例设计、脚本补充、批处理运行和结果交付几个环节完整闭环。一、当时题目的核心要求从自动化测试工程师的角度看这类面试题通常不只考察 Selenium 会不会写而是同时考察几个能力是否能读懂页面规则和业务限制。是否能设计正常流、异常流、边界值和重复操作场景。是否能把发现的问题转成自动化测试用例。是否能接入原有测试工程而不是单独写一段临时代码。是否能通过脚本一键执行并生成可查看的测试结果。我当时只找出了一个问题注册过的账号仍然可以再次注册。这个 Bug 本身是有效的但我的处理停在了“发现 Bug”这一步没有继续把它写进原来的自动化测试脚本里也没有通过打包好的run_test.bat执行并产出结果。这就是这次最大的失分点测试发现没有自动化沉淀自动化脚本没有形成交付闭环。二、当前复刻项目的结构我在selenium_demo中复刻了一个 Selenium 自动化测试项目访问的地址是https://www.saucedemo.com/结构如下selenium_demo/ config/ config.ini data/ data/ test_patients.csv locators/ saucedemo_login.yaml pages/ saucedemo_login_page.py tests/ test_saucedemo_login.py utils/ base/ base_page.py element.py locator_manager.py wait.py tool/ driver_manager.py logger_manager.py path_manager.py cookie_manager.py csv_manager.py randomVal_manager.py项目采用 Page Object 分层pytest 测试用例 - pages 页面对象 - utils/base 基础页面与元素操作 - Selenium WebDriver这个结构的优点是比较清晰定位器放在data/locators/*.yaml页面行为放在pages/测试断言放在tests/。这也是面试中最应该利用起来的地方。当前项目已经实现的用例是 SauceDemo 登录成功pytest.mark.parametrize(username,password,[(standard_user,secret_sauce),],)deftest_login_success_redirects_to_inventory(driver,username,password):expected_urlhttps://www.saucedemo.com/inventory.htmllogin_pageSauceDemoLoginPage(driver)login_page.open()login_page.login(username,password)WebDriverWait(driver,10).until(EC.url_to_be(expected_url))assertlogin_page.get_current_url()expected_url这个用例只覆盖了“正确账号 正确密码”的主流程还没有覆盖登录表单的异常输入、边界值、错误提示和重复提交等场景。三、问题一发现 Bug 后没有写进自动化用例面试时我发现“已注册账号可以再次注册”这个问题后正确做法应该是把它变成一个自动化测试用例。如果原项目中已经有test_ui或类似 UI 测试入口我应该直接在里面新增用例而不是只口头说明问题。一个合格的自动化用例至少要包含前置条件准备一个已经注册过的账号。操作步骤打开注册页输入相同账号信息再次提交。预期结果系统阻止重复注册并提示账号已存在。实际结果如果系统仍然注册成功则断言失败暴露 Bug。伪代码可以这样表达deftest_registered_user_cannot_register_again(driver):register_pageRegisterPage(driver)register_page.open()register_page.register(usernameexisting_user,passwordValidPass123,confirm_passwordValidPass123)assertregister_page.get_error_message()账号已存在这个用例的重点不是代码本身而是思路Bug 必须被脚本捕获。自动化测试工程师不能只停留在“我看到了 Bug”还要进一步证明“这个 Bug 可以被稳定复现并且以后能被持续检测”。四、问题二没有检查和更新 run_test.bat面试题里如果已经给了run_test.bat它通常就是交付入口。面试官可能并不会逐行看我写了什么而是直接运行这个脚本看测试是否能跑起来、报告是否能生成、失败是否能定位。所以我当时应该做三件事检查run_test.bat是否调用了正确的测试目录或测试文件。确认新增用例会被 pytest 收集到。运行脚本查看控制台结果、日志、截图或测试报告。一个基础的run_test.bat可以这样写echo off cd /d %~dp0 py -m pytest tests\test_saucedemo_login.py -q pause这里的关键点是cd /d %~dp0。它表示切换到 bat 文件所在目录即使脚本从别的路径被双击执行也能保证相对路径正确。对 Windows 环境下的测试交付来说这是一个很实用的小细节。五、问题三对 .bat 打包和交付不熟我之前项目里没有系统做过.bat打包所以面试时对这个环节不够敏感。复盘后我觉得至少应该掌握以下几类脚本能力。1. 切换到项目目录cd /d %~dp0这可以避免因为当前终端路径不对导致找不到tests、data或配置文件。2. 检查 Python 环境py --version py -m pip --version如果面试电脑环境不确定先确认 Python 和 pip 是否可用。3. 安装或检查依赖py -m pip install -r requirements.txt如果项目没有requirements.txt至少要知道当前项目依赖pytest、selenium、pyyaml、requests这类包。4. 执行测试并保留结果py -m pytest tests -q --junitxmlreports\pytest_result.xml自动化脚本的价值不只是跑完还要能留下结果方便面试官或团队成员查看。5. 保留控制台窗口pause对于双击执行的 bat 文件pause可以避免窗口一闪而过方便查看失败原因。六、登录表单边界值设计不够完善这次我对登录/注册表单边界值考虑得不够完整。以后遇到类似题目不需要一开始铺得很大可以先抓住最容易暴露问题的几类场景类型重点场景预期必填校验用户名为空、密码为空、两者都为空给出明确必填提示正误组合正确账号正确密码、正确账号错误密码、错误账号正确密码成功登录或提示账号密码错误边界长度低于最小长度、等于边界、超过最大长度按规则允许或拦截格式限制空格、特殊字符、中文、大小写差异按表单规则处理业务规则已注册账号重复注册、锁定账号登录、重复点击提交阻止非法操作并提示原因这样整理会更适合面试现场先保证主流程和高风险异常流再根据时间补充更细的等价类和边界值。对于 SauceDemo 这个站点还可以补充这些典型账号账号密码预期standard_usersecret_sauce登录成功locked_out_usersecret_sauce登录失败并提示账号锁定problem_usersecret_sauce登录成功但后续页面可能存在异常performance_glitch_usersecret_sauce登录成功但响应较慢standard_user错误密码登录失败空用户名secret_sauce提示用户名必填standard_user空密码提示密码必填这些用例非常适合用pytest.mark.parametrize参数化不需要为每个场景重复写一段 Selenium 操作。可以把这个作为后续练习题请将上面 SauceDemo 典型账号表格整理成参数化测试数据并分别断言登录成功后的跳转地址或登录失败后的错误提示。参考方向如下pytest.mark.parametrize(case_name,username,password,expected_type,expected_text,[(标准用户登录成功,standard_user,secret_sauce,success,inventory.html),(锁定用户登录失败,locked_out_user,secret_sauce,error,locked out),(错误密码登录失败,standard_user,wrong_password,error,do not match),(用户名为空,,secret_sauce,error,Username is required),(密码为空,standard_user,,error,Password is required),],)deftest_saucedemo_login_cases(driver,case_name,username,password,expected_type,expected_text):login_pageSauceDemoLoginPage(driver)login_page.open()login_page.login(username,password)ifexpected_typesuccess:assertexpected_textinlogin_page.get_current_url()else:assertexpected_textinlogin_page.get_error_message()七、下次遇到类似面试题的执行顺序如果重新做一次这类题我会按下面的顺序推进。第一步快速确认项目运行方式先看 README、测试目录、依赖文件和运行脚本。确认项目是用pytest、unittest还是其他框架执行找到面试官期望的入口。在当前复刻项目中可以用统一入口运行全部用例py run_test.py首次运行前先安装依赖py-m pip install-r requirements.txt如果电脑没有py命令也可以使用python-m pip install-r requirements.txt也可以双击或执行run_test.bat。这个 bat 会切换到当前项目目录再调用run_test.py。run_test.py内部使用 pytest 的-v模式运行tests/目录因此终端会输出每条 case 的名字和运行结果例如tests/test_saucedemo_login.py::test_login_success_redirects_to_inventory[standard_user-secret_sauce] PASSED当前run_test.bat内容可以整理为echo off setlocal EnableExtensions chcp 65001 nul cd /d %~dp0 set PYTHONUTF81 set UV_CACHE_DIR%~dp0.uv-cache set UV_PYTHON_INSTALL_DIR%~dp0.uv-python set SE_CACHE_PATH%~dp0.selenium-cache set PROJECT_PYTHON%~dp0.uv-python\cpython-3.12.13-windows-x86_64-none\python.exe set VENV_PYTHON%~dp0.venv\Scripts\python.exe echo echo Selenium Demo Test Runner echo Project: %CD% echo where uv nul 2 nul if %errorlevel%0 ( call :run_with_uv goto :finish ) if exist %VENV_PYTHON% ( echo [INFO] uv was not found. Using existing .venv. %VENV_PYTHON% run_test.py set EXIT_CODE%errorlevel% goto :finish ) set PYTHON_CMD where py nul 2 nul if %errorlevel%0 set PYTHON_CMDpy if not defined PYTHON_CMD ( where python nul 2 nul if %errorlevel%0 set PYTHON_CMDpython ) if not defined PYTHON_CMD ( echo [ERROR] No Python runtime was found. echo [HINT] Install uv, then run: echo uv sync set EXIT_CODE1 goto :finish ) echo [INFO] uv was not found. Using %PYTHON_CMD%. %PYTHON_CMD% run_test.py set EXIT_CODE%errorlevel% goto :finish :run_with_uv echo [INFO] uv detected. if exist %PROJECT_PYTHON% ( echo [INFO] Syncing dependencies with project-managed Python. uv sync --cache-dir %UV_CACHE_DIR% --python %PROJECT_PYTHON% ) else ( echo [INFO] Syncing dependencies from pyproject.toml. uv sync --cache-dir %UV_CACHE_DIR% ) if not %errorlevel%0 ( set EXIT_CODE%errorlevel% echo [ERROR] Dependency sync failed. exit /b %EXIT_CODE% ) echo [INFO] Running tests. uv run --cache-dir %UV_CACHE_DIR% python run_test.py set EXIT_CODE%errorlevel% exit /b %EXIT_CODE% :finish echo. if %EXIT_CODE%0 ( echo [OK] Test run finished successfully. ) else ( echo [ERROR] Test run failed with exit code %EXIT_CODE%. ) echo. echo This window will stay open. Close it manually when you are done. echo. cmd /k exit /b %EXIT_CODE%第二步先跑通原有用例不要一上来就改代码。先执行原有测试确认环境、浏览器、WebDriver、网络和依赖没有问题。这样后面新增用例失败时才能判断是代码问题还是环境问题。第三步根据规则列测试点把表单规则拆成字段规则和业务规则必填校验。长度校验。格式校验。重复数据校验。正确登录。错误登录。锁定账号或异常账号。重复提交。错误提示是否准确。页面跳转是否正确。第四步优先自动化高价值用例面试时间有限不一定要覆盖所有组合。优先写最能体现测试能力的用例登录成功主流程。用户名为空。密码为空。错误密码。锁定账号。重复注册。这些场景既能覆盖主流程也能覆盖异常流和业务规则。第五步把 Bug 写成失败用例发现 Bug 后不只写备注还要写断言。比如重复注册场景预期是出现“账号已存在”提示。如果系统仍然注册成功用例就应该失败。这类失败用例对面试官很有价值因为它证明我能把手工测试发现转化成回归测试资产。第六步更新运行脚本并生成结果最后检查run_test.bat是否包含新增测试文件并运行一次完整测试。交付时说明新增了哪些用例。发现了哪些 Bug。哪些用例通过哪些用例失败。失败是否符合预期。报告或日志输出在哪里。八、我这次真正需要补上的能力这次复盘后我认为自己要补的不是单一技术点而是一套自动化测试交付习惯。第一测试设计要更完整。不能只凭直觉点页面要系统覆盖正常流、异常流、边界值、等价类和业务规则。第二发现 Bug 后要自动化。面试中的 Bug 不是说出来就结束而是要写成可复现、可断言、可回归的测试用例。第三要熟悉原项目结构。已有 Page Object、定位器管理、driver 管理和日志工具时应该沿用项目结构补充代码。第四要重视运行入口。run_test.bat、测试报告、日志和截图都是自动化测试交付的一部分。第五要能解释自己的取舍。时间有限时不一定能写完所有用例但要说明优先级先覆盖主流程和高风险异常流再扩展边界值和组合场景。九、后续改进计划基于当前selenium_demo项目我后续可以继续补充在SauceDemoLoginPage中增加错误提示获取方法。在定位器 YAML 中增加错误提示元素。在tests/test_saucedemo_login.py中增加异常登录参数化用例。继续完善run_test.py和run_test.bat统一执行测试并生成报告。将失败截图和日志路径写入 README。例如异常登录用例可以设计为pytest.mark.parametrize(username,password,expected_message,[(,secret_sauce,Username is required),(standard_user,,Password is required),(standard_user,wrong_password,Username and password do not match),(locked_out_user,secret_sauce,Sorry, this user has been locked out),],)deftest_login_failed_shows_error(driver,username,password,expected_message):login_pageSauceDemoLoginPage(driver)login_page.open()login_page.login(username,password)assertexpected_messageinlogin_page.get_error_message()这个方向比单纯多写几个页面点击更重要因为它能体现自动化测试的核心价值用稳定的脚本持续验证业务规则。十、总结这次面试没有完成测试题表面看是 Selenium 用例没有补完深层原因是我当时没有把“自动化测试交付闭环”想完整。自动化测试工程师在面试题中需要展示的不只是会定位元素、会点击按钮、会写断言还要展示测试分析能力、工程结构意识、脚本运行能力和结果交付意识。下次再遇到类似题目我应该提醒自己先跑通原项目再设计测试点先覆盖主流程和高风险异常流再补边界值发现 Bug 后立刻沉淀成自动化用例最后用run_test.bat或项目指定入口执行并把结果清楚交付出来。这才是从“我找到了一个 Bug”到“我完成了一次自动化测试任务”的区别。扩展新用例新增页面测试时建议按以下步骤组织在data/locators/中新增页面定位器文件。在pages/中新增对应 Page Object继承BasePage。在tests/中新增 pytest 测试用例。测试数据优先通过 pytest 参数化或data/data/下的数据文件传入。扩展新功能可以设置将前面的bat脚本定时运行如当日下午8点至早上8点命令行方式schtasks /Create ^ /TN SeleniumDemo_NightRun ^ /TR F:\dowload\project\auto_test\6.selenium_demo\run_test.bat ^ /SC DAILY ^ /ST 20:00 ^ /RI 60 ^ /DU 12:00 ^ /F说明/ST 20:00晚上 8 点开始/RI 60每 60 分钟执行一次/DU 12:00持续 12 小时到次日早上 8 点/TR指定要执行的 .bat 文件图形界面方式打开「任务计划程序」点击「创建任务」在「触发器」中新建每天 开始时间20:00重复任务间隔1 小时持续时间12 小时在「操作」中新建程序或脚本F:\dowload\project\auto_test\6.selenium_demo\run_test.bat起始于F:\dowload\project\auto_test\6.selenium_demo保存任务即可注意如果 bat 运行后不自动退出定时任务会一直占用进程最好定时任务使用一个运行完会退出的 bat。