前回の
Test::mysqldを使ったゲームサーバのテスト
多くのWebサービスや、
代表的な手法は、
ただ、
そこで使っているのが、
Test::mysqldでテスト専用のmysqldを起動する
DDLを実行したあとに、 テスト専用のmysqldを起動するときに気を付けるべき点もいくつかあります。 ローカルにある開発用のmysqldをテスト中でも用いる一般的な手法に比べ、 この問題に対処する最も良い方法は、 筆者の担当しているサービスのテーブル数は多く、 複数のテストを実行するときにも問題が起こります。テストファイルの中でmysqldを起動していると、 mysqldの起動時間のせいで、 そのために、 以下に、 このスクリプトを実行して表示された環境変数を作るコマンドを実行して、 テストコードでの例は次のようになります。 これで高速にmysqldが起動し、 mysqldの起動時間を短くする方法を挙げましたが、 使用するには、 テストファイルの中では、 テストファイルごとにmysqldが起動せず、 mysqldプロセスを再利用することに関して注意点があります。それは、 テーブルは流用できるので、 そのため、 あるいは、 そこで提案したいのが、 以下は、 トランザクションを実行してロールバックするのに比べて時間はかかりますが、 mysqldをプーリングするには、 mysqld専用である 使用するには、 そして、 テストの中では、 ただし、 などの手法が考えられます。 ただ、 いずれもメリット/ <続きの 2022年8月24日発売Test::mysqld
は、Test::mysqld
を用いてmysqldを起動するテストコードを次に示します。
use Test::mysqld;
use DBI;
use MyApp::GameLogic;
my $mysqld = Test::mysqld->new(); ―
Test::mysqld
でmysqldを起動します。そのあとに、$dbh
を作ります。ここで起動したmysqldにはデータベースtest
が存在しますが、CREATE
文などのDDL$dbh
をMySQLが使われるモデルオブジェクトに渡すと、Test::mysqld
を使うと、Test::mysqldの注意点
mysqldを起動するためのリソースを余分に消費する
テストが始まるまでの起動時間が長くなる
Test::mysqld
を使うと、CREATE
文の流し込みや、Test::mysqldの起動高速化のためにデータを流用する
Test::mysqld
によるmysqldの起動には時間がかかります。その大半が、ibdata
などのデータ領域を含んだディレクトリを作成することに費やされています。このディレクトリをテスト起動時に毎回作らないようにします。あらかじめ作成しておき、Test::mysqld
にはcopy_
オプションが存在します。これは、use Test::mysqld;
use File::Spec;
my $mysqld = Test::mysqld->new;
my $dbh = DBI->connect($mysqld->dsn);
$dbh->do($_) for @ddls;
$dbh->do($_) for @fixture_sqls;
$mysqld->stop;
say 'export TEST_MYSQLD_DATA_DIR='
. File::Spec->catdir($mysqld->data_dir, 'var');
my $mysqld = Test::mysqld->new(
copy_data_from => $ENV{TEST_MYSQLD_DATA_DIR}
);
App::Prove::Plugin::MySQLPoolによるプーリング
App::Prove::Plugin::MySQLPool
は、prove
向けのプラグインモジュールです。prove
の起動時に指定します。$ prove -PMySQLPool t/something.t
my $dbh = DBI->connect($ENV{PERL_TEST_MYSQLPOOL_DSN});
mysqldのプーリングを行う際の注意点
fail
することが考えられます。DBIx::TransactionManager
を用いれば、プーリングされたmysqldの初期化
DBIx::Inspector
を使用して、use DBIx::Inspector;
my $inspector = DBIx::Inspector->new(dbh => $dbh);
my @tables = $inspector->tables;
for my $table (@tables) {
my $table_name = $table->name;
$dbh->do("TRUNCATE TABLE $table_name")
or die $dbh->errstr;
}
Harrietを用いてプーリングを行う
App::Prove::Plugin::MySQLPool
は簡単にmysqldプロセスを再利用できるモジュールですが、copy_
などのオプションには対応していない点、Harriet
を使う方法もあります。Harriet
はApp::Prove::Plugin::MySQLPool
と同様、prove
のプラグインとして動作するモジュールです。ただし、App::Prove::Plugin::MySQLPool
と比べて、Harriet
では余計にコードを書く必要がありますが、Harrietの使用例
t/
に次のコードを書きます。use Harriet;
use Test::mysqld;
$ENV{TEST_MYSQLD_DSN} ||= do {
my $mysqld = Test::mysqld->new(
# 前述したスクリプトで作った
# 事前作成ディレクトリを指定できる
copy_data_from => ...,
);
$HARRIET_GUARDS::TEST_MYSQLD = $mysqld;
$mysqld->dsn;
};
$ prove -PHarriet t/something.t
App::Prove::Plugin::MySQLPool
のときと同様、TEST_
にDSNが入ります。これを用いて$dbh
を作ればMySQLにつなぐことができます。Harrietを使用した場合の注意点と解決策
t/
の中で複数個立てておき、Test::mysqld
には複数個のmysqldを一気に起動するstart_
メソッドがあるため、
prove
ではない並列実行を行う独自のテストコマンドを用いて、prove
を並列に走らせて結果を統合するコマンドであるgo-prove
を用いて実現しています。本誌最新号をチェック!
WEB+DB PRESS Vol.130
B5判/
定価1,628円
ISBN978-4-297-13000-8
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現!
いまはじめるFlutter
iOS/
作って学ぶWeb3
ブロックチェーン、