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

未预先执行cargo build时Rust CLI应用测试失败的解决办法

问题

我正在对一款纯Rust CLI应用做单元测试,执行以下命令时会弹出找不到二进制文件的错误:

cargo clean
cargo test --release

但换成下面的命令就能正常运行:

cargo clean
cargo build --release
cargo test --release

有没有办法让Cargo自动先把二进制应用构建完成,再执行测试?

测试代码
#[cfg(test)]
pub mod tests {
    use std::process::Command;

    use assert_cmd::prelude::{CommandCargoExt, OutputAssertExt};
    use predicates::prelude::predicate;

    #[test]
    fn test_that_cli_app_produces_result() -> Result<(), Box<dyn std::error::Error>> {
        let mut cmd = Command::cargo_bin("fastsim-cli")?;
        let mut cyc_file = project_root::get_project_root().unwrap();
        cyc_file.push("../fastsim/resources/cycles/udds.csv");
        assert!(cyc_file.exists());
        let mut veh_file = project_root::get_project_root().unwrap();
        veh_file.push("../fastsim/resources/vehdb/2012_Ford_Fusion.yaml");
        assert!(veh_file.exists());

        cmd.args([
            "--cyc-file",
            cyc_file.to_str().unwrap(),
            "--veh-file",
            veh_file.to_str().unwrap(),
        ]);
        cmd.assert()
            .success()
            .stdout(predicate::str::contains("32.4"));

        Ok(())
    }
}
解决方案

问题根源在于cargo test默认只会构建测试相关代码及依赖,不会自动触发CLI二进制目标的构建。以下几种方法可以解决这个问题:

方法1:测试时指定构建二进制目标

执行测试命令时,明确告诉Cargo要先构建对应的二进制:

cargo test --release --bin fastsim-cli

这条命令会优先构建fastsim-cli二进制,再运行测试。

方法2:修改Cargo.toml关联测试与二进制

在Cargo.toml中给测试目标添加对二进制的依赖,让Cargo自动先构建二进制:

[[test]]
name = "your_test_module"  # 对应代码中的测试模块名
dependencies = ["fastsim-cli"]

如果测试写在lib crate里,也可以直接在[lib]区块下添加依赖:

[lib]
name = "fastsim_lib"
path = "src/lib.rs"
dependencies = ["fastsim-cli"]

方法3:使用--all-targets参数构建所有目标

这个参数会让Cargo构建所有类型的目标(二进制、库、测试等)后再执行测试:

cargo test --release --all-targets

缺点是会构建所有目标,可能比只构建需要的二进制更耗时。

方法4:测试代码中手动触发构建

在测试开头添加构建命令,强制Cargo先生成二进制:

#[test]
fn test_that_cli_app_produces_result() -> Result<(), Box<dyn std::error::Error>> {
    // 先构建release版本的二进制
    Command::new("cargo")
        .args(["build", "--release", "--bin", "fastsim-cli"])
        .status()?;
    
    // 后续测试代码不变
    let mut cmd = Command::cargo_bin("fastsim-cli")?;
    let mut cyc_file = project_root::get_project_root().unwrap();
    cyc_file.push("../fastsim/resources/cycles/udds.csv");
    assert!(cyc_file.exists());
    let mut veh_file = project_root::get_project_root().unwrap();
    veh_file.push("../fastsim/resources/vehdb/2012_Ford_Fusion.yaml");
    assert!(veh_file.exists());

    cmd.args([
        "--cyc-file",
        cyc_file.to_str().unwrap(),
        "--veh-file",
        veh_file.to_str().unwrap(),
    ]);
    cmd.assert()
        .success()
        .stdout(predicate::str::contains("32.4"));

    Ok(())
}

这种方法会增加冗余构建,不如前几种优雅,适合临时场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:44:16