Yew 应用应该如何设计测试策略?
Yew 应用的测试要分两层看:纯 Rust 逻辑尽量放在普通单元测试里跑,涉及组件渲染、浏览器 API、事件交互的部分再放到 Wasm 或端到端测试里。这样做的原因很现实:浏览器测试慢、依赖环境多,而业务函数、状态 reducer、数据转换逻辑其实不需要浏览器。
比较稳的策略是“底层多测、上层少测、关键路径必测”。底层用 cargo test 覆盖解析、状态流转和工具函数;组件层用 wasm-bindgen-test 或 SSR 渲染验证输出;真正依赖点击、输入、路由和网络的流程交给 Playwright 这类 E2E 工具。
Yew 测试从哪里开始?
先把可测试逻辑从组件里拆出来。比如表单校验、接口响应转换、列表过滤,不要全部塞进 html! 宏附近。拆出来之后,普通 Rust 测试就能覆盖大部分分支,速度快,也不需要启动浏览器。
rustpub fn normalize_name(input: &str) -> Option<String> { let name = input.trim(); if name.is_empty() { None } else { Some(name.to_string()) } } #[test] fn trims_user_name() { assert_eq!(normalize_name(" Alice "), Some("Alice".into())); assert_eq!(normalize_name(" "), None); }
涉及组件渲染时,可以用 wasm-bindgen-test 在真实浏览器或 headless 环境里跑。配置通常放在测试文件顶部,CI 里再指定浏览器。
rustuse wasm_bindgen_test::*; wasm_bindgen_test_configure!(run_in_browser); #[wasm_bindgen_test] fn browser_env_is_ready() { assert!(web_sys::window().is_some()); }
Yew 测试的关键不是工具越多越好,而是把不同风险放到合适层级。普通 Rust 测试兜住逻辑,Wasm 测试兜住浏览器边界,E2E 测试兜住主流程,这样速度和信心比较平衡。
追问
单元测试和组件测试的边界怎么划?
只要逻辑不依赖 DOM,就优先写普通单元测试。比如 reducer、权限判断、价格格式化、API DTO 转换,都应该从 Yew 组件里抽出去。组件测试只验证组件是否把状态、属性和事件正确接起来,不要用它覆盖所有业务分支。边界划清以后,测试会更快,也更不容易因为 UI 文案改动而大面积失败。
wasm-bindgen-test 适合测什么?
它适合测试必须运行在 Wasm 或浏览器环境里的代码,比如 web_sys、定时器、LocalStorage、组件挂载后的副作用。它不适合承担全部测试,因为启动浏览器成本高,失败日志也比普通 Rust 测试难读。取舍上,可以把它放在“少而关键”的位置。常见踩坑是本地能跑,CI 里缺浏览器或驱动,最后需要在 workflow 里显式安装 Firefox 或 Chrome。
异步请求和 Mock 应该怎么做?
最好把请求层封装成 trait 或独立函数,让组件只依赖抽象结果,而不是直接在组件里到处调用 gloo_net::http::Request。单元测试里用 fake client 返回固定数据,E2E 再连测试环境或 mock server。这样能避免网络抖动污染组件测试结果。边界是不要 mock 得太过头,如果连序列化字段名都绕过了,线上接口变更时测试也发现不了。
rust#[derive(Clone, PartialEq)] pub enum LoadState<T> { Idle, Loading, Ready(T), Failed(String) } pub fn user_label(state: &LoadState<String>) -> String { match state { LoadState::Ready(name) => format!("User: {name}"), LoadState::Failed(e) => format!("Error: {e}"), _ => "Loading".into(), } }
Yew 项目需要端到端测试吗?
需要,但不要太多。E2E 测试适合覆盖登录、核心表单提交、关键路由跳转、支付或发布这类主链路。它的价值是发现组件之间、路由、网络和浏览器行为组合后的问题。代价是慢、脆、维护成本高,所以不适合把每个按钮都写成 E2E。比较好的边界是:失败会直接影响业务闭环的流程,才放进 E2E。
CI 里测试 Yew 有哪些配置坑?
最常见的是工具链没装全,Rust、wasm target、wasm-pack、浏览器缺一个都会失败。其次是缓存配置不当,target 和 cargo registry 没缓存会让 CI 非常慢。另一个坑是把所有测试塞进同一个 job,导致普通单测也被浏览器环境拖慢。可以拆成两个 job:一个跑 cargo test,一个跑 Wasm/browser 测试。
yaml- uses: actions-rs/toolchain@v1 with: toolchain: stable target: wasm32-unknown-unknown - run: cargo test - run: cargo install wasm-pack - run: wasm-pack test --headless --firefox