前回、PHPUnit require_once地獄からの脱出 1 まずはrequire_onceでテスト元のファイルをどう読み込むか編 で大分長々と書きましたが、PHPUnitでテストファイルからrequire_onceでテスト元のファイルを読みだすのが面倒だという話です。
どうすればいいのかといいますと、phpunit.xmlを下記のように書き換えます。
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap = "vendor/autoload.php"
colors = "true">
</phpunit>
下記が肝心の部分です。
bootstrap = "vendor/autoload.php"
ついでに、色がつくようにしています。
colors = "true"
緑の光あれ。
MonkeyTest.phpから、
require_once “class/Monkey.php”;
を消してみます。
<?php
use MonkeyWorld\Monkey; //追加
use PHPUnit\Framework\TestCase;
class MonkeyTest extends TestCase
{
public function testScream()
{
$monkey = new Monkey();
ob_start();
$monkey->scream();
$actual = ob_get_clean();
$expected = 'ウキー!!!';
$this->assertEquals($expected, $actual);
}
}
testScreamを実行してみます。
OKです!緑の色もついて、みやすいですね!( ˊᵕˋ )
テスト元のMonkey.php に talkToChimpanzee()というメソッドが追加されました。
<?php
namespace MonkeyWorld;
class Monkey
{
public function scream(){
echo "ウキー!!!";
}
public function talkToChimpanzee(){
Chimpanzee::talk();
}
MonkeyTest.phpもtalkToChimpanzeeをテストできるように書き換えます。
use PHPUnit\Framework\TestCase;
class MonkeyTest extends TestCase
{
public function testScream()
{
$monkey = new Monkey();
ob_start();
$monkey->scream();
$actual = ob_get_clean();
$expected = 'ウキー!!!';
$this->assertEquals($expected, $actual);
}
public function testTalkToChimpanzee()
{
$monkey = new Monkey();
ob_start();
$monkey->talkToChimpanzee();
$actual = ob_get_clean();
$expected = 'こんにちは。おいらチンパンジーだよ。';
$this->assertEquals($expected, $actual);
}
}
今度はMonkeyTest.phpのMonkeyTest.classをテストとして実行してみます。
OKですね!
ちなみに、上記はPHPStormから実行していますが、コマンドプロンプトから実行すると、次のようになります。
phpunitの後に引数をつけずに、
phpunit tests/MonkeyTest.php
とするだけです 。
PHPUnitの設定ファイル、phpunit.xmlで実行の初期に
ところで、実験的にclass/Hoge.phpというやつを追加します。
<?php
class Hoge
{
public function talk(){
print "おいらHogeクラスです";
}
}
こいつには、namespaceの宣言がないことに注意してください。
Monkey.phpにtalkToHogeというメソッドを追加します。
<?php
namespace MonkeyWorld;
class Monkey
{
public function scream(){
echo "ウキー!!!";
}
public function talkToChimpanzee(){
Chimpanzee::talk();
}
public function talkToHoge(){
Hoge::talk();
}
}
MonkeyTest.phpに次のテストメソッドを足します。
public function testTalkToHoge()
{
$monkey = new Monkey();
ob_start();
$monkey->talkToHoge();
$actual = ob_get_clean();
$expected = 'おいらHogeクラスです';
$this->assertEquals($expected, $actual);
}
MonkeyTestクラスを実行します。
Error : Class 'MonkeyWorld\Hoge' not found
D:\xampp\htdocs\autoloadSample\class\Monkey.php:16
D:\xampp\htdocs\autoloadSample\tests\MonkeyTest.php:38
というエラーが出て、実行が失敗したみたいです。(>_<)
というか、そもそも普通にこれはブラウザからPHPを実行しても実行できません。最初のサンプルでも使った、トップディレクトリにあるhoge.phpを実行します。
hoge.phpは次の通りです。
<?php
require_once "vendor/autoload.php";
use MonkeyWorld\Monkey;
require_once "class/Hoge.php";
$monkey = new Monkey();
$monkey->scream();
echo "<br>";
$monkey->talkToChimpanzee();
$monkey->talkToHoge();
これを実行すると次のようになります。
Fatal error: Cannot declare class Hoge, because the name is already in use in D:\xampp\htdocs\autoloadSample\class\Hoge.php on line 3
というエラーが出て実行できません。
あんまり深堀りできてないですが、これ、Hogeクラスが重複してますよってエラーなんですよね。なんででしょうか。わかる人、教えてください。m(_ _)m
仕方ないので、Hoge.phpに次のようにnamespaceをつけます。
<?php
namespace MonkeyWorld;
class Hoge
{
public function talk(){
print "おいらHogeクラスです";
}
}
すると、エラーもなく実行できるようになります。
hoge.phpの実行結果↓
PHPUnitの実行結果↓
namespaceは大変大事ですね。
ちなみに、autoloadで読み込むnamespaceの指定については、下記の記事をご参考にしてみてください。
ありがとうございます。PHPを始めたばかりで、autoloadの仕組みが良くわかっていませんでしたが、おかげで理解することができました。
いえ、お役に立ったならよかったです!