1. 竞赛自动化测试考题的命题规律与备考重心1.1 赛项分值分布与常见考点先弄明白考什么2026年广东省职业院校技能大赛高职组“软件测试”赛项延续了历届“以真实业务系统为载体、以测试全流程为主线”的考核思路。第二套自动化测试题表面上是考自动化测试脚本实际上考的是“测试用例设计 自动化脚本编写 测试执行 缺陷记录”四件事的串联能力。说得直白一点评委会给你一个部署好的Web系统里面埋了若干个缺陷让你编写自动化测试脚本去覆盖业务流程并在规定时间内跑出结果、记录问题、提交测试文档。从近三年的赛题看自动化测试部分的分值占比大概在20%—30%之间但它的实际影响远超分值本身。原因很简单自动化测试是整场比赛唯一能够“批量发现缺陷”的环节。功能测试靠人工点界面一题一题地过效率低而自动化脚本一旦跑通几十条用例可以在几分钟内执行完毕缺陷暴露量会明显上升。比赛中的成绩断层往往就发生在这一环节——有的团队用Selenium写脚本二十分钟跑完四十条用例还能顺带把截图证据链做得漂漂亮亮有的团队写了半天脚本最后执行报错慌乱中改代码越改越乱。再说考点的分布。以第二套题的自动化测试模块为例核心高频考点通常落在以下五类业务场景上登录/注销流程包括账号密码校验、验证码跳转、错误提示信息验证数据列表查询与筛选包括关键字搜索、分页跳转、空结果提示表单的新增、编辑、保存包括必填项校验、重复数据校验、成功后的页面跳转与回显业务流转操作例如提交订单、审批通过、审核驳回等带状态流转的流程数据删除与批量操作包括确认弹窗、删除成功后列表刷新。看起来都是“常规功能”但比赛系统常常会在操作路径上做一些特殊设计例如登录成功后页面跳转带参数、表单提交前有二次确认弹窗、某些按钮在特定状态下才可点击。这些细节正是自动化测试脚本“容易翻车”的地方往往也是区分高分卷和低分卷的分水岭。1.2 “参考答案”的正确用法从抄答案到理解评分方式很多准备比赛的选手拿到“参考答案”后的第一反应是直接背脚本、背用例。我的建议是可以背但不能死背。比赛最大的变数在于测试环境。同一套题库在不同赛场部署时受系统版本、浏览器版本、初始数据状态的影响元素定位路径和预期结果会发生细微差别。死背一套代码遇到环境差异就会直接卡死。更好的用法是拿参考答案去反推它的答题思路这道题的用例覆盖点是什么脚本为什么这样设计断言测试报告里如何描述缺陷才算得分点弄清楚评分方式比追求“脚本能跑”更重要。竞赛评分通常分成几个维度第一用例设计质量。用例需要和题目要求的功能点一一对应覆盖正常流和异常流预期结果要写清楚不能含糊。很多选手把用例写成了操作步骤流水账缺少“断言点”——这在评分时会被扣掉相当比例的分数。第二脚本能否正确执行。这是硬指标。脚本必须能在比赛系统上从零开始独立跑通且结果与预期一致。评分时评委通常不会一行行读你的代码而是直接看运行过程和输出结果。之前见过有选手的脚本在自己的笔记本上能跑到了比赛机器上就挂掉排查半天发现是浏览器驱动版本不一致这种“低级问题”造成的失分非常可惜。第三执行证据链。包括脚本运行过程截图、日志输出、测试结果汇总表、缺陷报告单。评委要根据证据来给分尤其在“是否发现指定缺陷”这一项上没有截图的缺陷等于没发现。第四代码规范性。包括变量命名是否可读、是否使用数据驱动、是否使用了合理的等待方式等。规范性在评分表中的权重通常不高但在两人操作的比赛现场规范代码意味着更容易排查和修改——这属于隐性加分项。所以“参考答案”最大的价值不是让你闭眼抄而是让你对照它的评分点检查自己在设计、编码、证据、文档四个环节上有没有缺失。2. 自动化测试答题的完整链条用例、脚本、执行、证据一个不能少2.1 测试用例设计自动化脚本的地基很多选手在拿到题目后第一件事就是写代码这是大忌。正确的顺序是先设计用例再写脚本。哪怕时间再紧张也至少要花20到30分钟把用例框架搭出来。自动化测试的用例设计和功能测试用例的写法略有不同核心区别在于“可执行性”。每条用例必须包含六个要素用例编号例如TC_Login_001测试模块与前置条件操作步骤细到输入什么、点击哪里输入数据具体值不能写“任意合法账号”预期结果明确到“出现什么提示”“跳转到哪个页面”“单元格显示什么内容”实际结果与测试结论执行完填写以登录模块为例一套好的自动化用例至少应该覆盖用例场景输入数据预期结果正确账号密码登录admin / 123456登录成功跳转首页显示用户名正确账号错误密码admin / 000000提示“密码错误”空账号登录空 / 123456提示“请输入用户名”空密码登录admin / 空提示“请输入密码”不存在账号testuser / 123456提示“用户不存在”连续错误锁定错误密码连续5次提示“账号已锁定”这些场景不一定全部出现在比赛题目里关键在于你的用例设计思路要体现“等价类划分 边界值分析 场景法”的组合应用。评委看的是你懂不懂测试设计方法而不是单纯看你列了多少条用例。用例设计另一个容易被忽略的点是“步骤描述的颗粒度”。写给自动化脚本用的用例步骤必须精确到控件级别。比如“点击搜索按钮”之前需要写明“在关键词输入框中输入‘张三’点击‘搜索’按钮等待结果列表刷新”。颗粒度太粗的用例到了写脚本时会让你反复回看页面搞清楚操作路径非常浪费时间。2.2 自动化脚本编写用最短的代码踩通主流程用例设计完成后不要急着给每条用例都写独立脚本。更高效的做法是先写一个“主流程脚本”把所有页面对象和业务操作封装成函数再根据用例逐条调用。以Selenium Python为例一个典型的自动化测试项目结构可以按以下方式组织# conf.py配置信息 BASE_URL http://192.168.1.100:8080/#/login USERNAME admin PASSWORD 123456 DRIVER_PATH rD:\tools\chromedriver.exe # base_page.py页面公共操作封装 from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class BasePage: def __init__(self, driver): self.driver driver self.wait WebDriverWait(driver, 10) def find(self, locator): return self.wait.until(EC.presence_of_element_located(locator)) def click(self, locator): self.wait.until(EC.element_to_be_clickable(locator)).click() def input(self, locator, text): elem self.find(locator) elem.clear() elem.send_keys(text) def get_text(self, locator): return self.find(locator).text# login_page.py登录页面对象 from selenium.webdriver.common.by import By class LoginPage(BasePage): username_loc (By.ID, username) password_loc (By.ID, password) login_btn_loc (By.ID, loginBtn) error_msg_loc (By.CLASS_NAME, el-message--error) def login(self, username, password): self.input(self.username_loc, username) self.input(self.password_loc, password) self.click(self.login_btn_loc)# test_login.py登录用例脚本 from selenium import webdriver from login_page import LoginPage import unittest class TestLogin(unittest.TestCase): def setUp(self): self.driver webdriver.Chrome() self.driver.get(BASE_URL) self.page LoginPage(self.driver) def tearDown(self): self.driver.quit() def test_login_success(self): self.page.login(admin, 123456) # 断言登录成功后页面跳转且用户名元素可见 self.assertTrue(self.page.is_login_success()) def test_login_wrong_password(self): self.page.login(admin, 000000) self.assertTrue(self.page.is_error_msg_displayed(密码错误))比赛现场的时间压力下脚本能做到“页面对象封装 通用等待 断言函数”三层结构已经足够拿高分。不要去追求过度复杂的设计模式比如多层继承、数据工厂之类竞赛评分不会因此加多少分反而容易把调试时间拖长。2.3 测试证据链决定能不能拿满分的环节脚本跑通只是第一步如何把“跑通”变成评委能看到的证据才是拿分的关键。我见过太多团队脚本执行结果在控制台上全是绿色的通过但最后分数却不理想。为什么因为评委没有看到任何截图、日志或结果记录。控制台上的输出关闭之后什么都没有了评分依据自然就不够充分。正确的做法是在脚本中按场景自动截图并将截图统一命名保存到指定目录。比如import datetime def take_screenshot(driver, name): now datetime.datetime.now().strftime(%Y%m%d_%H%M%S) driver.save_screenshot(f./screenshots/{name}_{now}.png)在关键操作点之后插入截图包括登录成功后、查询结果加载后、表单提交成功提示后、缺陷复现时。截图的命名要包含用例编号和业务含义比如“TC_Login_001_登录成功.png”这样评委一眼就能看出对应哪条用例。除了截图之外脚本还应输出对应步骤的日志信息。用Python的logging模块写入文件每步操作记录一行“时间 用例编号 操作内容 结果状态”。测试结束之后日志就是完整的执行轨迹不需要评委对着控制台翻来翻去。还有一点比赛现场的测试环境通常是局域网部署的Web系统评委在评判时更依赖选手提交的测试报告和证据附件。建议在写完用例、跑通脚本之后留出固定时间把截图、日志、测试结果汇总成一份带目录的文档比单纯提交一堆松散文件要专业得多。3. 高分自动化脚本必须绕开的五个技术坑3.1 版本环境比赛的“隐形淘汰项”自动化测试比赛中最常见、也最冤的失分点是环境不一致导致脚本无法执行。比赛机房电脑上安装的Chrome版本和你平时练习用的版本不一致WebDriver版本匹配不上一启动就直接抛“session not created”异常。这类问题不涉及任何技术难度纯粹是准备不足。赛前一定准备好这两种东西一是兼容多个版本的chromedriver二是能自动匹配浏览器版本的驱动管理工具。推荐使用Selenium Manager或webdriver-manager这类工具它们可以根据浏览器版本自动下载和匹配驱动。Python示例from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager driver webdriver.Chrome(ChromeDriverManager().install())但要注意比赛机房的网络可能不允许访问外网下载驱动用webdriver-manager在线安装驱动的方案可能失效。更稳妥的做法是把对应版本的chromedriver放到本地目录在启动脚本中显式指定路径并且准备两到三个版本备份在U盘里。比赛当天第一件事不是看题目而是确认环境打开被测系统、打开浏览器开发者工具、确认Chrome版本号、检查驱动能否正常启动、尝试找到被测系统的登录页面元素。这一套流程控制在10分钟内能帮你提前排掉80%的环境隐患。3.2 元素定位别把XPath写死自动化测试脚本里元素定位是“翻车率”最高的环节。很多同学喜欢直接复制开发者工具里的绝对XPath比如//*[idapp]/div/div[2]/div/div[2]/div[2]/div[2]/div[3]/div[2]/button这种定位方式在静态页面里勉强能用但比赛系统很多界面是动态渲染的列表数据加载后DOM结构会变化绝对XPath稍微多一个节点就失败。正确做法是优先按稳定属性定位顺序应该是id name class 相对XPath CSS选择器。写相对XPath时尽量通过元素的业务属性来定位。比如有一个按钮文本是“新增用户”首选xpath //button[contains(class,btn-add) and contains(text(),新增)]如果页面里有两个按钮都叫“新增”可以用位置关系来限定比如定位“用户列表区域的第一个新增按钮”xpath //div[contains(class,user-list)]//button[contains(text(),新增)]再补一个在比赛里特别实用的技巧优先用CSS选择器代替XPath。CSS的定位写法通常更短、更稳定比如css input[namekeyword] css button.btn-primary css li.active a而且Selenium的find_element(By.CSS_SELECTOR, ...)在元素查找失败时的报错信息也比XPath更容易定位问题。3.3 等待机制休眠等待是失分重灾区比赛系统基本都用了现代前端框架页面元素加载存在明显的异步延迟。最常见的失败场景是脚本点击搜索按钮后立刻断言下一页面的元素结果因为数据还没加载完元素不存在脚本直接报NoSuchElementException。很多同学的习惯是用time.sleep(3)让脚本固定等待三秒。虽然简单粗暴但问题也明显网速和服务器响应快的时候白白等三秒拖慢执行效率服务器响应慢的时候三秒不够脚本照样报错。更好的方案是使用显式等待等到指定条件满足再继续from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By wait WebDriverWait(driver, 10) wait.until(EC.visibility_of_element_located((By.ID, userTable)))显式等待的关键参数是超时时间。比赛中建议设置8到10秒因为页面局部刷新偶尔要5秒以上。如果超时时间设太短执行会不稳定太长则拖慢整体节奏。还有一个小坑expected_conditions里的visibility_of_element_located和presence_of_element_located是有区别的。前者要求元素可见在页面上占位置且不隐藏后者只要求元素存在于DOM中。断言“成功提示”这类元素时建议用visibility避免元素在DOM里存在但被隐藏导致误判。3.4 数据驱动与参数化一份数据多次复用的通用做法比赛题目里经常要求对同一流程执行多条数据用例比如用不同账号测试登录、用不同关键词测试查询。如果每个数据都写一段脚本代码脚本长度会爆炸而且新增用例时改动量大。数据驱动是这里的标准解法。一种简单做法是使用unittest的subTest配合数据列表login_data [ {username: admin, password: 123456, expected: 登录成功}, {username: admin, password: 000000, expected: 密码错误}, {username: , password: 123456, expected: 请输入用户名}, ] for data in login_data: with self.subTest(datadata): self.page.login(data[username], data[password]) self.assertEqual(self.page.get_result_text(), data[expected])subTest的好处是其中一条数据断言失败时不会中断后续数据执行而且输出信息里会带出具体的数据项方便你快速定位是哪组数据出了问题。如果脚本量更大可以把测试数据单独放到JSON或Excel文件里利用Python的openpyxl或json库读取import json with open(login_data.json, encodingutf-8) as f: login_data json.load(f)这种分层方式在代码规范评分点上是明显的加分项现场调试时也省心——改数据完全不用动代码。3.5 断言逻辑断过多不如断得准断言是自动化测试的灵魂也是评分时判断“用例是否真正覆盖了需求”的核心依据。但很多选手在这一环节把握不住分寸。一种极端是“没断言”脚本把操作步骤做完了但不检查任何结果执行完毕就算“通过”。这种脚本对缺陷发现没有任何价值评分时几乎拿不到分因为评委无法确认你的脚本是否真正验证了预期结果。另一种极端是“过度断言”每完成一步就断言所有可见元素的文本甚至把无关的页面标题、静态文案也写进断言。这样脚本脆弱不堪稍微有一点无关元素变化就失败调试时浪费大量时间。正确做法是只对“业务结果”断言。所谓业务结果就是需求的验收点。比如新增用户成功后断言列表中出现了新用户名并且有成功提示删除用户成功后断言列表中不再出现该用户名并且有确认弹窗提示错误密码登录断言页面上出现“密码错误”提示且没有跳转首页查询关键词为“张三”断言结果列表的所有行都包含“张三”或者至少第一行匹配。断言点的数量控制在每条用例2到4个就足够了。比赛时脚本执行速度要快断言过多只会增加不稳定因素。4. 比赛时间分配与应急处理方案4.1 黄金三段时间模型脚本、验证、报告广东省赛的软件测试赛项通常比赛总时长在4小时左右。第二套自动化测试题如果单独成模块建议采用“三个一”的时间分配模型即“一个半小时写脚本一个小时执行验证一个小时写报告最后半小时兜底复查”。第一个半小时拿来做环境和用例设计。很多人觉得这个时间段不该用来设计用例直接写代码效率更高恰恰相反。比赛题目的被测系统是你之前没见过的先浏览系统功能结构、确认哪些模块是自动化测试的考核对象才能保证你的用例覆盖面和题目的功能点对齐。环境自检也在这个时间段完成。接下来一个半小时写脚本。这段是最消耗脑力的时间建议两人分工协作一个人负责写核心页面对象另一个人负责写用例流程。写完一个模块就立即运行一次而不是全写完再运行。分批运行的好处是问题早暴露、早解决不会在最后阶段积压一堆报错。然后留一个小时做全量执行和验证。执行前先清空浏览器缓存、重置被测系统数据如果比赛系统提供重置功能再按测试计划跑完整套脚本。这里要强调全量执行至少要跑两遍。第一遍验证脚本能通第二遍确认结果稳定。如果时间只够跑一遍也要在报告中标注“执行一次”和风险提示。最后一个小时写测试报告和整理证据。这一小时内要做的事情很多汇总测试结果、筛选缺陷截图、写明缺陷复现步骤、按严重等级分类缺陷、把自动化脚本和用例文档打包压缩。注意压缩包命名规范很多赛事要求按“参赛队编号-模块名称-文件列表”的格式命名不按要求命名会直接被扣分。4.2 现场最常见的突发情况与应对清单比赛现场永远有意外。提前想好对策真出事时就能冷静处理。先看脚本层面的突发情况。如果脚本中途报错第一件事不是改代码而是先看报错信息定位到具体行号。常见的几种情况元素找不到优先检查页面是否真的加载到这一步确认定位符是否变化元素被拦截优先检查是否有弹窗遮挡、按钮是否处于禁用状态断言失败优先检查业务逻辑是否真的符合预期确认是“系统缺陷”还是“脚本写错预期值”。这里有一个实操经验比赛题目里埋的缺陷往往恰好是“按钮点击后无反应”“查询结果与条件不匹配”这类问题。如果你的断言报错了先不要怀疑自己重新手工操作一遍确认系统的真实表现。如果手工操作也和预期不一致那就恭喜你发现了一个缺陷记得截图记录。再看系统层面的突发情况。浏览器崩溃、网络断开、被测系统无响应——遇到这些情况先保持镇定举手示意工作人员说明情况请求处理。赛事一般会提供问题处理通道但你自己也要有预案脚本要随时保存重要代码提交到U盘备份浏览器配置固化好避免崩溃后重配环境浪费时间。最后是时间层面的也是最容易让人慌的临近交卷还有半小时但还剩一部分用例没跑完。这时候果断放弃全量执行转为“定向执行”优先跑和核心功能点相关的用例确保主要得分点已经拿到证据。剩余未执行的用例在报告中明确标注“因时间不足未执行”这比硬撑着跑完一堆乱码、最后证据混乱要体面得多。5. 赛后复盘从参考答案到真正变强的路径5.1 对比答案而不是背答案比赛结束后很多同学喜欢把参考答案拿回来原封不动地背诵指望下一场比赛直接套用。坦白说这种做法的收益非常有限。更好的做法是把参考答案和自己的方案逐项对比找出差异背后的原因用例设计层面参考答案覆盖了哪些边界情况你自己漏了哪些漏掉的原因是什么脚本实现层面参考答案的断言点设置在哪里和你选的断言点有什么不同哪种更接近测试目标证据链层面参考答案的测试报告格式如何组织缺陷描述用了哪些关键词有没有你可以直接复用的报告模板对比时重点关注被扣分的地方。赛题评分细则通常会在说明文档列出对照细则逐项核对自己哪里失了分下一次比赛就不会再犯同样的错。这才是一份“参考答案”真正值钱的部分。5.2 一次比赛对实际工作的迁移价值从长期来看参加这类比赛的收获远不只是奖项。自动化测试比赛的全流程和真实工作项目高度相似都有需求文档、都有被测系统、都要写用例、都要设计脚本、都要提交测试报告。在比赛中训练出来的用例设计能力、脚本调试能力、时间管理能力、缺陷表达能力都能直接迁移到软件测试岗位的实际工作中。尤其值得一说的是“测试思维”。比赛中你面对的每一个被测系统本质上都是陌生的业务系统。快速读懂系统、快速圈定测试范围、快速设计有效用例——这种能力在任何测试岗位都吃得开。比赛中培养的Selenium脚本习惯、PO模式设计思路、断言和等待的使用分寸也直接对应到企业级自动化测试项目中。最后再分享一个细节比赛用到的测试文档模板、检查清单、脚本脚手架赛后在获得参赛队许可的前提下可以整理成一个自己的自动化测试工具箱。以后面对实际项目的自动化测试任务直接在这个工具箱的基础上迭代效率会比从零开始高出一大截。我自己参与过的许多实际项目自动化测试方案最初的雏形就来自比赛现场的这套应急打法。