You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust项目分离lib.rs与main.rs的优势及测试组织方式咨询

拆分main.rs与lib.rs并非社区隐性约定,有明确实际收益

别觉得这是无意义的规矩,对你做TDD开发Web服务器的场景来说好处非常直接:

  • 测试隔离性更好:把路由解析、请求处理、响应生成这些核心逻辑挪到lib.rs后,写测试不需要真的启动服务、绑定端口,直接调用对应函数就能测逻辑正确性,测试跑的速度快,也不会因为端口占用、环境依赖导致测试不稳定。如果所有代码都堆在main.rs里,所有测试都要跟着main的二进制入口走,没法绕开启动流程单独测内部逻辑,写小粒度测试的时候非常别扭。
  • 代码复用更方便:哪怕你现在只打算做单二进制的Web服务器,后续要是想加个配套的命令行管理工具、离线数据迁移脚本、压测小工具,都可以直接依赖lib里的核心逻辑,不用复制粘贴代码。逻辑全写在main.rs里的话,同项目的其他二进制根本没法引用这些代码。
  • 编译效率更高:Rust的编译缓存是按crate单元生效的,你把核心逻辑全放在lib,main.rs只留极薄的一层启动骨架(解析配置、调用lib的run方法、处理顶层错误),后续改启动相关的代码时,不需要重新编译整个核心库的代码,项目越大这个收益越明显。

一个标准的薄main.rs长这样:

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = my_web_server::load_config()?;
    my_web_server::start_server(config)?;
    Ok(())
}
测试放置位置没有强制标准,按测试粒度选就行

不存在“必须单独建tests目录”的要求,社区普遍是两种方式搭配用,各有适用场景:

  • 每个.rs文件末尾加#[cfg(test)] mod tests模块:这部分是单元测试,因为测试模块是当前源码模块的子模块,可以直接访问模块内的私有函数、私有结构体,不需要为了测试特意把内部成员改成pub破坏封装。写单个函数、单个组件的小粒度测试时用这个方式最方便,TDD写逻辑前先写的测试基本都放这里。
  • 项目根目录的tests/目录:这部分是集成测试,目录下每个.rs文件都会被编译成独立的测试crate,只能调用lib对外暴露的公开接口,完全模拟外部用户调用你的代码的场景。适合写多组件联动的流程测试、端到端测试,比如测“发送GET请求到指定路径返回符合预期的响应”这种完整链路逻辑,这类测试统一放在tests目录归集就好。

简单说就是小粒度测内部逻辑挨着源码写,大粒度测公开接口、完整流程放tests目录,不用为了凑结构硬把所有测试都塞到同一个地方。

内容的提问来源于stack exchange,提问作者yjlee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 02:51:58