Test::mysqldを使うとクールにMySQLを起動させられるので、それを使おうとしたんだ。でもおいらのローカルにあるmysqlをMacPortsのmysqlで、ファイルレイアウトがメタメタなんだ。だからまずこんな感じで、Test::mysqldを継承するMyApp::Test::mysqldを書いたわけさ!

必要とあればMacPortsとかの環境じゃなくてもMYSQL_INSTALL_DBとMYSQLDを設定すればテスト時にTest::mysqldが見るバイナリを変更できるのがミソだね!

さて、これを使っても、何個もテストスクリプトがある時に一回一回mysqlを立ち上げ直してちゃ意味がない。遅いし、毎回DBの設定をしなくちゃいけないじゃないか!

だもんで、まずmake testが走るときに前もってTest::mysqldを起動させ、make test 終了とともにDBが停止するような仕組みをMakefile.PLに書いてみたわけさ!


Oh, how very unpleasantly hack-ish!

汚いけど、これでMakefileをいじっちゃうわけだね!ちなみにModule::Installも同じような力業でMakefileを編集してるよ!

ともあれこれでmake testとした時に自動的にMyApp::Test::mysqldが立ち上がるってわけさ。$SIG{INT} = \&exitってしておくのは、ユーザーがCtrl-Cした時にTest::mysqld::DESTROY()が走るようにするためのおまじないだよ!

mysqldが立ち上がったら、そこへの接続情報を$ENV{TEST_DSN}につっこんでおくわけさ。これでテスト側からこの値を参照するだけでDBに接続できるわけだね。

ここまで来たらもう一歩!

  • DBIx::Classを使ってるんだから、DBスキーマも自動的にdeployしたいじゃない!
  • それぞれのテストでTEST_DSN呼んだりするの面倒くさいよね!
  • 単体のファイルを実行した時は、mysqld起動+deployを各ファイルでやってほしいけど、make testの場合は1回だけ実行したい!

こんなワガママなキミはそれ用のラッパーを作ると便利かもね!そこでこんなMyApp::Testを書いたわけさ(3回目)!

ここでは僕の自家製DIコンテナOrochiってのを使ってるのでわからないことだらけかもしれないけど、重要なのは以下のことさ!

  • MyApp::Schemaは$self->assembler->get('schema/master')とすることにより、すでに生成されているならその値を、そうでなければあらたに生成した値を得ることができる。
  • MyApp::Schemaの生成には 'schema/master/connect_info'というデータが必要
  • connect_infoのDSN部分は、$ENV{TEST_DSN}が設定されているなら、それを利用する(mysqldはMakefileによって起動している)が、そうでないなら、自分でmysqldを立ち上げる。
  • その際、空のデータベースを立ち上げただけでは意味がないので、deployフラグもつけておく
  • deployフラグがたっている場合は、DIコンテナからschemaを取り出す際にdeployもしてしまう
こんなことをしておけば、make test時に一回一番最初だけに実行されるt/000_setup.tみたいなファイルを用意してMyApp::Test->new()->deploy()すればmake test中には一回しか起動+deployはされないし、各テスト実行時にもMyApp::Test->new()しておけばMyApp::Schemaを使用する時に自動的に同じ事が起こるわけさ!

じゃあもう眠いから、アディオス!

カテゴリ

トラックバック(0)

このブログ記事に対するトラックバックURL: http://mt.endeworks.jp/cgi-bin/mt-tb.cgi/2398

コメントする

筆者

daisuke - a.k.a. "lestrrat", Perl hacker at Livedoor Inc, Japan Perl Association 代表理事

このブログ記事について

このページは、Dが2009年10月16日 13:38に書いたブログ記事です。

ひとつ前のブログ記事は「乙嫁語り」です。

次のブログ記事は「ペスカトーレ」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.1