Rust集成测试中基准路径设置的问题
解决方案:添加根目录参数实现隔离的集成测试
要解决测试时目录环境互相干扰的问题,核心是让程序支持指定扫描根目录,而非硬编码当前工作目录。这样每个测试可以独立传入临时目录路径,无需修改全局工作目录。
1. 修改程序代码支持根目录参数
首先调整src/main.rs,给命令行添加可选的根目录参数,并优化文件扫描逻辑:
更新命令行参数定义
#[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { /// File patterns to process #[arg(required = true)] include: Vec<PathBuf>, /// Root directory to start scanning from (default: current directory) #[arg(short, long, default_value = ".")] root: PathBuf, }
调整文件扫描逻辑
修改list_files函数,接收根目录参数,使用相对于根目录的路径进行glob匹配:
fn list_files(root: PathBuf, include_patterns: Vec<PathBuf>) -> Result<Vec<PathBuf>> { let mut walk = WalkBuilder::new(&root); walk.hidden(true).ignore(true).git_global(true); let include_patterns: Vec<Pattern> = create_patterns(include_patterns)?; let mut matching_files = Vec::new(); for entry in walk.build() { let entry = entry.context("Failed to read directory entry")?; if entry.file_type().map_or(false, |ft| ft.is_file()) { let path = entry.path(); // 获取相对于根目录的路径,用于匹配glob模式 let relative_path = path.strip_prefix(&root).unwrap_or(path); if matches_patterns(&include_patterns, relative_path) { matching_files.push(path.to_path_buf()); } } } Ok(matching_files) }
更新main函数调用
fn main() { let args = Args::parse(); let files = list_files(args.root, args.include); println!("Found {:?} file(s).", files.unwrap()); }
2. 编写隔离的集成测试
修改tests/cli.rs,创建临时目录结构后,通过--root参数指定扫描目录,验证各种glob匹配场景:
测试单个文件匹配
#[test] fn finds_single_json_file() -> Result<(), Box<dyn std::error::Error>> { let temp_dir = TempDir::new()?; let temp_path = temp_dir.path(); // 创建测试文件 fs::write(temp_path.join("sample.json"), r#"{"a":1}"#)?; fs::write(temp_path.join("sample.txt"), "not json")?; let mut cmd = Command::cargo_bin("repro")?; cmd.arg("--root").arg(temp_path).arg("sample.json"); cmd.assert() .success() .stdout(predicate::str::contains("Found [\"") .and(predicate::str::ends_with("sample.json\"] file(s)."))); Ok(()) }
测试递归匹配子目录文件
#[test] fn finds_all_json_files_recursively() -> Result<(), Box<dyn std::error::Error>> { let temp_dir = TempDir::new()?; let temp_path = temp_dir.path(); // 构建嵌套目录结构 let sub_dir = temp_path.join("data"); fs::create_dir(&sub_dir)?; fs::write(sub_dir.join("nested.json"), r#"{"b":2}"#)?; fs::write(temp_path.join("top.json"), r#"{"a":1}"#)?; fs::write(sub_dir.join("readme.md"), "markdown content")?; let mut cmd = Command::cargo_bin("repro")?; cmd.arg("--root").arg(temp_path).arg("**/*.json"); let output = cmd.output()?; let stdout = String::from_utf8(output.stdout)?; assert!(stdout.contains("top.json")); assert!(stdout.contains("nested.json")); assert!(!stdout.contains("readme.md")); assert!(stdout.contains("Found 2 file(s)")); Ok(()) }
方案优势
- 测试隔离:每个测试使用独立的临时目录,无需修改全局工作目录,彻底避免测试间互相干扰
- 程序灵活性:用户可以手动指定扫描根目录,提升工具的实用性
- 匹配准确性:使用相对于根目录的路径进行glob匹配,完全符合用户对glob模式的使用预期
内容的提问来源于stack exchange,提问作者tdranv
相关产品推荐
相关产品推荐

