この記事は何か
このPHPがテンプレートエンジンのくせに慎重すぎる (前篇)の内容をPHPUnitではなくphpspecに置き換えたものです。phpspecを使った開発フローの初歩の例として参考になると思います。
というか最初はPHPUnitではなくphpspecで押し通すつもりでしたが、期待してたphpstan-phpspecが最新版のphpspec+PHPStanでは動作ないことがわかったので断念しました。とはいえ、静的解析に期待し過ぎなければphpspecも良い選択肢だと思いますよ。
テスティングフレームワークのインストール
PHPUnitが有名ですが有名すぎておもしろくないので、ここではphpspecを入れていきます。
$ composer require --dev phpspec/phpspec
Composer経由でクラスをロードするためにcomposer.json
を編集して設定します。
diff --git a/composer.json b/composer.json
index 943af4f..d559d78 100644
--- a/composer.json
+++ b/composer.json
@@ -14,5 +14,15 @@
],
"require-dev": {
"phpspec/phpspec": "^6.1"
+ },
+ "autoload": {
+ "psr-4": {
+ "Bag2\\Hello\\": "src"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "spec\\Bag2\\Hello\\": "spec"
+ }
}
}
composer.json
に書く時は、名前空間の\
を\\
のように二重にすることを忘れないでください(これはJSONの制約です)。また、名前空間の最後にも\\
を付けることをを忘れないでください。autoload-dev
の名前空間の最初にspec\\
を付けているのはphpspecの作法です。
この設定の意味について詳しく知りたい人はincludeって書きたくない僕たちのためのオートローディングとComposer - Qiitaを読んでください。
せっかくなので、もうひとつ。依存関係が増える前にテキストエディタでcomposer.json
を弄っておきます。
diff --git a/composer.json b/composer.json
index d559d78..56ca999 100644
--- a/composer.json
+++ b/composer.json
@@ -24,5 +24,8 @@
"psr-4": {
"spec\\Bag2\\Hello\\": "spec"
}
+ },
+ "config": {
+ "sort-packages": true
}
}
この設定をすると、composer require
で依存関係が増えたときにパッケージ名を勝手にソートしてくれるようになります。
手作業でcomposer.json
を編集した後は、必ずcomposer validate
で検証してください。また、オートロード関連の設定をした後はcomposer dump-upload
を実行してください。

次に.phpspec.yml
を設定しておきます。
suites:
acme_suite:
namespace: Bag2\Hello
psr4_prefix: Bag2\Hello
これはphpspecにクラスを生成させるための設定です。
specの追加
phpspecについて詳しく知るにはIntroduction — phpspec 5.x documentationを読んでください。
specファイルを作るにはphpspec describe
コマンドを使います。詳しくは動画を見てください。
いきなりですが、phpspecではいきなりphpspec run
します。
すると、空のクラスのファイルが生成されます。
次に、またおもむろにspecファイルを書き変えます。
diff --git a/spec/HelloSpec.php b/spec/HelloSpec.php
index 0b11c59..f2f2317 100644
--- a/spec/HelloSpec.php
+++ b/spec/HelloSpec.php
@@ -7,8 +7,8 @@ use PhpSpec\ObjectBehavior;
class HelloSpec extends ObjectBehavior
{
- function it_is_initializable()
+ function itはHelloを返す()
{
- $this->shouldHaveType(Hello::class);
+ $this->to('World')->shouldReturn('Hello, World!');
}
}
そのあとphpspec run
を実行すると、なんと空のメソッド実装が現れます。
phpspec run
を実行してグリーンになればOKです。

次にspecを増やしてみましょう。
diff --git a/spec/HelloSpec.php b/spec/HelloSpec.php
index f2f2317..9e212de 100644
--- a/spec/HelloSpec.php
+++ b/spec/HelloSpec.php
@@ -10,5 +10,6 @@ class HelloSpec extends ObjectBehavior
function itはHelloを返す()
{
$this->to('World')->shouldReturn('Hello, World!');
+ $this->to('Miku')->shouldReturn('Hello, Miku!');
}
}
phpspec run
を実行する赤く表示されます。

そりゃそうだ、return 'Hello, World!';
なんて書いてるんだから。なので、しっかり実装していきます。
diff --git a/src/Hello.php b/src/Hello.php
index 50771a1..498da61 100644
--- a/src/Hello.php
+++ b/src/Hello.php
@@ -4,8 +4,8 @@ namespace Bag2\Hello;
class Hello
{
- public function to($argument1)
+ public function to(string $name): string
{
- return "Hello, World!";
+ return "Hello, {$name}!";
}
}