忍者ブログ

uthorofotus iruc

プログラムを組むために考えたり憶えたりした、いろいろなことを記録していきます。タイトルの読みは「ウソロフォトス イルーク」

[31]  [30]  [29]  [28]  [27]  [26]  [25]  [24]  [23]  [22]  [21

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

askeet day fifteen: Unit tests の解説

askeetチュートリアルの15日目『単位テスト』です。symfonyのテスト仕組みを利用してテストプログラムを作っていきます。


15日目チュートリアルの日本語版はありません。本家英語版はこちらです。

■これまでのsymfony(Previously on symfony)
symfonyではシステムのテストには単体テスト(UnitTests)を使うことを薦めています。15日目のチュートリアルでは、この単体テストをします。

※このチュートリアルではSimpleTestを使っていますが、今のsymfonyはlimeという独自のテストを使っています。limeでのテストは後日に別記事で書きたいと思います。

■質問にタグを追加(Simple test)
PHPで書かれた単体テストフレームワークはいくつかありますが、symfonyではSimpleTestを使用します。SimpleTestをインストールするのですが、SimpleTestサイトにはPearパッケージが見あたりません。古いバージョン(1.0.0)のものだと、PHP5.0.5以降上手く動作しないとのことなので、PEARでインストールするのを諦めて、本家sourceforgeから1.0.1betaをダウンロードして、libディレクトリに置きます。

 wget http://nchc.dl.sourceforge.net/sourceforge/simpletest/simpletest_1.0.1beta.tar.gz
tar xfvz simpletest_1.0.1beta.tar.gz
mv simpletest lib/

■symfonyの単体テスト(Unit tests in a symfony project)
▽基本的な単体テスト(Default unit tests)
チュートリアルではaskeet/test/frontend/ にあると書かれていますが、今のバージョンではaskeet/test/functional/frontend/ に移っています。これはlimeで書かれたテストで、あとで見ることがあるかもしれないのでそのままにしておきます。チュートリアルで示されたコードはSimpleTest用に書かれたものなので、今のプロジェクトの中にはありません。

▽単体テストの追加(Add a unit test)
テストディレクトリの適当な場所に(askeet/test/unit/TagTest.php)テストファイルを書きます。これは13日目で作成したタグクラス(lib/Tag.class.php)のテストをするコードになります。Tag::normalizeメソッドに入れた文字列が、期待したとおりの結果を返すのかというチェックししています。

チュートリアル指示そのままのコードでは、SimpleTestクラスを読み込んでいないためエラーが出ます。また、SimpleTestのテストメソッド実行も自動でやってくれなくなったので、以下のようにコードを直します。

<?php
include(dirname(__FILE__).'/../bootstrap/unit.php');

require_once(SF_ROOT_DIR.'/lib/simpletest/unit_tester.php');
require_once(SF_ROOT_DIR.'/lib/simpletest/reporter.php');

require_once(SF_ROOT_DIR.'/lib/Tag.class.php');

class TagTest extends UnitTestCase
{
  public function test_normalize()
  {
    $tests = array(
      'FOO'       => 'foo',
      '   foo'    => 'foo',
      'foo  '     => 'foo',
      ' foo '     => 'foo',
      'foo-bar'   => 'foobar',
    );
    foreach ($tests as $tag => $normalized_tag)
    {
      $this->assertEqual($normalized_tag, Tag::normalize($tag));
    }
  }
}

$test =& new TagTest;
$test->run(new TextReporter());
?>

▽単体テストの実行(Running unit tests)
testコマンドは今のバージョンでは無くなっています。test-unitコマンドを使用します。このコマンドは /test/unit/以下にあるテストを実行するコマンドです。test-unitのあとにパラメータを追加すると、[パラメータ]Test.php というテストファイルのみを実行します。先ほど作ったテストを実行するのであれば、以下のようなコマンドになります。

#/test/unit/TagTest.php を実行
symfony test-unit Tag

test-unitにパラメータを付けた場合、どうやら指定されたファイルをただ実行しているだけのようです。
テストの実行 php直接とsymfonyコマンド経由の比較

▽反対に(The other way around)
実際の開発ではまず機能自体は空(何もしない)にし、テストから書き始めます。そのテストを通るように機能を開発し、テストが通るかチェックします。その次は、特殊文字(空白など)が入った場合のテストを作成し、これが通るように機能を修正していきます。ここで注意すべきは、テストのデバッグに時間を取られるのは本末転倒なので、テストの内容はなるべく簡単にします。

▽テストが失敗した時(When a test fails)
今度はsplitPhraseメソッドのテストを書きます。その際、1個失敗するテスト内容を加えておきます。先ほどのTagTestクラスのtest_splitPhraseメソッドに、チュートリアルで指示された内容を追加します。5個目のテストが失敗するテストです。スペースを含んだ文字列を登録したい場合は『"』ダブルクォーテーションで囲む仕様なので、『'』シングルクォーテーションではエラーになるはずです。

今のsplitPhraseメソッドの仕様だと、以下のような値が帰ってきます。

"'foo bar' askeet" => array("'foo", "bar'", 'askeet'),

■ブラウザセッションをシミュレート(Simulating a web browsing session)
単体テストだけではWebアプリケーションのテストは対応し切れません。htmlの結果やフォーム処理などのテストも必要です。Question関連のテストをするテストファイルを  test/functional/frontend/QuestionTest.phpに作成します。functionalディレクトリにはブラウザを使ったテストファイルの置き場所です。その下にアプリケーション名のディレクトリを作り、そこにファイルを置きます。

▽sfTestBrowserオブジェクト(The sfTestBrowser object)
sfTestBrowserは、ブラウザの挙動をシミュレートしてテストをしてくれるクラスです。このクラスを使ってテストを作っていきます。ただし、sfTestBrowserの仕様が変わったようでチュートリアルで書かれているコードそのままでは動きません。とりあえずはコードを見ておくだけにします。実際のテストは次に書かれたWebTestCaseを使って作ります。

▽WebTestCaseオブジェクト(The WebTestCase object)
sfTestBrowserはsymfonyで提供されているクラスでしたが、SimpleTestも同じようなクラスを持っています。そのWebTestCaseクラスを使ってテストを作っていきます。test/functional/frontend/QuestionTest.phpへチュートリアルのコードを以下のように記述します。テストメソッド(test_~)はチュートリアル指示そのままなので略しました。

<?php
include(dirname(__FILE__).'/../../bootstrap/functional.php');
require_once(SF_ROOT_DIR.'/lib/simpletest/web_tester.php');

class QuestionTest extends WebTestCase
{
  public function test_QuestionShow()
  
  public function test_QuestionAdd()
 
}

$test =& new QuestionTest;
$test->run(new TextReporter());
?>

以下のコマンドでこのテストを実行します。アプリケーション名[frontend]は必須ですが、ファイル名のパラメータは省略できます。その場合はディレクトリ(test/function/frontend)内のファイルをチェックし、~Test.phpとなっているテストファイルをすべてテストします。動作には多少の時間がかかるので、しばらく待ちましょう。

symfony test-functional frontend Question

▽Selenium
Seleniumという、主にJavaScriptで書かれたWebアプリケーションのテストツールを使います。なお、チュートリアルで指示されたダウンロードページはありません。Selenium Coreをダウンロードしてきます。なお、Selenium IDEはSeleniumで使うテストデータを作成するFirefoxエクステンションです。1からhtmlを書くよりは、こちらのエクステンションを使うととても楽にテストを書くことができます。

wget http://release.openqa.org/selenium-core/0.8.2/selenium-core-0.8.2.zip
unzip selenium-core-0.8.2.zip
mv selenium-core-0.8.2 web/selenium

webディレクトリにseleniumを置いたら、web/selenium/tests/にテストデータを置きます。チュートリアルで指示されたhtmlコードをそのままtestQuestion.htmlにします。http://askeet/selenium/index.html のSelenium TestRunnerのリンクを飛びます。その後、左上にTest Suiteをいうフォームがあるはずですので、../tests/testQuestion.html を指定します。そうすると、先ほど作ったテストデータをseleniumが読み込みますので、右上のExecute Testsパネルからテストを実行することができます。動作イメージは以下のような感じです。
selenium実行イメージ

■環境について少し(A few words about environments)
チュートリアルでは、動作テスト用にデータベースを別に用意する時などのために、テスト用の環境(test)を使っています。ただ、私の環境ではfrontend_test.phpをつくったのですが、上手く動かなかったのでprod環境でテストしてしまっています。

■また明日(See you Tomorrow)
今のsymfonyはすべてをカバーするテストシステムはまだないので、今日やったテストを組み合わせてテストをします。アプリケーションに機能を追加する前など、一度すべてのテストをしおくと、後々にバグなどで開発が後退することを避けることができます。
16日目のチュートリアルは、……何やるか決まっていなかったのでしょうか?とくに書かれていません。

PR

この記事にコメントする

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード   Vodafone絵文字 i-mode絵文字 Ezweb絵文字

この記事へのトラックバック

この記事にトラックバックする:

askeet day sixteen: Lazy day の解説 HOME UbuntuへのPECL xdebugインストール

プロフィール

HN:
flyfront
性別:
非公開
自己紹介:
PHPプログラマ。東京でsymfonyな仕事してます。

HNはflyfrontですが、
仕事関係ではr_koike名義を使ってる場合もあります。

Wassr

カレンダー

08 2017/09 10
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

最新コメント

[01/02 通りすがり]
[10/18 flyfront]

バーコード

アクセス解析

忍者ブログ [PR]
Template by repe