§データベースを使用したテスト
データベースを含む完全なアプリケーションを起動することで、データベースアクセスコードをテストする機能テストを作成することは可能ですが、アプリケーションのほんの一部をテストするためだけに、より多くのコンポーネントを起動して実行することの複雑さから、完全なアプリケーションの起動はあまり望ましくありません。
Playは、アプリケーションの残りの部分から分離してデータベースでテストできるように、データベースアクセスコードのテストに役立つ多くのユーティリティを提供しています。これらのユーティリティは、ScalaTestまたはspecs2のいずれかで簡単に使用でき、データベーステストを、負荷が高く低速な機能テストよりも、軽量で高速なユニットテストに近づけることができます。
§データベースの使用
データベースバックエンドでテストするには、以下のものが必要です。
libraryDependencies += javaJdbc % Test
データベースに接続するには、少なくとも、Database
静的ファクトリメソッドを使用して、データベースドライバ名とデータベースのURLが必要です。たとえば、MySQLに接続するには、次のようにします。
Database database =
Databases.createFrom("com.mysql.jdbc.Driver", "jdbc:mysql:///test");
これは、`localhost`で実行されているMySQL `test`データベースの、`default`という名前のデータベース接続プールを作成します。データベースの名前は、Play内部でのみ使用されます。たとえば、他の機能(進化など)では、そのデータベースに関連付けられたリソースを読み込みます。
カスタム名パラメータまたはカスタム設定パラメータ、あるいはその両方を指定することで、カスタム名、ユーザー名、パスワード、Playがサポートするさまざまな接続プール設定項目などの設定プロパティなど、データベースの他の設定を指定することができます。
Database database =
Databases.createFrom(
"mydatabase",
"com.mysql.jdbc.Driver",
"jdbc:mysql:///test",
ImmutableMap.of(
"username", "test",
"password", "secret"));
データベースを使用した後は、データベースは通常、開いている接続を保持する接続プールによってバッキングされ、実行中のスレッドも持つ可能性があるため、シャットダウンする必要があります。これは、`shutdown`メソッドを呼び出すことによって行われます。
database.shutdown();
これらのメソッドは、JUnitの`@Before`アノテーションと`@After`アノテーションと組み合わせて使用すると特に便利です。次に例を示します。
Database database;
@Before
public void createDatabase() {
database = Databases.createFrom("com.mysql.jdbc.Driver", "jdbc:mysql:///test");
}
@After
public void shutdownDatabase() {
database.shutdown();
}
**ヒント:** これを使用して、使用するデータベースと接続方法を設定するために、環境変数またはシステムプロパティを使用して、テストデータベース設定を外部化できます。これにより、開発者は自分の環境を自由に設定できるようになり、開発とは異なる特定の環境を提供するCIシステムにも柔軟に対応できます。
§インメモリデータベースの使用
テストを実行するために、データベースなどのインフラストラクチャのインストールを必要としないことを好む人もいます。Playは、これらの目的のためにH2インメモリデータベースを作成するためのシンプルなヘルパーを提供しています。
Database database = Databases.inMemory();
インメモリデータベースは、カスタム名、カスタムURL引数、およびカスタム接続プール設定を提供することで設定できます。`MODE`引数を指定してH2に`MySQL`をエミュレートするように指示し、接続プールですべてのステートメントをログに記録するように設定する例を次に示します。
Database database =
Databases.inMemory(
"mydatabase", ImmutableMap.of("MODE", "MYSQL"), ImmutableMap.of("logStatements", true));
汎用データベースファクトリと同様に、インメモリデータベース接続プールは必ずシャットダウンしてください。
database.shutdown();
§進化の適用
テストを実行する場合、通常はデータベーススキーマをデータベース用に管理する必要があります。すでに進化を使用している場合は、テストで開発と本番で使用しているのと同じ進化を再利用するのが理にかなっていることがよくあります。テスト専用の進化を作成することもできます。Playは、Playアプリケーション全体を実行することなく、進化を適用および管理するための便利なヘルパーを提供しています。
進化を適用するには、Evolutions
静的クラスから`applyEvolutions`を使用できます。
Evolutions.applyEvolutions(database);
これは、`evolutions/<databasename>`ディレクトリのクラスパスから進化を読み込み、適用します。
テストの実行後、データベースを元の状態にリセットすることができます。進化のダウン スクリプトを、すべてのデータベース テーブルをドロップするように実装している場合は、`cleanupEvolutions`メソッドを呼び出すだけでこれを行うことができます。
Evolutions.cleanupEvolutions(database);
§カスタム進化
状況によっては、テストでカスタム進化を実行したい場合があります。カスタム進化は、カスタムEvolutionsReader
を使用して使用できます。これを行う最も簡単な方法は、`Evolutions`の静的ファクトリメソッドを使用することです。たとえば、`forDefault`は、デフォルトデータベースのEvolution
スクリプトの単純なリストの進化リーダーを作成します。次に例を示します。
Evolutions.applyEvolutions(
database,
Evolutions.forDefault(
new Evolution(
1,
"create table test (id bigint not null, name varchar(255));",
"drop table test;")));
カスタム進化のクリーンアップは、`cleanupEvolutions`メソッドを使用して、通常の進化のクリーンアップと同じ方法で行われます。
Evolutions.cleanupEvolutions(database);
ただし、ここではカスタム進化リーダーを渡す必要はありません。これは、進化の状態がデータベースに格納されており、データベースをティアダウンするために使用されるダウン スクリプトが含まれているためです。
カスタム進化スクリプトをコードに配置することが現実的でない場合があります。この場合、`fromClassLoader`ファクトリメソッドを使用して、テスト リソース ディレクトリに配置できます。
Evolutions.applyEvolutions(
database, Evolutions.fromClassLoader(getClass().getClassLoader(), "testdatabase/"));
これは、開発と本番の場合と同じ構造と形式で、`testdatabase/evolutions/<databasename>/<n>.sql`から進化を読み込みます。
進化スクリプトをプロジェクトフォルダの外に保存する場合は、EnvironmentEvolutionsReader
を使用して、ファイルシステム上の絶対パスまたはプロジェクトフォルダから見た相対パスからスクリプトを読み込むことができます。
import play.Environment;
import play.api.db.evolutions.EnvironmentEvolutionsReader;
// Absolute path
Evolutions.applyEvolutions(
database,
new EnvironmentEvolutionsReader(Environment.simple().asScala(), "/opt/db_migration"));
// Relative path (based on your project's root folder)
Evolutions.applyEvolutions(
database,
new EnvironmentEvolutionsReader(Environment.simple().asScala(), "../db_migration"));
§JUnitとの統合
通常、同じ進化で実行したいテストが多数あるため、進化のセットアップコードを、データベースのセットアップおよびティアダウンコードとともに、前後のメソッドに抽出するのが理にかなっています。完全なテストの例を次に示します。
import static org.junit.Assert.*;
import java.sql.Connection;
import org.junit.*;
import play.db.Database;
import play.db.Databases;
import play.db.evolutions.*;
public class DatabaseTest {
Database database;
@Before
public void setupDatabase() {
database = Databases.inMemory();
Evolutions.applyEvolutions(
database,
Evolutions.forDefault(
new Evolution(
1,
"create table test (id bigint not null, name varchar(255));",
"drop table test;")));
}
@After
public void shutdownDatabase() {
Evolutions.cleanupEvolutions(database);
database.shutdown();
}
@Test
public void testDatabase() throws Exception {
Connection connection = database.getConnection();
connection.prepareStatement("insert into test values (10, 'testing')").execute();
assertTrue(
connection.prepareStatement("select * from test where id = 10").executeQuery().next());
}
}
**次へ:** Webサービスクライアントのテスト
このドキュメントに誤りを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを送信してください。質問やアドバイスはありますか?コミュニティフォーラムにアクセスして、コミュニティとの会話を開始してください。