スマートスタイル TECH BLOG|データベース&クラウドの最新技術情報を配信

MySQL Test FrameworkでMySQLを検証しよう

MySQL Test Frameworkとは、Unix/Linux用のMySQLのためのリグレッションテスト用フレームワークです。

https://dev.mysql.com/doc/refman/8.0/en/mysql-test-suite.html

MySQL/MariaDB/Percona Serverで提供されており、Tar ball、もしくはバイナリパッケージ(rpm, deb等)で提供されています。

数多くのテストスイート(一連のテストプログラムを実行するセット)が同梱されており、事前定義済みのMySQL専用のテストを再利用しつつ効率的に独自のテストも実装する事ができます。

今回は簡単に使用方法について検証したいと思います。

MySQL Test Frameworkのインストール

MySQL Test Frameworkのドキュメントは以下にあります。

MySQL

MariaDB

今回は、検証環境にCentOS7を使用しましたので、まずはRPMをインストールします。

バイナリパッケージは、 [package prefix name]-test という名称で提供されています。

インストールされる主なプログラムは以下です。

プログラム名 説明
mysql-test-run.pl テストスイートを実行するためのPerlスクリプトです。mtrというシンボリックリンクが用意されています
mysql-stress-test.pl ストレステスト用のPerlスクリプトです。
mysqltest 実際にテストを実行するためのC++プログラムです。mysql-test-run.plからはこのプログラムが呼び出されています。

mtrはインストール時に作成されたmysql-testディレクトリで実行される事を想定しています。
事前にmysql-testディレクトリに移動しましょう。

テストケースを構成するファイル

基本的なテストに使用するファイルとしては以下があります。
インストール先にはtrという名称のディレクトリがありますが、tはtest、rはresult用のファイルが格納されています。

ファイル名 説明
t/[test name].test テスト本体のファイルです
r/[test name].result テスト実行後の想定される結果テキストファイルです
t/[test name]-(master/slave/client).opt テスト実行時に作成されるmysqld(master/slave)やクライアントで使用するパラメータ
t/[test name]-(master/slave).sh テスト実行時のmysqldインスタンス(master/slave)ごとに実行されるスクリプト
t/[test name].inc 別のテストからインクルードされるテストスクリプト

また、テスト実行後の結果は [install dir]/var 配下に格納されます。

以下のように同じテストのファイル名は.incを除いて同じテスト名にします。

1つのテストは少なくとも同じ名称のtestファイルとresultファイルが必要になります。

testファイルには一連のコマンドを、resultファイルには、期待される標準出力の結果を記載します。

テストの作成

早速、簡単なテストケースを作成します。

select 1 というテストの結果が、select_one.resultの内容と同じかを確認します。

テストを実行するときは、テスト名をmtrに指定します。
mtrはmysqldを必要に応じて起動してテストを実行します。

実行したテストで使用したmy.cnf、datadir、ログ等は、 [install dir]/var に格納します。
一般ユーザで実行する場合は、任意の権限を持つディレクトリを --vardir に指定する必要があります。

一般ユーザで実行する際の注意点として、すでに [install dir]/var にディレクトリが存在した場合、実行時にクリーンアップが行われるため権限エラーが発生します。
その場合は、rootユーザで該当のディレクトリを削除/移動してからテストを実行してください。

テストは無事成功したようなので、次は失敗させてみましょう。
.resultファイルの1を2に変更してみました。

期待された結果が異なる事が報告され、Diffが表示されました。
テストを実行した際の結果ログは [install dir]/var/log 以下に格納されています。
出力される主なログは以下です。

ログファイル名 説明
bootstrap.log mysqld起動時のオプションと起動ログを出力
mysqld.[n].err テストに使用したmysqldのエラーログ
mysqltest.log 実行した全テスト結果を格納するログ
[testname].reject テストが失敗した際の標準出力
[suite name].[test name] テストごとに使用されるファイル等を格納するディレクトリ

テストスイートの作成

一連のテストをまとめたテストスイートを定義してみます。

テストスイートはsuiteディレクトリ配下の任意の名称のディレクトリです。
原則としてr,tのディレクトリを含み、一連のテストを格納します。

それではまた簡単なテストを格納したテストスイートを作成してみましょう。

--suite でテストスイート名を指定すると2つのテストが実行されます。

suiteディレクトリ配下には数多くのテストスイートが存在します。
中には今をときめくclone pluginのテストスイートなどもありますので、 t/*.test のファイルを確認すると、どのように実行することを想定しているのかという事の理解の助けになります。

また、テストケースにはコーディングガイドラインがありますが、自作のテストケースの参考として利用するのもよいと思います。

外部データベースに対するテストの実行

mtrは内部的にmysqldを起動してテストを実行することを想定しています。
ですが、プリセットされたデータベースに対してテストしたいというニーズは一定数あるかと思います。

起動済みのデータベースに対するテストを行うには、 --extern オプションを指定します。
--extern オプションを付けて実行された場合は、mtrはmysqldインスタンスを作成しません。

--extern を使用する事により意図しないデータの変更等を避けるために、以下のページに注意点がまとめられています。

https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_NAMING_CONVENTIONS.html

今回、稼働済みの環境に対してテストを実行するために、以下の作業を行います。

  • test データベースの作成
  • テスト用ユーザの作成と必要な権限の付与

外部データベースは、mysql-testとは異なるサーバ(mysql2)としました。

それではテストを実行してみます。

想定どおり成功しました。

外部データベースでは、起動済みであるために初期化時に読み込まれる.optファイルが使用できない、ローカルでの実行前提である.shが実行できない等の制限がありますので、
シンプルな用途のみに利用する事をお勧めします。

まとめ

今回は、MySQL Test Frameworkの簡単な動作について検証しました。

再現テストや設定確認等、アイデア次第で様々な用途に利用ができると思います。

MySQL Test Frameworkは基本的にはSQLで構成されますが、制御構文や外部スクリプトの実行、Perl構文の埋め込み等にも対応していますので、興味がありましたら
mysqltest Language Referenceをご確認ください。

ぜひMySQLの健康管理にご利用ください。


MySQL

 

Return Top