ARTICLE DETAIL

资讯详情

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

自动化测试框架设计:从能跑到好用,核心是约束与流程

自动化测试框架设计:从能跑到好用,核心是约束与流程 接手过一套跑了两年但几乎没人看的自动化框架500多条用例每次全量跑完要一个半小时通过率长期在70%上下徘徊报告发到群里第二天就被刷过去了。问团队成员为什么不看回答很一致——跑红的用例我也不知道怎么修看了也没用。这套框架从工具选型到用例组织都透着技术很努力的气息却恰恰死在了没人能接手和结果不可信这两件最基础的事上。后来我重新搭了一套几个月内通过率稳定在98%以上大家开始主动去看失败原因、顺手补用例。这中间最深的体会是自动化测试框架设计本质不是在写代码而是在设计约束和流程——约束你的测试代码该长什么样流程上保证结果能被人信任、被团队用起来。这篇文章结合我多年在接口测试、UI自动化、持续集成场景下的实操经验聊一聊从零设计一套自动化测试框架时要考虑的核心问题。适合正在规划测试架构的测试开发工程师、想从能跑走向好用的团队也适合刚接触自动化、想建立完整认知的测试新人。我会尽量把工具选型、分层逻辑、设计模式、数据管理、稳定性治理这些话题讲透并给出可以直接落地的思路。1. 为什么多数自动化框架最后沦为摆设先想清楚这4个问题很多人聊框架设计一上来就争论用pytest还是Robot Framework用Java还是Python要不要自研平台这些其实都不是最要命的问题。工具和语言各有优劣选哪个都能做出能用的框架。真正让框架死掉的往往是下面这4个问题在设计之初就没被认真回答。1.1 你到底要自动化什么这是所有问题的起点。自动化不是一个笼统的目标它分UI自动化、接口自动化、单元测试、契约测试、性能测试等多个层次每个层次的投入产出比完全不同。以我个人的经验排序接口自动化的性价比最高UI自动化维护成本最高。接口测试跑得快、依赖少、接口不稳定时能直接定位到前后端的问题UI自动化虽然最贴近用户视角但页面稍微改个文案、挪个按钮用例就要跟着动尤其在国内这种前端迭代极快的环境里UI用例的维护成本经常是接口用例的5倍以上。所以设计框架之前先跟团队对清楚这个框架主要服务于哪类测试是回归测试、冒烟测试还是上线前的全量验证测试对象是内部管理系统还是面向终端用户的高并发场景这些会直接决定后续的用例组织方式和技术选型。1.2 谁来维护这些用例这可能是最容易被忽略、却最致命的问题。一套框架刚搭起来的时候通常都光鲜亮丽但业务需求是不断变化的——接口加了字段、页面改了交互、权限模型变了。如果每一次业务变更测试代码都要跟着动而团队里又没有明确的负责人用不了三个月用例库里就会出现大量历史遗留的红色用例。我见过不少团队自动化项目启动时全员热情高涨写了上千条用例结果半年后只剩一个人在“抽空看看”再后来连这个人也看不过来了。这就是典型的没有回答谁来维护的问题。设计框架时必须同步设计维护机制是测试开发专职维护还是业务测试全员参与用例的评审和重构节奏是怎样的需求变更的通知链路是否畅通这些问题没有答案框架的寿命不会超过一个季度。1.3 稳定性能不能达到可容忍的门槛自动化测试最怕的不是用例失败而是随机失败——同一个用例上个月跑红的这个月没有任何代码改动却变绿了下个月又红了。这种不确定性会彻底摧毁团队对自动化结果的信任。稳定性的核心威胁通常来自三个方面等待策略不健壮、测试数据互相污染、环境不稳定。这三块我会在后面的章节展开细讲。这里只想强调一个判断标准如果一套自动化框架的通过率低于90%并且趋势不稳定就不要指望团队会依赖它的结果。与其继续堆用例不如先把已有的用例治稳定。1.4 反馈速度能不能跟上使用场景自动化测试的价值跟反馈速度直接挂钩。一套框架跑完全量用例需要两小时那它只能作为夜间巡检工具早晨看结果、修复、再验证完整闭环要跨一个工作日。但如果能把关键用例压缩到10到15分钟内跑完这套框架就能嵌入开发阶段的CI流水线每次提交代码、合并分支都触发执行把问题拦截在更早的环节。不要小看这个差距。反馈快的框架会把测试从质量门禁变成开发伙伴团队使用意愿会完全不同。所以在框架设计时就要有意识地在用例分层上做快速反馈集和全量回归集两大类而不是所有用例一锅烩。2. 框架分层的核心逻辑用例层、业务层与驱动层的边界画法框架设计里最常被提起但又最容易被做歪的就是分层。很多人听到分层就想到Page Object、想到BaseCase但真正理解分层是为了什么的人不多。2.1 分层的本质把变化隔离在固定区域我习惯用做饭来打比方。一套完整的测试框架类似一个运转的厨房菜单是测试用例做什么菜、厨师是业务逻辑层怎么把菜做出来、食材采购员是驱动层原料从哪儿来、怎么处理、厨房管理制度是配置与基础设施层环境、数据、权限、日志。这个比方背后的核心思想是每一个变化源都应该有自己专属的存放地点不能散落在各个用例里。比如页面元素的定位、接口的URL和参数格式、登录态的获取方式、测试数据的准备和清理、失败重试的机制——这些都是变化源。如果它们被打散在100条用例里每次需求变更你就要在100个地方做修改这就是维护成本失控的开始。2.2 不同测试类型的分层思路UI自动化经典的分层结构是这样的用例层只描述业务场景比如用户登录后修改个人资料成功。业务逻辑层封装具体操作步骤比如登录动作、填写表单、点击按钮。对象层封装页面元素定位例如页面对象的Page类元素定位集中管理。基础设施层负责浏览器驱动、等待策略、日志截图、数据准备等通用能力。接口自动化的分层略微不同更常见的是这样用例层定义测试场景、断言断言逻辑。接口封装层把HTTP请求封装成业务方法例如创建订单查询订单状态。数据工厂层负责测试数据的生成、准备和清理支持从YAML、JSON或数据库读取。基础设施层负责请求会话管理如登录态token、配置读取、日志与报告。分层不一定非要三层或者四层关键是每层只关心自己的职责。用例层不写DOM定位、不拼HTTP请求、不管理数据库连接接口封装层不写断言、不处理业务逻辑判断基础设施层的改动不应该影响用例的写法。2.3 一条写用例的红线用例层只说做什么我自己在评审测试代码时有一条红线用例层只允许出现业务语义不允许出现任何技术实现细节。举两个例子对比一下。不推荐的写法是这样的def test_login_success(): driver webdriver.Chrome() driver.get(https://example.com/login) driver.find_element(By.ID, username).send_keys(admin) driver.find_element(By.ID, password).send_keys(123456) driver.find_element(By.ID, login_btn).click() time.sleep(3) assert 欢迎 in driver.page_source driver.quit()这条用例把浏览器启动、元素定位、强制等待、断言方式全塞在一起。今天换一个页面结构要改明天换一套登录方式要改后天要求支持无头模式又要改。加了Page Object之后会好一些但好得还不够彻底。更接近我期望的写法是这样的def test_user_can_modify_profile(login_as_admin, api_client): profile api_client.update_profile(user_idU10086, nicknamenew_nickname) assert profile.status_code 200 assert profile.json()[nickname] new_nickname这条用例读起来就是一个完整的业务规则不看代码细节也能知道它在验证什么。至于用户怎么登录的、请求怎么发的、数据怎么准备的全部由fixture和封装层去解决。这样的用例写起来快、读起来轻松、维护时不需要去猜作者的意图。2.4 分层的反例一个四不像框架长什么样说个真实的反面教材。我有一次接手别人的自动化项目看到工程结构里既有unittest风格的TestCase类又有pytest风格的函数用例还有几个装饰器满天飞的高级封装。点开一条用例里面直接连了生产环境的数据库、硬编码了密码、还用time.sleep(5)等待一个不确定的异步请求。这种框架的问题在于它没有做任何一层约束——写用例的人可以自由发挥想怎么写就怎么写最后整个工程就变成一个各写各的风格集合。测试框架设计的第一要务就是约束。约束用例的写法、约束数据的来源、约束等待的方式、约束断言的方式。这种约束不是限制创造力而是保证100条用例之间可预期、可维护、可协作。3. 工具选型不是堆新技术pytest生态与Selenium/Requests的取舍工具选型这个话题很容易陷入谁的粉丝多的争论。我想说的是选工具不是选最好最火的是选最匹配你团队上下文和业务类型的。这里我分享下我最常用、也最推荐的一套组合以及为什么这样选。3.1 为什么我首选pytest而不是unittest在Python生态里unittest是标准库自带的老将pytest是事实上的社区标准。我几乎所有的框架都是用pytest搭的原因很朴素fixture机制和断言风格太舒服了。unittest的setUp和tearDown是类级别的写起来很僵硬。如果一条用例需要特定的数据准备另一条不需要unittest就要靠加开关或者写多个测试类来区分代码会越来越绕。pytest的fixture是函数级别的依赖注入按需申请、按作用域复用可以灵活组合。另一个让我坚定选pytest的点是断言和失败信息。unittest强制你用assertEqual、assertTrue这一套断言失败时给出的信息有时候很让人抓狂。pytest直接使用Python原生的assert语句失败时还会给你左右对比的上下文。接口测试里断言字段、JSON结构、状态码直接用assert就非常直观。3.2 fixture机制到底解决了什么问题fixture的核心价值是把环境准备和清理变成一种可复用的资源而不是散落在每个用例里的样板代码。这个是我在设计框架时最常用到的能力。import pytest import requests pytest.fixture(scopesession) def auth_token(): 整个测试会话共用一个登录态避免每个用例都重新登录 resp requests.post(https://api.example.com/login, json{username: tester, password: ******}) assert resp.status_code 200 return resp.json()[token] pytest.fixture def api_client(auth_token): 每个用例拿到一个带认证的请求客户端 session requests.Session() session.headers.update({Authorization: fBearer {auth_token}}) yield session session.close()scopesession表示整个测试周期只做一次登录后续用例全部复用这个token。scope有function、class、module、session四档用哪个档取决于你的数据独立性需求。如果系统依赖登录态而并发执行多个用例共享一个token都没问题就用session级别跑起来能省很多时间。fixture的yield语法也解决了做完要清理的场景比如创建了一个数据库记录测试完了要删除写在yield后面即可。这比unittest的tearDown优雅得多尤其当多个fixture组合使用时依赖关系是显式声明的测试流程很容易梳理。3.3 Selenium的适用边界跨浏览器支持的真相说到UI自动化Selenium依然是绕不开的名字。它通过WebDriver这套协议驱动真实浏览器最大的价值就是跨浏览器支持——Chrome、Firefox、Edge、Safari自然不必说甚至IE这种老古董在兼容性测试里偶尔还得请出来。但Selenium也有它的边界新手最容易踩的坑是用它去模拟所有交互。比如拖拽上传、弹窗处理、iframe切换以及一些需要Canvas渲染校验的场景Selenium写起来会很痛苦且极不稳定。如果被测系统的UI大量依赖Canvas、WebGL或者复杂的拖拽逻辑就需要考虑结合图像识别、JavaScript执行或专门的组件级测试方案不能只靠Selenium硬撑。在等待策略上Selenium 4开始内置了更健壮的等待机制但很多人还在用time.sleep这种祖传写法。我后面会在稳定性那章详细展开。3.4 Requests接口测试简洁就是力量接口测试我用的HTTP客户端是requests没有换成异步的httpx。虽然异步在性能上有优势但绝大多数接口自动化场景是顺序发请求、校验响应bottleneck根本不在网络请求那几十毫秒上。requests的API简洁、文档全、生态成熟配合pytest的fixture写接口用例非常顺畅。参数化和数据驱动是接口测试的重头戏pytest有内置的parametrize装饰器可以把大量用例组织成表格数据这一点后面讲数据驱动时我会一起说。3.5 技术选型的最少必要原则很多团队在框架设计阶段就想着引入Docker、Kubernetes、平台化、AI自动生成用例这种一步到位的心态往往会拖垮项目本身。我的建议是先做最小可用再逐步演进。对于一个刚起步的团队一套pytest requests/httpx Selenium allure的技术栈已经足够覆盖大多数接口和UI测试需求。配置管理用YAML数据管理先放JSON/YAML报告用AllureCI集成用GitLab CI或Jenkins。这些工具都经过了大量项目的检验遇到问题时社区资料好找。等用例规模到了几千条、需要分布式执行的时候再思考引入Selenium Grid、多进程执行、平台化也不迟。而且技术栈越少新人上手越快团队成员越容易互相review代码。一个全是黑科技的框架最大的问题不是它跑不跑得起来而是没人敢改它。4. 设计模式在框架中的落地场景从单例到工厂到策略设计模式在测试框架里是个既热门又被滥用的词。我的总体观点是设计模式是用来解决特定重复问题的成熟方案不是为了体现技术水平而存在的概念。下面聊几个在测试框架里真正派上用场、并且我实际落地过的模式。4.1 单例模式管好唯一的浏览器实例UI自动化里一个测试进程通常只需要一个浏览器实例反复创建和销毁既慢又容易出资源问题。单例模式在这里就很有价值。不过Python实现单例时有个容易踩的坑多线程环境下多个线程同时检查实例是否存在就可能重复创建。更好的做法是把driver的创建放在pytest的fixture里用scopesession从框架层面保证唯一性而不必手动实现单例。但如果你是在非pytest环境写普通脚本单例仍然是个好用的方案。4.2 工厂模式管好浏览器的多样化启动需要支持Chrome、Firefox、Edge等多浏览器执行时工厂模式特别好用。工厂接收一个浏览器类型参数返回对应配置好的WebDriver实例。这样用例层只需要说给我一个浏览器不需要关心具体是怎么启动的。class BrowserFactory: staticmethod def create(browser_name: str, headless: bool False): if browser_name chrome: options webdriver.ChromeOptions() if headless: options.add_argument(--headlessnew) return webdriver.Chrome(optionsoptions) if browser_name firefox: options webdriver.FirefoxOptions() if headless: options.add_argument(-headless) return webdriver.Firefox(optionsoptions) raise ValueError(fUnsupported browser: {browser_name})后面要新增一个浏览器只需要在工厂里加一个分支用例层完全不用动。4.3 策略模式管好不同的数据准备和登录方式接口测试经常遇到同一个接口在不同场景下需要不同的数据生成策略比如正常入参、边界值、缺失字段。策略模式很适合这种场景定义一组数据生成的策略运行时动态选择。同理不同环境的登录方式也可能不同有的用账号密码、有的走Token、有的扫码把这些逻辑封装成策略就可以在配置里一键切换。这种设计的好处是新增一种策略不需要改动已有用例只需要扩展新增策略类符合开闭原则。4.4 模板方法模式管好测试生命周期每个用例大致都要经历准备数据 - 执行业务 - 断言结果 - 清理数据的流程。模板方法模式很适合把这种固定流程封装在基类里子类只负责实现每一步的具体内容。比如一个BaseApiTest类定义了execute_test的模板方法内部先调用setup_data、然后call_api、再assert_response、最后cleanup。子类只需要实现这些抽象方法即可。这种模式在处理所有用例都必须记录耗时、都必须截图、都必须做某个通用校验的场景时特别有效。4.5 观察者模式管好失败事件的处理框架里一旦发生用例失败通常需要同时做很多事往报告里写堆栈、截图、发送通知、记录日志。这些行为散落在各个用例里会很烦用观察者模式可以统一管理。pytest的钩子机制本质上就是一种观察者的实现。通过conftest.py里的pytest_runtest_makereport等钩子可以在用例失败时统一触发截图、日志和通知的动作用例本身完全不需要感知这些事。这也是我为什么一直强调基础设施的职责闭环到基础设施里不要让用例层背着走。4.6 使用设计模式的边界感设计模式用得好是加分用不好就是灾难。我见过有人把20多个设计模式硬塞进测试框架里最后每个用例的调用链长达七八层调试一个失败用例要翻五六个文件。这种过度设计的根子是把这里是测试代码给忘了——测试代码的首要价值是可读性和可维护性其次才是所谓的优雅。我给自己定了一条标准同一个问题模式化后新写一个用例的成本必须比模式化之前更低而不是更高。如果一个封装让用例变得更难写了那多半是模式用错了地方。5. 数据驱动与配置分离把变化因素赶出测试代码测试框架设计中最容易被忽略、但实际最影响长期维护的是数据和配置的管理。这一篇里我单独拿出来讲因为大量框架的腐化就始于硬编码。5.1 配置管理的演进从硬编码到环境变量最原始的框架长什么样配置文件是不存在的登录账号直接写在代码里URL直接塞在用例内部连个常量都懒得抽。这种框架换个环境跑就废了。成熟的做法是分三层管理配置默认配置放在yaml或toml文件里包含所有环境的通用参数。环境配置按环境拆分配置文件config.dev.yaml、config.staging.yaml、config.prod.yaml或者用环境变量覆盖关键参数。运行时覆盖通过pytest命令行参数或环境变量动态指定当前要跑的环境。推荐用YAML一是可读性好二是支持嵌套结构三是注释方便团队协作时可以直接在配置里写说明。5.2 测试数据放哪里固定数据与动态数据的分工测试数据的管理是个大学问或者更直白地说是大多数框架崩溃的导火索。固定数据——比如一个已知用户的账号、一个预设的商品ID——适合放在YAML或JSON的测试数据文件里配合parametrize使用一目了然。动态数据——比如每次运行都要新创建一条订单记录、一个唯一的手机号——不适合放在文件里硬编码应该在代码里通过工厂函数生成。这里我会做一个数据工厂模块专门负责生成动态数据并且确保数据在测试结束后能清理掉。5.3 数据工厂让数据准备不拖累用例编写我用一个简单的例子说明数据工厂的思路。假设我们测试一个注册接口每个用例需要一个唯一的手机号import random import time def generate_phone(): 生成一个永远不会重复的中国大陆手机号 prefix 139 suffix str(int(time.time() * 1000))[-8:] return prefix suffix def create_user_via_api(api_client, rolenormal): 通过接口创建一个测试用户返回用户ID和登录token phone generate_phone() resp api_client.post(/api/users, json{ phone: phone, role: role, }) assert resp.status_code 201 return resp.json()数据工厂的核心要求是提供的数据好用、干净、可控。好用是调用简单干净是数据有唯一性约束不会互相污染可控是数据创建后在用例结束时有明确的清理机制。这个模块设计好了用例里就几乎不再出现一堆造数代码了。5.4 幂等性设计一条用例可以重复跑不搞脏环境接口自动化和UI自动化里最让人头疼的问题之一就是用例反复执行导致数据堆积或者状态冲突。比如你创建了订单第一次跑成功了第二次再跑订单号变了但之前的关联数据还在。用例之间互相影响随机失败就来了。所以我在框架设计里会把幂等性当成一条硬性要求来推。具体做法是每个用例开始时先检查目标数据是否存在存在就复用或清理掉重建。唯一标识用动态值如时间戳、UUID而不是写死。用户的注册类用例统一用动态手机号避免重复注册冲突。有状态的用例比如查询订单列表断言时关注自己产生的数据而不是全表数据。幂等性不是靠某一段代码解决而是要在写用例时养成重复执行也能通过的意识。这点可以从框架的Wiki约定和code review上双管齐下。5.5 环境切换五秒钟切换一套环境框架要有一键切换环境的能力这是所有跨环境执行dev、test、staging、生产的基础。我会在pytest命令行参数层面加上一个环境选项并在conftest里根据该选项加载对应配置。pytest --envstaging tests/test_order_flow.py配合allure报告直接在报告标题里带上环境信息这样排查问题时就不会搞混环境了。6. 稳定性是第一生命力等待、重试、隔离与清理前面提到过自动化框架最大的敌人是随机失败。这一章我集中讲我治理稳定性的四个手段每个都是实战中验证过的。6.1 等待策略永远不要再写time.sleep新手写UI自动化几乎人手一个time.sleep(5)好像多睡几秒就万事大吉。实际上强制等待不仅拖慢执行速度而且在一定负载下依然不稳定——页面加载快时浪费了时间加载慢时又不够用。正确的思路是显式等待轮询等待某个条件成立直到超时。from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 等待登录按钮可点击 WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, login-btn)) )显式等待背后是轮询超时可配置间隔的循环轮询之间休息一小段固定时间条件满足就立即返回是真正的及时反馈策略。接口测试中类似的做法是不断请求某个异步任务的状态直到返回终态。这里要注意区分等待的目的是条件满足不是时间足够。6.2 重试机制不是所有失败都值得重试失败到底该不该重试我的判断标准是只有环境因素导致的失败才适合重试断言失败绝对不应该重试。环境因素包括网络抖动、服务正在重启、页面元素偶发加载慢。断言失败代表产品逻辑出了问题重试一百次也没用反而把问题掩盖了。pytest里用pytest-rerunfailures插件可以做失败重试但要设置好重试次数和重试间隔。我通常把retry次数设为1到2重试间隔几秒钟。重试太多次会掩盖真实问题也让报告失去可信度。6.3 用例隔离从数据、环境、执行顺序三个层面下手用例隔离的意思是任何一条用例的失败都不应该影响其他用例的执行结果。三个层面要同时做到数据隔离每条用例使用的数据尽量是独立的动态工厂生成不共享可变数据。如果你必须共享数据要保证共享的数据是只读的。环境隔离测试执行时依赖的服务要稳定可用。团队里经常出现的环境被其他测试搞挂了长期看要靠环境自治来解决比如每个测试任务独立拉起一套测试环境用Docker做这件事非常划算。执行顺序隔离框架要支持随机顺序执行、按依赖分组执行但不能依赖用例文件名的天然顺序。依赖特定顺序才能通过的用例本身就是设计不良的信号。6.4 flaky用例要做标记不要拖垮整体信号当一套框架用例数量上了几百上千条后总会冒出几条偶尔红、偶尔绿的用例。对这种用例我的处理步骤是先在Allure标注flaky标签把它从核心门禁用例中摘出来不让它影响滚动发布然后专门排一个任务去稳定它比如用try/except捕获现场信息实在修不好的跟产品和技术讨论是不是用例本身设计有问题——比如一个动画的时延不受控可能需要结合接口等待来替代UI等待。这里要特别强调千万不要把所有flaky用例直接跳过。跳过意味着风险没人看见等业务出问题时才发现自动化根本没覆盖到那才是真的危机。6.5 超时治理给每条用例装上闹钟有时候一条用例卡住整个测试任务就卡住。我给框架加了一层用例超时机制pytest-timeout插件可以给每条用例设置最大执行时间超时直接标记失败。这样即使外部依赖挂了也能在预设时间内结束任务让整个反馈链路保持稳定。我一般把超时时间设在正常耗时的1.5到2倍比如一条用例正常需要5秒就设10秒超时。太紧会导致高峰期的无辜失败太松又起不到卡控作用。7. 报表体系与反馈链路让测试结果真正驱动决策框架最终的目的是让结果有人看、有人信、有人用。所以最后一步是把结果包装成团队愿意消费的形式并且把发现问题 - 修复问题的闭环跑通。7.1 一份好的报告要服务三类人报告不是只给测试看的它至少要服务三类人测试工程师需要的是失败现场——日志、截图、堆栈、请求响应、失败原因能快速定位并修复。开发工程师需要的是问题线索——哪个接口、哪个页面、什么前置条件下出错了。管理者和产品需要的是整体信号——用例规模、通过率、耗时、关键业务场景是否健康。一份报告如果不能同时照顾这三类人的需求就会被不同角色各自吐槽。这也是我一直推荐Allure的原因它的结构设计天然兼顾了这三层信息。7.2 Allure报告的使用经验Allure是我在Python和Java项目里都一直在用的报告工具核心几个点分享给大家报告里的test story和feature标签不只是分类功能更是业务人员和开发沟通的语言。我会在框架的Wiki里约定统一的标签规范。失败报告里要尽量带上关键步骤的日志和截图。对于UI测试截图最好不只截失败那一刻而是失败前后的连续帧能辅助判断问题的前后链路。import allure allure.feature(订单流程) allure.story(创建订单) def test_create_order(api_client): with allure.step(准备商品数据): product prepare_product() with allure.step(调用创建订单接口): resp api_client.post(/api/orders, json{product_id: product[id]}) with allure.step(校验订单创建成功): assert resp.status_code 201step会把用例拆成清晰的步骤失败时一看就知道卡在哪一步不用从整个堆栈里猜。7.3 失败信息要能做到自解释这是我在团队里反复强调的一个要求一条用例失败后其他同事从报告里能否不看代码就判断出大概原因。要做到这点失败通知和日志里必须包含当前执行的环境和执行时间请求的URL、方法和Body对于接口测试返回的响应状态码和关键字段失败的断言信息比如期望值和实际值关键步骤的截图和日志片段。如果一个失败报告给到同事对方还要问这条路是测什么的那报告的设计就算不上合格。7.4 结果通知把测试放进团队的工作流报告生成后的通知环节我建议直接跟团队的IM机器人打通。执行完毕往群里推送结果卡片里面包含通过率、失败用例列表、报告链接。这样即使没有主动去看报告平台测试结果也会主动触达所有人。需要特别注意的是推送内容要克制、信息密度要高。不要一失败就刷几十条消息最好汇总成一条卡片。失败用例多时附上前5到10个失败名称与链接即可详情去报告里看。7.5 用指标度量框架本身框架设计得好不好不能只靠感觉我用以下几个指标定期评估通过率趋势近30天用例通过率是否稳定在90%以上。假阳性率重试后通过且最终确认为环境/代码非缺陷的比例这个比例太高说明框架的等待和数据隔离有问题。平均修复时间从用例失败到修复用例或定位缺陷的平均耗时能反映报告质量。用例增量每周新增用例和失效用例的差值用于观察用例库是否健康成长。维护耗时团队每周花在改框架和修用例上的时间占比长期超过30%就要警惕了。这几项指标我会放在框架文档里定期回看它们比任何一句框架很好用都更客观。我在实际设计框架的过程中最深的体会是框架不是写完就完事的它是一个持续演化的活系统。我每季度会干一件事——集中删代码删除那些三个月没人打开过的用例、删除冗余的封装、简化绕了三层的抽象。删完之后你会发现框架依然跑得好但维护成本下降了一大截。最后再分享一个小技巧框架设计时始终保留一个最笨的入口。哪怕你做了平台、做了配置中心、做了各种自动生成也要保证一个懂基础编程的人能在半小时内手动跑通一条用例。这个最笨的入口往往是框架在最困难时期还能存活下去的救命稻草。
返回列表