web-dev-qa-db-ja.com

Spring Boot / JUnit、複数のプロファイルに対してすべてのユニットテストを実行します

いくつかのテストで構成されるBaseTestクラスがあります。各テストは、リストしたすべてのプロファイルに対して実行されます。

次のようなパラメータ化された値を使用することを考えました。

@RunWith(Parameterized.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
// @ActiveProfiles("h2-test") // <-- how to iterate over this?
public abstract class BaseTest {

@Autowired
private TestRepository test;

// to be used with Parameterized/Spring
private TestContextManager testContextManager;

public BaseTest(String profile) {
   System.setProperty("spring.profiles.active", profile);
   // TODO what now?
}

@Parameterized.Parameters
public static Collection<Object[]> data() {
  Collection<Object[]> params = new ArrayList<>();
  params.add(new Object[] {"h2-test" });
  params.add(new Object[] {"mysql-test" });
  return params;
}

@Before 
public void setUp() throws Exception {
  this.testContextManager = new TestContextManager(getClass());
  this.testContextManager.prepareTestInstance(this);
  // maybe I can spinup Spring here with my profile?
}

@Test
public void testRepository() {
  Assert.assertTrue(test.exists("foo"))
}

これらの異なるプロファイルで各テストを実行するようにSpringに指示するにはどうすればよいですか?実際、各プロファイルは異なるデータソース(メモリ内h2、外部mysql、外部Oracle、..)と通信するため、リポジトリ/データソースを再初期化する必要があります。


@ ActiveProfiles(...)を指定でき、BaseTestから拡張して、ActiveProfileアノテーションをオーバーライドすることもできます。これは機能しますが、テストスイートの一部しか表示しません。テストがたくさんあります。 -クラスはBaseTestから拡張されており、クラスごとにいくつかの異なるプロファイルスタブを作成したくありません。現在は機能していますが、醜い解決策です:

  • BaseTest(@ActiveProfiles( "mysql"))
    • FooClassMySQL(BaseTestからの注釈)
      • FooClassH2(@ActiveProfiles( "h2"))
    • BarClassMySQL(BaseTestからの注釈)
      • BarClassH2(@ActiveProfiles( "h2"))

ありがとう

10
Frame91

Mavenを使用する場合は、実際にコマンドライン(または必要に応じて環境変数)からアクティブなプロファイルを指定できます。

_mvn clean test -Dspring.profiles.active=h2-test
_

Springがコンテキストを起動する前にプロファイルを指定する必要があるため、この場合、パラメーター化されたテストを使用したアプローチは機能しない可能性があります。この場合、パラメーター化された統合テストを実行すると、テストランナーがテストの実行を開始する前に、コンテキストが既に起動されます。また、JUnitのパラメーター化されたテストは、他の理由で発明されました(異なるデータ系列でユニットテストを実行する)。

編集:またもう1つ-@RunWith(Parameterized.class)を使用することにした場合、別のランナーを使用することはできません。多くの場合(統合テストに関してはすべてではないにしても)、_SpringRunner.class_のように別のランナーを指定する必要があります。パラメーター化されたテストではそれを実行できません。

3
Szymon Stepniak

Springプロファイルはこのように機能するようには設計されていません。
あなたの場合、各プロファイルは特定のデータソースを使用します。
したがって、予想されるデータソースでテストを実行するには、それぞれにSpringBootのロードが必要です。

実際、やりたいことは、テストしたいSpringプロファイルと同じ数のMavenビルドを作成するようなものです。

さらに、ローカル環境でのビルドは可能な限り高速にする必要があります。
自動テストの実行にDBMS実装を掛けて、それぞれにSpringBootのリロードが必要な場合は役に立ちません。

@ActiveProfilesを指定する必要はありません。

これは、特定のSpring Bootプロファイルを指定することで、各Mavenビルドを(順次または並列に)実行するジョブを定義できる継続的インテグレーションツールのタスクのように見えます。

mvn clean test -Dspring.profiles.active=h2

mvn clean test -Dspring.profiles.active=mysql

等...

Mavenビルドの実行を実行するスクリプトを作成して、ローカルで実行することもできます。
しかし、前述のように、ローカルビルドの速度が低下し、複雑になります。

4
davidxxx