gpt4 book ai didi

unit-testing - 为磁盘上的文件对生成单元测试

转载 作者:行者123 更新时间:2023-11-29 08:16:02 24 4
gpt4 key购买 nike

一些问题(例如 How can I create parameterized tests in Rust?)涉及使用宏在 Rust 中创建参数化单元测试。我需要使用此技术来 generate a pair of unit tests for every pair of input files in a directory .单元测试本身只是调用一个简单的函数:

fn check_files(path1: &str, path2: &str, msg: &str) {
assert!(true, "FAILURE: {}: {} and {}.", msg, path1, path2);
}

我使用 lazy_static 生成输入文件列表:

#![feature(plugin)]
#![plugin(interpolate_idents)]

extern crate glob;
#[macro_use]
extern crate lazy_static;

use glob::glob;

lazy_static! {
/// Glob all example files in the `tests/` directory.
static ref TEST_FILES: Vec<String> = glob("tests/*.java")
.expect("Failed to read glob pattern")
.into_iter()
.map(|res| res.unwrap().to_str().unwrap().to_string())
.collect::<Vec<String>>();
}

然后宏使用 interpolate idents crate 连接标识符以创建单元测试名称:

#[test]
fn test_glob_runner() {
// Define unit tests for a single pair of filenames.
macro_rules! define_tests {
($name1:tt, $name2:tt, $fname1:expr, $fname2:expr) => ( interpolate_idents! {
#[test]
fn [test_globbed_ $name1 _ $name2 _null]() {
check_files($fname1, $fname2, "null test");
}
#[test]
fn [test_globbed_ $name1 _ $name2 _non_null]() {
check_files($fname1, $fname2, "non-null test");
}
} )
}
// Write out unit tests for all pairs of given list of filenames.
macro_rules! test_globbed_files {
($d:expr) => {
for fname1 in $d.iter() {
for fname2 in $d.iter() {
// Remove directory and extension from `fname1`, `fname2`.
let name1 = &fname1[6..].split(".").next().unwrap();
let name2 = &fname1[6..].split(".").next().unwrap();
|| { define_tests!(name1, name2, fname1, fname2) };
}
}
}
}
// Test all pairs of files in the `tests/` directory.
test_globbed_files!(TEST_FILES);
}

这会产生以下编译器错误:

error: expected expression, found keyword `fn`
--> tests/test.rs:14:13
|
14 | fn [test_globbed_ $name1 _ $name2 _null]() {
| ^^

这个错误消息对我来说意义不大,尤其是因为 define_tests 宏类似于 code here .但是,我不确定是否真的可以在单元测试名称中使用 name1name2

有一个complete but simplified example project on GitHub ,只需克隆并运行 cargo test 即可查看编译器错误。

最佳答案

您在参数化测试中尝试的方法的问题是 TEST_FILES 仅在运行时计算,而您希望能够在编译时使用它来消除几个 # [测试] 函数。

为了完成这项工作,您将需要一些方法在编译时计算 TEST_FILES。一种可能性是通过一个构建脚本,该脚本在构建时迭代 glob 并将 #[test] 函数写入一个可以包含在您的测试目录中的文件。

Cargo.toml 中:

[package]
# ...
build = "build.rs"

[build-dependencies]
glob = "0.2"

build.rs中:

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

extern crate glob;
use glob::glob;

fn main() {
let test_files = glob("tests/*.java")
.expect("Failed to read glob pattern")
.into_iter();

let outfile_path = Path::new(&env::var("OUT_DIR").unwrap()).join("gen_tests.rs");
let mut outfile = File::create(outfile_path).unwrap();
for file in test_files {
let java_file = file.unwrap().to_str().unwrap().to_string();

// FIXME: fill these in with your own logic for manipulating the filename.
let name = java_file;
let name1 = "NAME1";
let name2 = "NAME2";

write!(outfile, r#"
#[test]
fn test_globbed_{name}_null() {{
check_files({name1}, {name2}, "null test");
}}
#[test]
fn test_globbed_{name}_non_null() {{
check_files({name1}, {name2}, "non-null test");
}}
"#, name=name, name1=name1, name2=name2).unwrap();
}
}

tests/tests.rs中:

include!(concat!(env!("OUT_DIR"), "/gen_tests.rs"));

关于unit-testing - 为磁盘上的文件对生成单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49056579/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com