TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.9 KiB
5.9 KiB
PHP AOT 编译器测试运行指南
测试文件位置
所有测试文件位于 tests/compiler/ 目录下,使用 .phpt 扩展名。
运行测试
运行单个测试
# 运行特定测试文件
php run-tests.php tests/compiler/test-name.phpt
# 示例:运行 match expression 测试
php run-tests.php tests/compiler/match-expression.phpt
运行多个测试
# 运行多个测试(使用通配符)
php run-tests.php tests/compiler/pattern*.phpt
# 运行整个目录
php run-tests.php tests/compiler/
常用选项
# 显示详细信息
php run-tests.php tests/compiler/test-name.phpt -v
# 并行运行测试(加快测试速度)
php run-tests.php tests/compiler/ -j4
# 只显示失败的测试
php run-tests.php tests/compiler/ -g FAIL
# 保持测试生成的文件
php run-tests.php tests/compiler/test-name.phpt --keep-all
# 显示内存使用情况
php run-tests.php tests/compiler/test-name.phpt -m
新增测试用例说明
本次新增的 16 个测试文件覆盖了以下 PHP 8.x 特性:
| 测试文件 | 测试内容 | PHP 版本 |
|---|---|---|
| trait-basic.phpt | Traits 基础 | 7.4+ |
| generators.phpt | 生成器 | 7.4+ |
| attributes.phpt | 注解/属性 | 8.0+ |
| match-expression.phpt | Match 表达式 | 8.0+ |
| named-arguments.phpt | 命名参数 | 8.0+ |
| union-intersection-types.phpt | 联合类型 | 8.0+ |
| constructor-promotion.phpt | 构造函数提升 | 8.0+ |
| null-coalescing.phpt | 空合并运算符 | 7.4+ |
| array-spread.phpt | 数组展开 | 7.4+ |
| arrow-functions.phpt | 箭头函数 | 8.0+ |
| magic-methods.phpt | 魔术方法 | 7.4+ |
| iterators.phpt | 迭代器 | 7.4+ |
| anonymous-classes.phpt | 匿名类 | 7.4+ |
| type-declarations.phpt | 类型声明 | 7.4+ |
| late-static-binding.phpt | 后期静态绑定 | 7.4+ |
| variadic-functions.phpt | 可变参数函数 | 7.4+ |
PHPT 文件格式
每个测试文件包含三个主要部分:
--TEST--
测试描述
--FILE--
<?php
// PHP 测试代码
?>
--EXPECT--
期望的输出结果
编写新的测试
基本步骤
-
在
tests/compiler/目录创建新文件,如my-feature.phpt -
添加测试头部:
--TEST-- My Feature Test -
添加测试代码:
--FILE-- <?php // 你的测试代码 function main() { // 测试逻辑 } ?> -
添加期望输出:
--EXPECT-- 期望的输出结果
注意事项
- main 函数: 大多数测试需要在
main()函数中执行代码 - 输出匹配: EXPECT 部分必须与实际输出完全匹配(包括空格和换行)
- var_dump: 使用
var_dump()来输出变量类型和值 - 错误处理: 对于预期会抛出异常的测试,使用 try-catch 包裹
示例模板
--TEST--
Feature Name
--FILE--
<?php
// 定义类或函数
class MyClass {
public function test() {
return "result";
}
}
function main() {
$obj = new MyClass();
var_dump($obj->test());
}
?>
--EXPECT--
string(6) "result"
调试失败的测试
查看差异
php run-tests.php tests/compiler/failed-test.phpt -v
输出会显示期望值和实际值的差异:
========DIFF========
Expected:
string(6) "result"
Actual:
string(7) "results"
查看生成的文件
# 保持生成的 C++ 文件
php run-tests.php tests/compiler/test-name.phpt --keep-all
# 查看生成的 C++ 代码
cat build/tests/compiler/test-name.cc
手动编译和运行
# 1. 生成 stub 文件
php bin/gen_stub.php -f tests/compiler/test-name.php
# 2. 转换为 C++
php bin/tpc.php tests/compiler/test-name.php
# 3. 编译 C++ 代码
cd build && make test-name
# 4. 运行编译后的程序
./build/test-name
测试覆盖率检查
覆盖清单直接从 PHPT 和相关 PHPUnit fixture 的源码生成:
# 查看带明确分母的摘要
php bin/analyze-test-coverage.php
# 生成 PHP 版本 × 特性 × 三类测试证据的完整矩阵
php bin/analyze-test-coverage.php \
--format=markdown \
--output=build/test-coverage.md
# CI 使用 JSON,并在解析问题或失效 fixture 引用时失败
php bin/analyze-test-coverage.php \
--format=json \
--output=build/test-coverage.json \
--strict
报告分别计算 AST 节点、正向编译、运行语义和负向诊断覆盖率,并明确列出每个分母;不会生成含义不清的单一总百分比。分类规则及 JSON 字段说明见 测试覆盖清单。
常见问题
Q: 测试失败,显示 "Not implemented" 错误
A: 这说明该 PHP 特性尚未被 AOT 编译器支持。请查看编译器的 TODO 列表或提交 issue。
Q: 字符串长度不匹配
A: PHP 8.x 的字符串输出可能会截断,调整 EXPECT 部分的字符串长度以匹配实际输出。
Q: 如何跳过某些测试?
A: 在测试文件中添加 --SKIPIF-- 部分:
--SKIPIF--
<?php
if (!feature_supported()) {
echo "skip Feature not supported";
}
?>
Q: 如何测试性能?
A: 使用 --TIMEOUT-- 设置超时时间,并在测试中包含性能基准:
--TIMEOUT--
5
--FILE--
<?php
$start = microtime(true);
// 性能测试代码
$duration = microtime(true) - $start;
var_dump($duration < 1.0); // 应该在 1 秒内完成
?>
贡献测试
欢迎提交新的测试文件!请遵循以下准则:
- 文件命名: 使用小写字母和连字符,如
new-feature.phpt - 测试描述: 在 TEST 部分清晰描述测试内容
- 覆盖全面: 测试正常情况、边界情况和错误情况
- 代码简洁: 保持测试代码简单明了
- 输出准确: 确保 EXPECT 部分与实际输出完全匹配
更多信息
- PHP 官方测试套件文档:https://github.com/php/php-src/blob/master/run-tests.php
- PHP AOT 编译器文档:查看项目根目录的 README
- 问题反馈:提交 issue 到项目仓库