30 个版本

0.8.2 2024年7月18日
0.8.1 2024年3月20日
0.8.0 2024年1月31日
0.7.5 2023年11月3日
0.3.2 2019年7月31日

#51 in 开发工具

Download history 2219/week @ 2024-04-19 2113/week @ 2024-04-26 2008/week @ 2024-05-03 1904/week @ 2024-05-10 2421/week @ 2024-05-17 2513/week @ 2024-05-24 2189/week @ 2024-05-31 2514/week @ 2024-06-07 2330/week @ 2024-06-14 2441/week @ 2024-06-21 2104/week @ 2024-06-28 2261/week @ 2024-07-05 2357/week @ 2024-07-12 2381/week @ 2024-07-19 2321/week @ 2024-07-26 2455/week @ 2024-08-02

9,819 每月下载量

Apache-2.0/MIT

79KB
1.5K SLoC

lang_tester

此包提供了一个简单的语言测试框架,旨在帮助测试编译器和虚拟机等事物。它允许用户表达简单的测试,以检查进程的成功/失败以及 stderr/stdout,包括直接在源文件中嵌入这些测试。它松散地基于 compiletest_rs 包,但更简单(因此有时功能较弱),并且设计用于测试非 Rust 语言。

例如,一个 Rust 语言测试器,大致类似于 compiletest_rs,如下所示

use std::{env, fs::read_to_string, path::PathBuf, process::Command};

use lang_tester::LangTester;
use tempfile::TempDir;

fn main() {
    // We use rustc to compile files into a binary: we store those binary files
    // into `tempdir`. This may not be necessary for other languages.
    let tempdir = TempDir::new().unwrap();
    LangTester::new()
        .test_dir("examples/rust_lang_tester/lang_tests")
        // Only use files named `*.rs` as test files.
        .test_path_filter(|p| p.extension().and_then(|x| x.to_str()) == Some("rs"))
        // Treat lines beginning with "#" inside a test as comments.
        .comment_prefix("#")
        // Extract the first sequence of commented line(s) as the tests.
        .test_extract(|p| {
            read_to_string(p)
                .unwrap()
                .lines()
                // Skip non-commented lines at the start of the file.
                .skip_while(|l| !l.starts_with("//"))
                // Extract consecutive commented lines.
                .take_while(|l| l.starts_with("//"))
                .map(|l| &l[COMMENT_PREFIX.len()..])
                .collect::<Vec<_>>()
                .join("\n")
        })
        // We have two test commands:
        //   * `Compiler`: runs rustc.
        //   * `Run-time`: if rustc does not error, and the `Compiler` tests
        //     succeed, then the output binary is run.
        .test_cmds(move |p| {
            // Test command 1: Compile `x.rs` into `tempdir/x`.
            let mut exe = PathBuf::new();
            exe.push(&tempdir);
            exe.push(p.file_stem().unwrap());
            let mut compiler = Command::new("rustc");
            compiler.args(&["-o", exe.to_str().unwrap(), p.to_str().unwrap()]);
            // Test command 2: run `tempdir/x`.
            let runtime = Command::new(exe);
            vec![("Compiler", compiler), ("Run-time", runtime)]
        })
        .run();
}

这定义了一个语言测试器,它使用给定目录中的所有 *.rs 文件作为测试文件,对这些文件运行两个测试命令: Compiler(即 rustc);和 Run-time(编译后的二进制文件)。

然后用户可以编写以下这样的测试文件

// Compiler:
//   stderr:
//     warning: unused variable: `x`
//       ...unused_var.rs:12:9
//       ...
//
// Run-time:
//   stdout: Hello world
fn main() {
    let x = 0;
    println!("Hello world");
}

上面的文件包含 4 个有意义的测试,两个由用户指定,两个由默认值隐含: Compiler 应该成功(例如,在 Unix 上运行时返回一个 0 退出代码),并且其 stderr 输出应警告关于第 12 行的未使用变量;并且生成的二进制文件应该在 stdout 上成功输出 Hello world

Cargo 集成。

使用 lang_tester 创建的测试可以作为现有测试套件的一部分使用,并可以使用 cargo test 命令运行。例如,如果运行语言测试的 Rust 源文件是 lang_tests/run.rs,则将以下内容添加到您的 Cargo.toml 中

[[test]]
name = "lang_tests"
path = "lang_tests/run.rs"
harness = false

依赖关系

~3–11MB
~101K SLoC