phpspec 是行为驱动开发(BDD)的规范编写与执行工具,仅用于开发阶段驱动设计,不参与运行时;需通过 composer require --dev phpspec/phpspec 安装,配置正确的 PSR-4 autoload 并执行 composer dump-autoload,否则易出现类找不到或“No specs found”等问题。

phpspec不是“库”,它是行为驱动开发(BDD)的规范编写与执行工具,安装后用于生成、运行和验证 PHP 对象的行为契约。它不被 require 在业务代码里,也不参与 runtime,只在开发阶段驱动设计。
用 composer require --dev phpspec/phpspec 安装是最稳妥的方式
直接在项目根目录下运行该命令,它会把 phpspec 写入 composer.json 的 require-dev 区域,并下载到 vendor/ 目录。不要用全局安装(composer global require),因为不同项目可能依赖不同版本,容易引发冲突或 phpspec describe 生成的命名空间错乱。
- 确保项目已有
composer.json;若没有,先运行composer init - 安装后可执行文件路径通常是
vendor/bin/phpspec,不是bin/phpspec—— 后者仅当你在composer.json中显式配置了"config": {"bin-dir": "bin"}才成立 - 如果执行
vendor/bin/phpspec报错 “Permission denied”,给它加执行权限:chmod +x vendor/bin/phpspec
phpspec init 之后要检查 autoload 配置是否匹配 src 目录结构
运行 phpspec init 会引导你配置命名空间前缀和源码路径(如 src/)。但如果你的类实际放在 lib/ 或 app/ 下,或者用了 PSR-4 而不是 PSR-0,phpspec 就找不到待测类,运行时会提示 Class not found 或 Could not load class。
- 确认
composer.json中的autoload和autoload-dev正确映射了你的源码路径,例如:"autoload": { "psr-4": { "App\": "src/" } } - 改完后必须运行
composer dump-autoload,否则phpspec仍按旧映射加载 - 若类名与文件路径不严格遵循 PSR-4 规则(比如
MarkdownConverter放在src/Utils/MarkdownConverter.php,但命名空间写成AppConverter),phpspec run会直接失败,不报具体原因,只显示 “No specs found”
第一次写 spec 时别跳过 phpspec describe 命令
手动新建 spec/ 下的文件容易漏掉命名空间、use 语句或 it should 的标准格式,而 phpspec describe AppMarkdownConverter 会自动生成骨架文件并注册 autoload 关系。这个命令不只是创建文件,它还尝试解析类是否存在、是否可实例化,并据此生成对应 spec 结构。
- 如果目标类尚不存在,
phpspec describe会问你是否要生成它 —— 这是 BDD “先写行为,再实现”的关键入口 - 生成的 spec 文件里默认含
$this->beConstructedWith(),但如果你的类构造函数需要依赖对象(如ParserInterface),得手动替换为$this->beAnInstanceOf()或注入 mock,否则phpspec run会因无法 resolve 构造参数而中断 - 注意:
describe生成的类名是基于你输入的全限定名推导的,比如输入AppMarkdownConverter,它会尝试在src/MarkdownConverter.php创建类 —— 如果你实际想放它在src/Converter/MarkdownConverter.php,就得提前建好目录,或后续手动移动并修正命名空间
phpspec run 失败时优先看错误堆栈最顶行的关键词
不同于 PHPUnit,phpspec 的错误信息更偏向“契约未满足”的语义表达,而不是抛出异常堆栈。但当它真报错时,第一行往往就是根因:
-
Call to undefined method:说明 spec 中调用了尚未实现的方法,这是预期行为,下一步就是去补实现 -
ArgumentCountError或TypeError:通常源于构造函数参数类型与 spec 中beConstructedWith()传入值不匹配,比如期望string却传了null -
Specified binding for ... is ambiguous:出现在使用let或letGo时变量名重复或作用域混乱,常见于多个it should块共用同名变量却未隔离 - 空输出或
No specs found:大概率是 spec 文件没放在spec/子目录下,或文件名不以Spec.php结尾,或类名没按XXXSpec命名
真正卡住人的地方,往往不是语法或命令,而是 phpspec 对 PSR-4 路径、命名空间、autoload 三者一致性要求极严——差一个斜杠、少一次 dump-autoload、或多一层目录嵌套,它就安静地不报错,只说“没找到”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











