autozig 0.1.2

Safe autogenerated interop between Rust and Zig
Documentation
# Zig Test Integration Guide

AutoZig 现在支持将 Zig 的单元测试集成到 Rust 的测试框架中!

## 功能概述

这个功能允许你:
- `.zig` 文件中编写 Zig 测试(使用 `test` 块)
-`build.rs` 中自动编译这些测试为可执行文件
- 从 Rust 的 `#[test]` 函数中调用和验证 Zig 测试
- 集成到标准的 `cargo test` 工作流中

## 工作原理

1. **编译阶段**(build.rs):
   - `autozig_build::build_tests()` 扫描指定目录中的所有 `.zig` 文件
   - 使用 `zig test` 命令编译每个文件的测试
   - 生成独立的测试可执行文件(命名为 `test_{filename}`
2. **测试阶段**(Rust tests):
   - Rust 测试函数调用编译好的 Zig 测试可执行文件
   - 捕获并验证测试输出和退出状态
   - 集成到 Cargo 的测试报告中

## 使用方法

### 1. 在 Zig 文件中添加测试

```zig
// math.zig
const std = @import("std");

export fn factorial(n: u32) u64 {
    if (n <= 1) return 1;
    var result: u64 = 1;
    var i: u32 = 2;
    while (i <= n) : (i += 1) {
        result *= i;
    }
    return result;
}

// 添加单元测试
test "factorial basic cases" {
    try std.testing.expectEqual(@as(u64, 1), factorial(0));
    try std.testing.expectEqual(@as(u64, 1), factorial(1));
    try std.testing.expectEqual(@as(u64, 2), factorial(2));
    try std.testing.expectEqual(@as(u64, 6), factorial(3));
}
```

### 2. 在 build.rs 中编译测试

```rust
// build.rs
fn main() {
    // 编译主库
    autozig_build::build("src").expect("Failed to build Zig code");
    
    // 编译 zig/ 目录中的所有测试
    autozig_build::build_tests("zig").expect("Failed to build Zig tests");
}
```

### 3. 创建 Rust 测试文件

```rust
// tests/zig_tests.rs
use std::process::Command;
use std::path::PathBuf;

fn get_test_exe_path(name: &str) -> PathBuf {
    let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set");
    PathBuf::from(out_dir).join(format!("test_{}", name))
}

#[test]
fn test_math_zig_tests() {
    let test_exe = get_test_exe_path("math");
    
    let output = Command::new(&test_exe)
        .output()
        .expect("Failed to execute Zig math tests");
    
    assert!(
        output.status.success(),
        "Zig math tests failed: {}",
        String::from_utf8_lossy(&output.stderr)
    );
}
```

### 4. 运行测试

```bash
cd examples/external
cargo test --test zig_tests
```

## 输出示例

```
running 4 tests
test test_all_zig_tests_exist ... ok
test test_math_zig_tests ... ok
test test_strings_zig_tests ... ok
test test_zig_zig_tests ... ok

Zig math tests output:
STDERR:
1/4 math.test.factorial basic cases...OK
2/4 math.test.fibonacci sequence...OK
3/4 math.test.gcd calculations...OK
4/4 math.test.prime number check...OK
All 4 tests passed.

test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured
```

## API 参考

### `autozig_build::build_tests()`

```rust
pub fn build_tests(zig_dir: impl Into<PathBuf>) -> Result<Vec<PathBuf>>
```

**功能**:编译指定目录中所有 `.zig` 文件的测试

**参数**:
- `zig_dir` - 包含 `.zig` 文件的目录路径

**返回**:
- `Ok(Vec<PathBuf>)` - 编译成功,返回测试可执行文件路径列表
- `Err(_)` - 编译失败

**行为**:
- 扫描目录中的所有 `.zig` 文件
- 为每个文件编译测试可执行文件
- 测试可执行文件命名格式:`test_{filename}`(不含 `.zig` 扩展名)
- 输出到 `$OUT_DIR` 目录

### ZigCompiler 方法

```rust
// 编译测试到可执行文件
pub fn compile_tests(
    &self,
    source: &Path,
    output_exe: &Path,
    target: &str,
) -> Result<()>

// 运行测试可执行文件
pub fn run_test_executable(&self, test_exe: &Path) -> Result<String>
```

## 实现细节

### 编译命令

```bash
zig test source.zig -femit-bin=output_exe -target native -O ReleaseFast
```

- `-femit-bin=<path>` - 输出测试可执行文件路径
- `-target native` - 编译为本地架构
- `-O ReleaseFast` - 优化级别

### 测试可执行文件位置

测试可执行文件存储在 Cargo 的 `OUT_DIR` 中:
```
target/debug/build/<package-hash>/out/test_<filename>
```

### 测试输出格式

Zig 测试输出到 `stderr`,格式如下:
```
1/4 test_name...OK
2/4 another_test...OK
...
All 4 tests passed.
```

## 最佳实践

1. **测试文件组织**
   -`.zig` 文件放在专门的测试目录(如 `zig/`   - 每个文件包含相关功能的测试
   - 使用描述性的测试名称

2. **测试编写**
   - 使用 `std.testing` 模块的断言函数
   - 为每个导出函数编写测试
   - 测试边界情况和错误条件

3. **集成到 CI**
   - 在 CI 管道中运行 `cargo test`
   - 确保 Zig 编译器已安装
   - 使用 `--test zig_tests` 单独运行 Zig 测试

## 示例项目

查看 `examples/external` 获取完整的工作示例:

```
examples/external/
├── build.rs              # 编译测试
├── zig/                  # Zig 源文件
│   ├── math.zig         # 带测试的数学函数
│   ├── strings.zig      # 带测试的字符串函数
│   └── zig.zig          # 带测试的工具函数
└── tests/
    └── zig_tests.rs     # Rust 测试调用 Zig 测试
```

## 故障排除

### 测试可执行文件未找到

确保:
1. `build.rs` 中调用了 `build_tests()`
2. `.zig` 文件在正确的目录中
3. 检查 `OUT_DIR` 环境变量

### 测试编译失败

检查:
1. Zig 编译器版本兼容性
2. `.zig` 文件语法是否正确
3. 测试代码是否使用了正确的 Zig 标准库 API

### 测试运行失败

验证:
1. 测试断言是否正确
2. 测试逻辑是否有误
3. 查看详细输出(使用 `--nocapture`
## 技术优势

✅ **零手动配置** - 自动发现和编译测试  
✅ **原生 Zig 测试** - 使用标准 Zig 测试语法  
✅ **集成到 Cargo** - 统一的测试命令和报告  
✅ **快速反馈** - 独立的测试可执行文件  
✅ **CI 友好** - 标准 Cargo 测试工作流  

## 未来改进

- [ ] 支持测试过滤(只运行特定测试)
- [ ] 并行运行多个测试文件
- [ ] 测试覆盖率报告
- [ ] 测试失败时的详细诊断信息

## 相关文档

- [Zig 测试文档]https://ziglang.org/documentation/master/#Testing
- [Cargo 测试指南]https://doc.rust-lang.org/cargo/guide/tests.html
- [autozig README]README.md