ホームページ >Java >&#&チュートリアル >開発/製品パリティ : Spring Boot テストコンテナ
開発/製品パリティは、開発環境と実稼働環境の間のギャップを減らすことを目的としています。この記事では、開発と運用を可能な限り類似させる方法として、特に Spring Testcontainers との統合テストにおけるツールのギャップを対象としています。
データベースを含む統合テストを実行する場合、すべての CRUD 操作を慎重に管理する必要があります。これは、TestDeleteUserByID_ShouldReturnOk() などのテストが、2015 年以来当社を利用してくれる最も忠実なクライアントのアカウントを「誤って」消去してしまう可能性がある集中型データベース環境では非常に重要です ?♂️
このようなリスクを軽減するには、テスト データを分離するためのデータベース トランザクションなどのソリューションを検討できます。たとえば、テストではデータを変更するトランザクションを開始し、最後にロールバックすることで、データベースを元の状態のままにすることができます。
ただし、これによって重大な問題が生じます: テストは何をテストするのか?
分離が失敗し、コードが何らかの理由でロールバックされない変更を実行し、実稼働環境へのデータ漏洩につながった場合はどうなるでしょうか?このようなシナリオでは潜在的な損害は重大です。
あるいは、H2DB などのインメモリ データベースを使用した自己完結型テストにもいくつかの課題があります。たとえセットアップが簡単であっても、H2DB は RDBMS とは異なるため、開発環境と本番環境でテストの結果が異なる可能性が高く、その結果を信頼することはできません。
https://stackoverflow.com/questions/62778900/syntax-error-h2-database-in-postgresql-compatibility
次に問題の少ない解決策は、データベースのクローンを作成することです。これにより、運用環境に似た環境でリスクの少ないアプローチが提供されます。ただし、この方法には限界があります。 ORM が運用データベース スキーマの作成とセットアップを自動化することを考えると、複製された開発データベースの同期を維持する方法を考える必要があります。
「Testcontainers は、JUnit テストをサポートする Java ライブラリで、一般的なデータベース、Selenium Web ブラウザ、または Docker コンテナ内で実行できるその他の軽量の使い捨てインスタンスを提供します。」
元々は Java 用に開発されましたが、その後 Go、Rust、.NET などの他の言語をサポートするように拡張されました。
Testcontainers の主なアイデアは、IDE から実行可能なオンデマンドのインフラストラクチャを提供することです。そこでは、モックやメモリ内サービスを使用せずに、自動クリーンアップを使用してテストを実行できます。
これは 3 つのステップで実現できます:
Testcontainers ライブラリのドキュメント
統合テストの基本クラスである ApplicationIntegrationTests で、静的な PostgreSQLContainer を定義します。このコンテナは、このクラスから派生したすべてのテスト インスタンスで使用されます。
@Testcontainers アノテーションを使用すると、@Container アノテーションが付けられたすべてのフィールドの検出、コンテナーのライフサイクル メソッドの管理、コンテナーの起動が可能になります。
@DynamicPropertySource アノテーションを使用すると、プロパティをテスト環境に動的に挿入できます。
@Testcontainers @ActiveProfiles("test") public abstract class ApplicationIntegrationTests { @Container protected static PostgreSQLContainer<?> postgres=new PostgreSQLContainer<>("postgres:17.2-alpine") .withDatabaseName("testcontainersproject") .withUsername("root") .withPassword("root"); @DynamicPropertySource static void initialize(DynamicPropertyRegistry registry) { registry.add("spring.datasource.url",postgres::getJdbcUrl); registry.add("spring.datasource.username",postgres::getUsername); registry.add("spring.datasource.password",postgres::getPassword); } }
あるいは、@Testcontainers と @Container の使用をスキップし、代わりに @BeforeAll と @AfterAll を使用してコンテナのライフサイクルを直接管理することもできます。このアプローチにより、コンテナーの開始と停止のタイミングと方法をより詳細に制御できるようになります
@BeforeAll public static void runContainer(){ postgres.start(); } @AfterAll static void stopContainers() { postgres.stop(); }
@AfterAll コールバック メソッドで、Postgres コンテナを明示的に停止します。ただし、コンテナを明示的に停止しなくても、Testcontainers はテスト実行の終了時にコンテナを自動的にクリーンアップしてシャットダウンします。
次のように ApplicationIntegrationTests を拡張することで、統合テストを作成できるようになりました。
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc public class CategoryControllerTest extends ApplicationIntegrationTests { private static final String CATEGORY_ENDPOINT="/categories"; @Autowired private MockMvc mockMvc; @Autowired private CategoryRepository categoryRepository; @Test void TestGetAllCategories_ShouldReturnOk() throws Exception { List<Category> categories = List.of( new Category("Electronics", "All kinds of electronic gadgets from smartphones to laptops"), new Category("Books", "A wide range of books from novels to educational textbooks") ); categoryRepository.saveAll(categories); MvcResult mvcResult=mockMvc.perform( get(CATEGORY_ENDPOINT). contentType(MediaType.APPLICATION_JSON) ) .andExpect(status().isOk()) .andReturn(); var response=mvcResult.getResponse().getContentAsString(); assertNotNull(response); assertFalse(response.isEmpty()); } }
以上が開発/製品パリティ : Spring Boot テストコンテナの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。