Edited at

Googleが提唱するTestSizeとJava,MavenによるTestSizeの実現方法について

More than 1 year has passed since last update.


TestSizeとは

テストから見えてくる グーグルのソフトウェア開発Google Testing Blogによると、Googleは開発者のテスト区分を統一する(それまではシステムテスト、EtoEテスト、UIテスト、Seleniumテストなどいろいろな表現があり、そのどれもがどのようなテストか明確に定義されない)ために、TestSizeという概念と導入し、それぞれ以下のように定義している。

S(Small)テスト
M(Medium)テスト
L(Large)テスト
E(Enormous)テスト

時間的目標(メソッドごと)
100ms未満で実行
1s 未満で実行
できる限り高速に実行
できる限り高速に実行

実行時間の上限
起動後1分経ったらSテストターゲットを強制終了
起動後5分経ったらMテストターゲットを強制終了
起動後15分経ったらLテストターゲットを強制終了
起動後1時間経ったらEテストターゲットを強制終了

Sテスト
Mテスト
Lテスト
Eテスト

ネットワークサービス(ソケットオープン)
モック
localhostのみ

データベース
モック


ファイルシステムアクセス
モック


ユーザと向かい合うシステムへのアクセス
モック
推奨されない

システムコール実行
×
推奨されない

マルチスレッド
推奨されない


sleep 文
×


システムプロパティ
×



TestSizeによる実行タイミングの分割

このTestSizeごとにテストの実行タイミングを定義することで、必要なフェーズで必要な分のテストが実行でき、素早くユーザへフィードバックすることができるようになる。

例えば、クックパッドの記事にならうと、以下のように実行タイミングをわけることができる。

このようにすることで、クックパッドではプルリクエストでテスト実行を5分以内に行い、早期にユーザへフィードバックすることを実現している。

Sテスト
Mテスト
Lテスト
Eテスト

実行タイミング
プルリクエストごとに
プルリクエストごと、もしくはMasterにマージされるごとに
任意、もしくはリリースごとに
任意、もしくはリリースごとに


Java,MavenによるTestSizeの実現

では、TestSizeとその実行タイミングの分割をどのように実現するか。

ここではJava,Mavenを使用した場合を解説する。


環境


  • Java:1.8.0_102

  • Apache Maven:3.3.9

  • JUnit:4.12

  • maven-surefire-plugin:2.19.1


Categoryクラスとアノテーションの付与

Javaの代表的なテストフレームワークであるJUnitには、JUnit4.8からCategoryというアノテーションが追加された。

テスト対象のメソッドやクラスに@Categoryをマークすることで、テストスイートから実行する対象を細かく制御できるようになる。

詳しくはこの記事を参照してほしい。

TestSizeごとのインターフェースを定義して、

定義したインターフェースを@Categoryの引数に渡すことでテスト実行対象を制御することができる。

package hogehoge;

public interface Small {}

package hogehoge;

public interface Medium {}

public class hoge {

@Category(Small.class)
@Test
public void a() {
fail();
}

@Category(Medium.class)
@Test
public void b() {
fail();
}
}


MavenによるTestSizeの指定方法

Mavenの実行時にTestSizeをパラメータとして渡せれば、TestSizeによる実行タイミングの分割は可能である。

できればこのようにできるとよい。

TestSizeの指定がなければ、全てのテストを実行し、TestSizeを一つもしくは複数指定でき、その場合は指定したTestSizeのテストが実行される。

mvn test // All tests run.

mvn test -P Small // Small tests run.
mvn test -P Small,Medium // Small and medium tests run.

上記を実現するMavenの設定は以下のようになる。

maven-surefire-plugingroupsにTestSizeを指定する。

デフォルトでは空を指定することで、引数を指定しない場合にすべてのテストが実行されるようにしている。

<project ...>

<properties>
<testcase.groups></testcase.groups>
</properties>

<profiles>
<profile>
<id>Small</id>
<properties>
<testcase.groups>hogehoge.Small</testcase.groups>
</properties>
</profile>
<profile>
<id>Medium</id>
<properties>
<testcase.groups>hogehoge.Medium</testcase.groups>
</properties>
</profile>
</profiles>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<argLine>-Dfile.encoding=UTF-8</argLine>
<groups>${testcase.groups}</groups>
</configuration>
</plugin>
</plugins>
</build>
</project>


まとめ

TestSizeの話はGoogle,クックパッドさんがよく記事にしてくれていますが、その実現方法について記載した記事がなかったので、記載しました。

何かの役にたてば光栄です。