0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

フラットphpをテストする

Last updated at Posted at 2019-05-23

まえがき

phpunitを用いればphpのテストで困ることはありません。

今夜までだ
ただし、今夜までだ!

テスト対象はフラットphp。classもvendorもなく、DBアクセスもありません。
もちろんcomposerも使用していません。

テスト対象のphp
<?php
namespace honya;

[$status, $res] = fncHonya();

header('HTTP/1.1 '.$status);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($res);

function fncHonya(){
  // ちょこっとビジネスロジック
  return [200, ['result'=>'ok']];
}

phpunitはフラットphpをテストできない!

初めて知りました。フラットphpで開発したことがなかったので。
テストコードを作る方が面倒でしたが、知恵を絞ってテストできるようにしてみました。

元のファイル構成:

app
└ honya.php

テストできるようにしたファイル構成:

app
└ honya.php
└ compser.json
└ phpunit.xml
└ tests
 └ HonyaTestClass.php
 └ HonyaTest.php
 └ fixtures

テスト用classを作る

HonyaTestClassを作成し、honya.phpをrequireしたメソッドを作成しました。

ポイントは3点

テスト用class
<?php
namespace honya;

class HonyaTestClass {

    private $header = [];
    private $http_status = null;
    private $body = null;

    /**
     * @runInSeparateProcess
     */
    public function request(){
        ob_start();
        require 'honya.php';
        $this->body = ob_get_clean();
        $this->http_status = http_response_code();
        $this->header = xdebug_get_headers(); //@TODO php7 xdebug
    }

    public function getHttpStatus(){ return $this->http_status; }
    public function getHeader(){ return $this->header; }
    public function getBody(){ return $this->body; }
}

namespace はテスト時に必要と分かりましたが、実際は不要です。
性能に影響がないので入れました。
echo で bodyを返すため、ob_start、ob_get_clean で echo 出力を奪い取っています。
@runInSeparateProcess を付けることでphpunitに邪魔されず、テスト対象の echo だけ取得できます。
header は header_list() で取得できないので(原因不明)、xdebug_get_headers() を使用しています。php5では機能しましたが、php7では機能しません(原因不明)

テストを作る

classさえ作ればテストコードは普通です。

HonyaTest.php(テスト本体)
<?php
namespace honya;

require_once 'tests\HonyaTestClass.php';
require_once 'tests\HonyaTestUtil.php';

class HonyaTest extends \PHPUnit\Framework\TestCase {

    use HonyaTestUtil;

    /** @runInSeparateProcess */
    public function test1() {

        $body = 'honya body';
        $this->init_function(200, $body);

        $_POST['honya_param1'] = 'honya1';
        $_SERVER['REQUEST_URI'] = '/honya';

        $clazz = new \honya\HonyaTestClass();
        $clazz->request();

        $this->assertEquals('honya2 body', $clazz->getBody());
        $this->assertEquals('200', $clazz->getHttpStatus());
//      $this->assertSame([], $clazz->getHeader()); //@TODO php7 xdebug
    }
}

テスト用utilを作る

ポイントは2点

  • namespace
  • trait
HonyaTestUtil.php()
<?php
namespace honya;

use phpmock\phpunit\PHPMock;

trait HonyaTestUtil {

    use PHPMock;

    public function init_function($http_status, $body){
        $this->getFunctionMock(__NAMESPACE__, 'getenv')->expects($this->any())->willReturn('');
    }
}

getFunctionMock は namespace が空のときエラーになります。
テスト対象(honya.php)に namespace を入れたのは、そういう訳です。

HonyaTestUtil はclassにしていましたが、new でも static でもエラーになるので、trait にしました。

./vendor/bin/phpunit

で、実行できます。
phpunit.xml のデフォルトで autoload.php と テスト対象フォルダを指定されてるためです。
カバレッジも表示できるみたいですが、表示するまでもないので、暇があったらやります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?