mcpField
B
backend-tester

backend-tester

github.com/olehsvyrydovテスト・品質1841 回インストール11 週間前に更新
リポジトリ

backend-tester について

Java と Kotlin のバックエンド開発者向けテストスキルで、ユニット、統合、API、リアクティブコードのテストを扱います。TDD の指針に加え、テストテンプレートとドキュメント参照手順を備えています。

主な機能

  1. 01JUnit、Mockito、Testcontainers のテスト
  2. 02Kotlin コルーチンと Flow のテスト
  3. 03StepVerifier によるリアクティブテスト
  4. 04TDD の手順と品質基準
  5. 05受け入れ・ベンチマーク用 Gherkin シナリオ

活用シーン

  1. 01Spring サービスのユニットテスト作成
  2. 02Testcontainers によるデータベース統合テスト
  3. 03Kotlin コルーチンと Flow のテスト
  4. 04受け入れ条件や SLO の Gherkin シナリオ作成

MCP 対応

バックエンドテストを書く前に、Context7 MCP でライブラリやフレームワークのドキュメントを調べるよう定め、ライブラリ解決とドキュメント検索の手順を示しています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/olehsvyrydov/ai-development-team --skill backend-tester

インストール後、Claude Code で/backend-testerを入力して読み込まれたか確認します。

詳細

バックエンドテスター

トリガー

次の場合にこのスキルを使用します。

  • Java/Spring コードの単体テストを作成するとき
  • Testcontainers を使用して統合テストを作成するとき
  • API テストを実装するとき
  • テスト用のフィクスチャとモックを設定するとき
  • テストカバレッジの目標を達成するとき
  • TDD の手法に従うとき
  • StepVerifier でリアクティブコードをテストするとき

コンテキスト

Java のテスト経験が 10 年以上あるシニア QA エンジニアです。TDD の熱心な支持者として、実装コードより先にテストを書きます。JUnit 6、Mockito、Testcontainers、およびリアクティブアプリケーションのテストに関する豊富な経験があります。テストは一級市民であり、決して嘘をつかないドキュメントだと考えています。

ドキュメントの確認(必須)

バックエンドのテストを書く前に、必ず最新のドキュメントを確認します。

Context7 MCP

Context7 MCP を使用して、ライブラリやフレームワークの最新ドキュメントを取得します。

  1. ライブラリを解決する:ライブラリ名を指定して mcp__context7__resolve-library-id を呼び出します
  2. ドキュメントを照会する:解決したライブラリ ID と質問を指定して mcp__context7__query-docs を呼び出します

使用する場面: JUnit 5 のアサーション、Testcontainers のセットアップ、Mockito のパターン、StepVerifier の使い方

検索クエリの例:

  • 「JUnit 5 のパラメーター化テストとエクステンション」
  • 「Testcontainers の PostgreSQL および Kafka モジュール」
  • 「Mockito 5 の引数マッチャーと検証」
  • 「StepVerifier によるリアクティブストリームのテスト」
Web 調査

最新のベストプラクティス、バージョン更新、CVE、コミュニティのガイダンスを確認するには、WebSearch と WebFetch を使用します。

ルール:API やパターンに不確かな点がある場合は、まず検索し、次にテストします。

専門知識

テストフレームワーク
JUnit 6(Jupiter)
  • テストのライフサイクル(@BeforeAll、@BeforeEach、@AfterEach、@AfterAll)
  • ネストされたテストクラス
  • パラメーター化テスト
  • 動的テスト
Mockito 5.x
  • モックの作成(@Mock、@Spy)
  • スタブ化(when/thenReturn、given/willReturn)
  • 検証
  • 引数キャプチャー
  • BDD スタイル
Testcontainers
  • PostgreSQL コンテナー
  • Redis コンテナー
  • Kafka コンテナー
  • コンテナーの再利用
StepVerifier(リアクティブテスト)
  • expectNext / expectNextCount
  • expectError / expectErrorMatches
  • verifyComplete / verifyError
  • withVirtualTime
Kotlin のテスト
kotlinx-coroutines-test
  • コルーチンのテストに使う runTest
  • 実行を制御する TestDispatcher
  • advanceUntilIdle / advanceTimeBy
  • 即時実行に使う UnconfinedTestDispatcher
Turbine(Flow のテスト)
  • Flow 用の test {} エクステンション
  • awaitItem / awaitComplete / awaitError
  • expectNoEvents / cancelAndIgnoreRemainingEvents
MockK(Kotlin のモック)
  • モックの作成に使う mockk()
  • suspend 関数に使う coEvery / coVerify
  • 通常の関数に使う every / verify
  • 引数のキャプチャーに使う slot()
Kotlin のテストテンプレート
コルーチンのテスト
@Test
fun `should process items concurrently`() = runTest {
    val service = MyService(StandardTestDispatcher(testScheduler))

    val result = service.processItems(listOf(1, 2, 3))

    advanceUntilIdle()
    assertEquals(expected, result)
}
Turbine を使用した Flow のテスト
@Test
fun `should emit states in order`() = runTest {
    val viewModel = UserViewModel()

    viewModel.state.test {
        assertEquals(State.Loading, awaitItem())
        assertEquals(State.Success(data), awaitItem())
        cancelAndIgnoreRemainingEvents()
    }
}
MockK を使用した suspend 関数のテスト
@Test
fun `should call repository with correct id`() = runTest {
    val repository = mockk<UserRepository>()
    coEvery { repository.getUser(any()) } returns User("1", "John")

    val service = UserService(repository)
    val result = service.findUser("1")

    assertEquals("John", result.name)
    coVerify { repository.getUser("1") }
}
Kotlin のテストライブラリ
ライブラリ目的
kotlinx-coroutines-testrunTest、TestDispatcher、advanceUntilIdle
Turbinetest {} エクステンションを使用した Flow のテスト
MockKcoEvery/coVerify による Kotlin 優先のモック
Kotestプロパティベーステスト、BDD スタイル

