PytestとJUnitでカバレッジ100%を達成する!

アイキャッチ画像

導入

単体テストにおいて「カバレッジ100%」という言葉はよく耳にしますが、実務では達成が難しいと感じる方も多いのではないでしょうか。
条件分岐や例外処理、外部サービスとの連携など、テストが複雑になる要素が多く、気づけば網羅できていないケースが発生します。

本記事では、Pythonの Pytest と Java の JUnit を用いて、実務でカバレッジ100%を達成するための具体的なテクニックをご紹介いたします。
「100%を目指すこと」ではなく、“抜けを防ぐための仕組みとして100%を活用する” という視点で解説いたします。

カバレッジ100%が難しい理由

カバレッジを100%にするためには、単にコードを呼び出すだけでは不十分です。
特に次のようなケースで抜けが発生しやすくなります。

  • 条件分岐が多いロジック
    • if文・三項演算子・ガード節など、分岐ごとにテストが必要です。
  • 例外処理の網羅不足 
    • 正常系だけテストして満足してしまい、例外系が抜けるケースが多く見られます。
  • 外部依存の存在
    • DB・外部API・メッセージキューなど、依存を切らないとテストが書けません。
  • 非同期処理や並列処理 
    • Pythonのasync/await、JavaのCompletableFutureなどは特に注意が必要です。

これらを丁寧にテストすることで、結果としてカバレッジが100%に近づきます。

Pytestで100%を達成するための実務テクニック

① fixtureで前提条件を統一する 

Pytestのfixtureは、テストの前準備を共通化できるため、テストの抜けを防ぎます。

@pytest.fixture
def client():
    return TestClient(app)

② mock / patch で外部依存を切る

外部APIやDBアクセスは unittest.mock.patch を使って切り離します。

@patch("service.fetch_data", return_value={"status": "ok"})
def test_handler(mock_fetch):
    assert handler() == "ok" 

③ 例外系テストを必ず書く  

正常系だけではカバレッジは伸びません。

with pytest.raises(ValueError):
    func(-1) 

④ パラメータ化で網羅性を上げる

境界値をまとめてテストできます。

@pytest.mark.parametrize("value", [0, 1, 100])
def test_range(value):
    assert validate(value)

JUnitで100%を達成するための実務テクニック 

① Mockitoで依存を切る  

外部APIやリポジトリはmock化してテストします。

when(repo.find()).thenReturn("OK");

② 例外テストは assertThrows

例外系を確実にテストできます。

assertThrows(IllegalArgumentException.class, () -> service.run(-1));

③ privateメソッドは“間接的に”テストする 

直接呼び出すのではなく、公開メソッドを通じて網羅します。

④ Jacocoでカバレッジを可視化

Maven/GradleでJacocoを有効化し、PR時にレポートを確認します。

import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

class RangeValidatorTest {

    @Test
    void testValidRange() {
        assertTrue(RangeValidator.validate(0));     // 最小値
        assertTrue(RangeValidator.validate(1));     // 最小値+1
        assertTrue(RangeValidator.validate(100));   // 最大値
    }

    @Test
    void testInvalidRange() {
        assertFalse(RangeValidator.validate(-1));   // 下限未満
        assertFalse(RangeValidator.validate(101));  // 上限超過
    }
}

カバレッジ100%を維持する運用

100%を達成しても、運用で下がってしまうことがあります。
次の仕組みを導入することで、品質を維持できます。

  • PR時(プルリクエストのタイミング)にカバレッジチェックを自動実行
  • カバレッジ低下を検知したらレビューで指摘
  • テスト観点表と連携し、抜けを防ぐ
  • バグ発生時は観点表とテストを更新する

まとめ

カバレッジ100%は「完璧なテスト」を意味するものではありません。 しかし、抜けを防ぐための強力な指標であり、PytestとJUnitを正しく使うことで実務でも十分達成可能です。 テストの仕組みを整え、継続的に改善することで、品質は確実に向上していきます。