bem类选择器(如.search-form__submit)是最可靠的dom定位方式,因其语义明确、作用域隔离;而cy.get('button')不可用,因标签选择器会匹配所有button元素,导致误命中、跨表单冲突及隐藏元素干扰。

直接用 cy.get('.search-form__submit') 这类 BEM 类选择器,是目前最可靠、最省事的 DOM 定位方式——前提是类名写对、没被构建工具意外改写,且 modifier 没被单独滥用。
为什么 cy.get('button') 在真实项目里基本不可用
标签选择器等于放弃控制权:button 会匹配页面上所有 <button></button>,包括 Ant Design 的 Button、自定义封装的 <mybutton></mybutton> 渲染出的底层 button,甚至被 v-show 隐藏但仍在 DOM 中的按钮。
-
button[type="submit"]依然可能跨表单误命中,无法区分“搜索表单提交”和“注册表单提交” -
cy.contains('提交')依赖可见文本,但按钮文字常动态变化(“提交中…”、“重试”),或被 i18n 替换,定位立刻断裂 - 浏览器渲染层不保证元素顺序或层级唯一性,仅靠标签名无法建立稳定映射
怎样写出真正可测的 BEM 类名
BEM 类名不是写得长就有用,关键在于结构合规、语义完整、不退化:
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- modifier 必须与 block 或 block__element 同时存在:真实 DOM 是
<button class="button button--disabled"></button>,而不是只写button--disabled;单独查cy.get('.button--disabled')必然失败 - 禁用含空格的选择器:
.modal--open .modal__content已退化为后代选择器,破坏作用域隔离,PostCSS 插件如postcss-bem-linter应配置规则拦截 - 禁止
.card__title strong这类依赖标签的选择器——它让card__title--highlighted在不同 HTML 结构下行为不一致,根本无法构造稳定断言 - block 名需具象,避免泛化:用
search-form,不用form;多人协作时建议加业务前缀,如checkout-button而非react-button
测试脚本里怎么正确命中 BEM 类名
核心原则:验证类名是否存在,而非样式是否生效。用 classList.contains,别碰 getComputedStyle:
- Jest + RTL:
screen.getByRole('button', { name: /submit/ }).classList.contains('search-form__submit--loading') - Cypress:
cy.get('button').should('have.class', 'search-form__submit--loading'),避免.should('have.css', 'opacity', '0.5') - 快照测试中,
expect(container).toMatchSnapshot()能天然捕获search-form__submit search-form__submit--loading这类组合,无需额外逻辑 - 若用了 CSS Modules,确保测试环境启用
localsConvention: 'camelCaseOnly',并用styles['search-form__submit']导出类名,或统一 fallback 到data-test属性
真正难测的不是单个类名,而是 modifier 组合互斥性——比如 search-form__submit--loading 和 search-form__submit--disabled 同时存在时,样式是否按预期覆盖。这必须显式构造多状态组合来验证,不能只测单一 modifier。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