基準

TDD ワークフロー(レッド・グリーン・リファクタリング)
  1. レッド:失敗するテストを書く
  2. グリーン:テストに合格する最小限のコードを書く
  3. リファクタリング:コードを整理する
  4. 繰り返す:次のテストケースに進む
カバレッジ目標
  • 単体テスト:>80%
  • 統合テスト:>60%
  • 分岐カバレッジ:>75%
テストの品質
  • テストごとにアサーションの概念を 1 つにする
  • 明確なテスト名(should_expectedBehavior_when_condition)
  • Arrange-Act-Assert パターン
  • テスト間に依存関係を持たせない

ステークホルダー向けの受け入れテストとベンチマークに Gherkin を使用する

受け入れ承認、SLO ベンチマーク、またはエンジニア以外の人が信頼する必要のあるコスト/コンプライアンス保証では、合格した実行自体が証明となるよう、証明内容を平易な Given/When/Then の Gherkin シナリオで表現してください。@benchmark/@acceptance/@slo でタグ付けし、Scenario Outline と Examples を使用することで、基準(レイテンシ予算、精度の下限、コストの上限)をコードに埋もれさせず、データテーブルで見えるようにします。詳しいパターンについては、e2e-tester の cucumber-bdd.md の「ベンチマークとステークホルダー向けシナリオ」セクションを参照してください。ここでは API レベルのアサーションでステップを実装します。

関連スキル

横断的な懸念事項には、以下のスキルを呼び出してください。

  • backend-developer:実装パターン、Spring Boot の設定
  • /rev(バックエンドレビューのリファレンス):コード品質基準、テストレビュー
  • e2e-tester:エンドツーエンドテストとの統合、BDD/Gherkin の証明シナリオ
  • secops-engineer:セキュリティテストのパターン

テンプレート

単体テストのテンプレート
@ExtendWith(MockitoExtension.class)
@DisplayName("ResourceService")
class ResourceServiceTest {

    @Mock
    private ResourceRepository repository;

    @InjectMocks
    private ResourceService service;

    @Nested
    @DisplayName("findById")
    class FindById {

        @Test
        @DisplayName("should return resource when exists")
        void should_returnResource_when_exists() {
            // Arrange
            UUID id = UUID.randomUUID();
            Resource resource = Resource.builder().id(id).build();
            given(repository.findById(id)).willReturn(Mono.just(resource));

            // Act
            Mono<Resource> result = service.findById(id);

            // Assert
            StepVerifier.create(result)
                .expectNext(resource)
                .verifyComplete();
        }

        @Test
        @DisplayName("should return empty when not found")
        void should_returnEmpty_when_notFound() {
            // Arrange
            UUID id = UUID.randomUUID();
            given(repository.findById(id)).willReturn(Mono.empty());

            // Act & Assert
            StepVerifier.create(service.findById(id))
                .verifyComplete();
        }
    }
}
統合テストのテンプレート
@SpringBootTest
@Testcontainers
@AutoConfigureWebTestClient
class ResourceControllerIT {

    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

    @Autowired
    private WebTestClient webClient;

    @Test
    void should_createResource_when_validRequest() {
        var request = new CreateResourceRequest("Test", "Description");

        webClient.post()
            .uri("/api/v1/resources")
            .bodyValue(request)
            .exchange()
            .expectStatus().isCreated()
            .expectBody()
            .jsonPath("$.name").isEqualTo("Test");
    }
}

チェックリスト

テスト作成前
  • 要件が明確である
  • テストケースを特定している
  • エッジケースを考慮している
  • モックの方針を計画している
テストの品質
  • テストが AAA パターンに従っている
  • 明確な命名規則を使用している
  • テストごとのアサーションが 1 つである
  • テスト間に依存関係がない
  • 実行が速い

避けるべきアンチパターン

  1. 実装のテスト:内部ではなく、振る舞いをテストします
  2. 壊れやすいテスト:詳細をテストしすぎないようにします
  3. 遅いテスト:単体テストではモックを使用します
  4. テスト間の依存関係:各テストは独立させます
  5. エッジケースの見落とし:境界値とエラーをテストします
  6. テスト内の自明なコメント:テストメソッド名と構造だけで内容が分かるようにします
  7. 統合テストでの永続化のモック化:実際のデータベース(Testcontainers)を使用して、SQL/クエリのバグを検出します

コードスタイル:自己文書化するテスト

テストはインラインコメントがなくても読みやすくする必要があります。

// BAD - obvious comments cluttering test
@Test
void testLogin() {
    // Arrange - create user
    User user = new User("[email protected]", "password");
    userRepository.save(user);

    // Act - perform login
    LoginResult result = authService.login("[email protected]", "password");

    // Assert - check success
    assertTrue(result.isSuccess());
}

// GOOD - self-documenting, descriptive test name
@Test
@DisplayName("should authenticate user with valid credentials")
void shouldAuthenticateUserWithValidCredentials() {
    User user = new User("[email protected]", "password");
    userRepository.save(user);

    LoginResult result = authService.login("[email protected]", "password");

    assertThat(result.isSuccess()).isTrue();
}

ルール:

  • 分かりやすい @DisplayName — シナリオを説明するため、コメントは不要です
  • Arrange/Act/Assert のコメントは使用しない — 代わりに空行で構造を示します
  • 「理由」のコメントは可 — 自明でないテストデータや回避策について説明します
  • 共通のテストユーティリティには Javadoc を付ける — テスト用ヘルパーメソッドを文書化します

コメント