BDD测试工具PHPSpec与Behat的区别及适用场景是什么?
Behat 与 PHPSpec 的核心区别及适用场景
二者定位完全不同,所谓「重复测试」是教程为了同步演示两个工具用法的特殊场景,实际项目中二者覆盖完全不同的测试维度,不存在冗余。
我们以「购物车满减计算」这个常见需求为例做说明:需求规则为购物车商品总金额满199减20、满299减50,不满则不享受优惠。
1. Behat 的定位与适用场景
Behat 是站在*业务相关方(产品、运营、客户)*视角的验收测试工具,核心目标是验证功能是否符合业务预期,完全不关心代码内部实现逻辑。
对应的Behat测试场景写法如下,完全不懂代码的业务人员也能直接看懂并确认是否符合需求:
功能: 购物车满减计算 场景: 总金额不满199时不享受优惠 给定购物车有1件价格为100元的商品 当计算应付金额时 那么应付金额为100元 场景: 总金额满199时减20 给定购物车有2件价格为100元的商品 当计算应付金额时 那么应付金额为180元 场景: 总金额满299时减50 给定购物车有3件价格为100元的商品 当计算应付金额时 那么应付金额为250元
适用场景
- 验证业务功能是否符合需求,做上线前的验收校验
- 对齐开发、测试、产品的需求理解,避免各方对需求的理解偏差
- 回归测试时快速验证核心业务流程没有被改动破坏
2. PHPSpec 的定位与适用场景
PHPSpec 是站在开发者视角的单元级设计与测试工具,核心目标是指导代码设计、验证单个类的行为是否符合开发预期,不关心上层业务流程是否通顺。
如果我们把满减逻辑抽为独立的CartPromotionCalculator类,对应的PHPSpec测试写法如下:
// CartPromotionCalculatorSpec.php function it_returns_original_amount_when_total_under_199() { $this->calculate(100)->shouldReturn(100); } function it_reduces_20_when_total_equal_or_over_199() { $this->calculate(200)->shouldReturn(180); } function it_reduces_50_when_total_equal_or_over_299() { $this->calculate(300)->shouldReturn(250); } // 还可以验证类的依赖调用是否符合预期,比如后续规则要从配置中心读取 function it_should_get_rules_from_config_service(ConfigService $configService) { $configService->get('cart_promotion')->shouldBeCalled()->willReturn([ 199 => 20, 299 => 50 ]); $this->calculate(200)->shouldReturn(180); }
适用场景
- 单元级别验证单个类的逻辑正确性,出现问题可以秒级定位故障点
- 倒逼开发者写出低耦合、可测试的代码,指导类结构设计
- 重构代码时快速验证类的原有行为没有被改动破坏
二者不是重复测试的原因
举两个实际故障场景就可以清晰区分:
- 你在
CartPromotionCalculator的返回值里不小心多加了10元运费,PHPSpec会直接报错,你第一时间就能定位到是这个类的逻辑问题;如果只有Behat,虽然也会报错,但你不知道问题出在满减计算、运费计算还是购物车金额统计环节,排查成本极高。 CartPromotionCalculator本身逻辑完全正确,但你在控制器层调用的时候,不小心把总金额传成了未计算折扣的原价,PHPSpec是测不出这个问题的,因为它只验证类本身的逻辑、不管上层调用方式,这时候Behat的场景就会报错,提示整个功能输出不符合预期。
简单总结:
- Behat 管「功能做的对不对」
- PHPSpec 管「代码写的对不对」
内容的提问来源于stack exchange,提问作者user9244658
相关产品推荐
相关产品推荐

