overこの広告は、90日以上更新していないブログに表示しています。2015-02-18Codeceptionのドキュメントの翻訳をはじめました。Codeception日本のPHPerにもっとCodeceptionを知ってもらうため、ついに?立ち上がりました。タイトルのとおり、Codeceptionのドキュメントの翻訳をはじめました。translated.https://github.com/Codeception/docs.pt_BR/issues/1#issue-19933969ということなので、guidesのみを対象としています。現状、ルール等何も用意出来ていない状態で見切り発車している状態ではありますが、プルリクエストなどお気軽にしていただければと思います。17:33Codeceptionのドキュメントの翻訳をはじめました。Selenium前回のエントリの続きです。今回は単純なアプリのテストなので、Dockerfileもテスト手順もシンプルでした。複雑な手順が必要となる、Seleniumを利用したWEBアプリのE2Eテストなどもこの方式でできるのかどうか、引き続き実験してみます。/usersするとusersテーブルからユーザー一覧を取得して表示する、という簡単なものを作成しました。GitHubテストはCodeceptionのWebDriverモジュールを利用して記述しました。Dockerコンテナ上でWEBアプリケーションを公開するDockerファイルをアプリケーションリポジトリの.docker/Dockerfileに記述します。悩んだ点は、ApacheやMySQLなどの設定をどのように行えばよいか、ということ。選択肢として、以下を考えました。RUN命令でsedを使い、必要な箇所の置換を行うADD命令でファイルを置き換える前者は、単純な置換であればいいですが、あっという間に未来のないDockerfileになりそうです。後者でいくことにしました。Dockerfileと並列に、httpd.confmy.cnfphp.iniを用意し、ADDします。結果、Dockerfileは以下のようになりました。8000:80オプションをつけてあげれば、コンテナの外部からホストのIPを指定してWEBアプリケーションにアクセスできるようになります。Chromiumを導入済みのコンテナイメージを共有してくれています。davert/selenium-envこれでバックグラウンドでコンテナが起動している状態となります。CodeceptionのWebDriverモジュールの設定をする結果から書くと、以下のような設定を行いました。'accept'ちょっと悩んだのは、以下の設定項目。default).コメントとして書いていますが、WEBアプリのコンテナも、SeleniumEnvコンテナも、-pオプションでポートのマッピングを行っているので、どちらもDockerホストのIPにすればとりあえず動くんじゃね?と。テスト実行用のスクリプトを作成する$APPROOT/.docker/run-tests.shを以下のように作成しました。--debug前回と同様、/opt/docker-l4-sampleにはJenkinsのジョブのワークスペースがマウントされます。./.docker/setup.sqlはアプリ用のDB・ユーザーの作成を行います。Jenkinsにジョブを作成し、ビルドする前回と基本的には同じです。ジョブ名リポジトリの名前に合わせました。「フリースタイル・プロジェクトのビルド」を選択。ソースコード管理Gitを選択し、リポジトリのURL、資格情報を設定。「シェルの実行」を選択し、以下を記述。ポートのマッピングオプションを追加しています。今回はSeleniumとWEBアプリ間の通信にホストIPを利用して行いましたが、異なるアプリのE2Eテストが同時に実行された場合を考えると、アプリ毎にポートのマッピングを変えないといけないのではないか?と思います。Jenkinsにジョブを設定する際に「どのポート空いてるんだっけ?」と考えるのはちょっとイヤですね。✘╹◡╹✘などを参考に、コンテナ間の通信はどうあるべきか、について理解する必要がありそうです。課題はありますが、理想のCIサーバを目指し、また一歩進みました。Jenkins私が属する組織では受託開発がメインでして、サーバーやミドルウェアなどの要件を我々が自由に決定できないケースもしばしば。基本はPHPなのですが、案件によってバージョンが異なったり、近頃ではNodeの案件なども出てきました。長いこと「CIサーバを導入したい」と思いつつもアプリ毎にCIサーバを立ち上げるのもメンドイコスト等の関係で現実的ではないので、頭を悩ませていました。そんな中、Dockerを使って解決している先人がいましたので、早速、試してみました。Node)を用意するDockerファイルを作成するテスト実行用のスクリプトを作成するJenkinsにジョブを作成し、ビルドする今後の課題など長いです。Box4.3.20Vagrant1.7.2先人の知恵まとめいろいろと調べていたところ、以下のようなポイントがあることがわかりました。Dockerのサーバーを用意するJenkinsとDockerを導入したCentOS6.5をVagrantで構築します。centos65-x86_64-20140116作成されたVagrantfileを編集します。SHELLVMを作成します。up成功したらVMを再起動し、ブラウザで、http://192.168.33.10:8080/jenkinsにアクセス、jenkinsが正常に動作していることを確認します。jenkinsが正常に動作していたら、以下を行っておきます。Nodeのそれぞれで作成しました。GitHubテストはCodeceptionで記述しました。GitHubテストはmochaで記述しました。Dockerファイルを作成する$APPROOT/.docker/Dockerfileをそれぞれに作成しました。Composerとします。テスト実行用のスクリプトを作成するそれぞれのアプリに$APPROOT/.docker/run-tests.shを作成し、テスト実行用のスクリプトを記述しました。test/opt/php-fizzbuzz、/opt/node-fizzbuzzには、Jenkinsのワークスペースがマウントされます。Jenkinsにジョブを作成し、ビルドするそれぞれのアプリ用のジョブを以下のように作成しました。ジョブ名リポジトリの名前に合わせました。「フリースタイル・プロジェクトのビルド」を選択。ソースコード管理Gitを選択し、リポジトリのURL、資格情報を設定。「シェルの実行」を選択し、以下を記述。/opt/$JOB_NAME/.docker/run-tests.shジョブが作成できたら、それぞれビルドを実行してみます。初回はコンテナの作成に時間がかかると思いますが、2度目からはキャッシュが使われるようになるため、ササッといくはずです。今後の課題などより複雑なテストはどうなる?今回は単純なアプリのテストなので、Dockerfileもテスト手順もシンプルでした。複雑な手順が必要となる、Seleniumを利用したWEBアプリのE2Eテストなどもこの方式でできるのかどうか、引き続き実験してみます。パーミッションまわり今回はユーザー権限まわりを気にしていないので、すべてrootで実行されます。このあたりも問題になる可能性がありますね。Practiceなのでしょう?テスト実行後にコンテナを破棄したい何度もビルドしていると、以下のように古いコンテナが残ってしまいます。これら、破棄した方がいいと思いますが、jenkinsでどうやるんでしょう?以上となります。Docker、「foregroundプロセスがないとダメ」とかいろいろ躓いたところはありましたが、使いこなせるようになると強力ですね。これでようやくCIサーバーを導入できそうです。PHPバージョン2で入った新機能などを紹介するエントリなど書く書く詐欺をしていたら年末になってしまいました。いうか2014年、2つめのエントリ。Codeceptionを中心にお仕事をしておりました。社内におけるCodeceptionの実績も溜まってきましたので、その経験をもとにした、マニュアルには載っていないちょっとしたコツやTIPSを紹介したい思います。Actorにはテンションの上がる名前をつけよう「マニュアルには載っていない」と前置きしながらいきなりマニュアルに載っていることを。バージョン1では「Guy」固定だったActor名、バージョン2からは自由に名前を決めることができます!(「FunctionalGuy」、「AcceptanceGuy」の「Guy」部分です。)正直バージョン2の新機能で最も素晴らしいのはココじゃないか!?実際のActor名の指定はbootstrapのオプションとして指定します。好きなアノ子の名前でも、ペットの名前でも、親しみの湧く名前を付けましょう。胸が熱くなること間違いなしです。楽しくテストしましょう。$I->seeElement(...)など、様々な箇所に登場してくるCSSセレクタ。あれ、テストコードの可読性を下げるやっかいなヤツです。性格にも依るんじゃないかと思いますが、時にはこんなことに。td:nth-child(2)');まぁ、PageObject使えよ!ということかもしれませんが、その前にテンプレートのid属性やclass属性をテストを意識したものに整理しておくことをおすすめします。テンプレート外注した場合など、idを下手にいじるとデザインに影響が及んだり、もあるわけで。そんなときはテスト専用のクラスをつけてしまえば良いと開発者の@davertさんはアドバイスしています。seeInField利用できるように、for属性、id属性の対応を適切にしておく一覧系であれば主キーにもとづいたid属性やクラスをtrに付与しておくなどを実践するようにしています。Testは基本的にCeptフォーマットで記述しています。開発者によって、wantTowantToTestexpectexpectTocommentに対する理解の違い、使いどころの違いのため、テストコードの統一性が損なわれるという経験をしました。そこで、現在では以下のようなテンプレートを導入しています。FunctionalGirl($scenario);$I->wantToTest('テストしたい機能名');$I->comment('どのようなテストを行うのかの説明、前提事項など');$I->amGoingTo('操作内容');$I->comment('特記事項');$I->amOnPage(...);$I->fillField(...);$I->click(...);$I->expect('操作の結果、期待すること1');$I->comment('特記事項');$I->see(...);$I->seeInField(...)$I->expect('操作の結果、期待すること1');$I->comment('特記事項');$I->see(...);$I->seeInField(...)このように、1つのamGoingToに対して複数のexpectを記述する形式にすると頭の中身をそのまま記述していけると考えています。いまのところ、これが「さいきょう」だと思ってますが、、、、異論は認める。入力画面');$I->comment('このテストではユーザー登録用のフォームが正常に動作することを確認します。'#password');最終手段!モジュールを拡張する方法CodeceptionはActorへの機能追加を実現するためのHelperという仕組みを提供しています。Documentationしかしながら、要件によってはモジュール+ヘルパーではテストができないケースがあるかもしれません。そんなときには最終手段としてモジュール自体を拡張するという方法が残っています。Laravel4モジュールを例に、拡張の手順を説明します。(パス等はプロジェクトに合わせて読み替えてください。trueこの、Laravel4をLaravel4Extに変更します。trueこれで準備は完了です。あとはLaravel4Extクラスで既存のメソッドをオーバーライドして好きなようにできます。他をすべて考え尽くしたあとの最終手段として採用すべき、だと個人的には考えています。将来的にフレームワーク側のバージョンアップに追随できなくなる可能性がある、というのが一番の理由です。実際に拡張をした例Laravel4モジュールの場合、DBに対する変更を確認するためのAPIとして、seeRecorddontSeeRecordがあります。とあるアプリケーションにて、アプリケーションが使用するユーザーとは別のユーザーが所有するテーブルにデータを永続化する、という機能がありました。セキュリティポリシーによりアプリケーションデフォルトのユーザーは永続先テーブルに対する権限は何もありません。そんな機能をテストするためには、テスト中にデータベースのコネクションを切り替えられるようにしなければなりません。dontSeeRecordにコネクション名を指定できるようにするという2つの選択肢を考えました。前者ではコネクションを戻すのを忘れた場合に後続のテストに影響がある(=うっかりミスで開発効率を下げる可能性がある)ため、後者を採用し、以下のようにしました。\DB::setDefaultConnection(self::DEFAULT_CONNECTION);}?>1年半前から使いはじめたCodeception、当時のバージョンは1.6.3.1。現在のバージョンは2.0.9。日本のPHPerに広めたいですね。来年こそはphpconに。17:03マニュアルには載っていないCodeceptionのコツ/TIPSTweet広告を非表示にするもっと読むコメントを書く2014-04-02Codeceptionにバグ修正をプルリました。Codeception久しぶりの更新です。Codeception、メジャーバージョンアップが近いです。