HTML国际化测试必须验证lang属性、charset、DOM结构与动态行为协同生效,需在CI中自动运行npx html-validate校验根lang和meta charset,用Playwright检查data-i18n键与语言包匹配性,并断言placeholder、验证消息、日期格式等动态内容随语言实时切换。

HTML国际化测试不是“看看文字有没有变”,而是验证语言属性、编码、DOM结构和动态行为是否协同生效;必须进CI自动跑,靠人点开不同语言页面检查不可持续。
lang属性和charset是否被正确注入
很多项目用JS动态改<html lang="zh">,但SSR或构建插件可能覆盖它;Content-Type响应头缺失或meta charset位置错误会导致中文乱码,但浏览器常自动容错,肉眼难发现。
- 在CI中用
npx html-validate加自定义规则校验:"attr-req-lang": true强制根元素有lang,"meta-charset": true确保<meta charset="utf-8">存在且在<title>前 - 用
requests-html写轻量脚本抓取各语言路径(如/zh/、/en/),断言r.html.find("html", first=True).attrs.get("lang")匹配预期值 - 避免只查
<meta>标签——有些构建工具(如Vite)会把charset注入到JS中动态插入,源码里看不到,得测真实HTTP响应头
data-i18n属性与翻译键是否一一对应
前端用data-i18n="login.submit"标记文本,但键名拼错、JSON里漏定义、或JS加载失败时,页面就显示原始键而非fallback文本,这类问题本地开发很难复现。
- 用
Playwright启动多语言环境(locale: "zh-CN"),遍历所有[data-i18n]元素,调用element.evaluate(el => el.dataset.i18n)提取键名,再比对语言包JSON文件是否包含该键 - 禁止在HTML里写
data-i18n="user.name.first"这种嵌套键——i18n库(如i18next)默认不展开,应扁平化为"user_first_name" - 测试时清空
localStorage并禁用网络,验证fallback逻辑:若语言包加载失败,是否回退到data-i18n-fallback或默认语言文本
表单占位符、验证消息、日期格式是否随语言实时切换
静态文本替换容易,但input placeholder、setCustomValidity()提示、Intl.DateTimeFormat输出这些动态内容,常因初始化时机或作用域问题失效。
立即学习“前端免费学习笔记(深入)”;
- 用
MutationObserver监听input元素的placeholder属性变化,在语言切换后1秒内检查是否更新,避免依赖setTimeout轮询 - 触发表单提交后,检查
element.validationMessage(不是getAttribute("validationMessage"))是否为当前语言的错误文案 - 对日期输入框,用
new Intl.DateTimeFormat(navigator.language).format(new Date())生成期望值,再比对input.valueAsDate格式化后的显示(注意Chrome和Firefox对type="date"的渲染差异)
CI中如何避免“假通过”
最常踩的坑是只测主语言页(如/),或扫描命令路径写成src/**/*.html却没排除微前端子应用的入口HTML——那些本就不该有lang或标题,反而让校验失败。
-
html-validate配置里用"ignore": ["src/micro-fe/**", "public/iframe-*.html"]精准排除非主站页面 - CI job分两步:先用
curl -I https://staging.example.com/zh/ | grep "content-language"确认响应头正确,再跑DOM级验证 - 别信
document.querySelector("html").lang——它返回JS执行后的值,而国际化测试要验证的是服务端吐出的初始HTML是否合规
真正麻烦的不是写测试代码,而是确定哪些语言路径算“有效测试目标”:比如/404.html要不要校验lang?/robots.txt重定向页是否纳入扫描?规则必须和路由配置、CDN缓存策略对齐,否则自动化只是制造噪音。



















