# テスト方針書

## 概要

本ドキュメントは、clojure-lspプロジェクトにおけるテスト戦略、テストレベル、使用ツール、およびCI/CDパイプラインでのテスト実行方針を定義するものです。clojure-lspはClojure/ClojureScript向けのLanguage Server Protocol (LSP) 実装であり、高い品質とクロスプラットフォーム互換性を確保するための包括的なテスト体制を構築しています。

## テスト戦略

### テストレベル

| レベル | 目的 | 担当 |
| --- | --- | --- |
| 単体テスト | 個々の機能・関数の動作検証。lib/test、cli/testディレクトリ配下で実行 | 開発者 |
| 結合テスト | 複数コンポーネント間の連携検証。LSPプロトコル経由でのend-to-end動作確認 | 開発者 |
| 統合テスト | 実際のプロジェクト構成（deps.edn、Leiningen、Boot、Shadow-cljs、Babashka）でのLSP機能検証 | CI/CD自動実行 |
| Pod テスト | Babashka Podとしての動作検証 | CI/CD自動実行 |

### テスト種別

| 種別 | 概要 | 実施タイミング |
| --- | --- | --- |
| 機能テスト | LSP機能（completion、rename、diagnostics、formatting等）の動作検証 | コミット・PR時 |
| リフレクションテスト | Javaリフレクション警告がないことの確認 | コミット・PR時 |
| クロスプラットフォームテスト | Linux、macOS、Windowsでの動作確認 | CI/CD実行時 |
| 静的解析 | clj-kondoによるlint、cljfmtによるフォーマットチェック | コミット・PR時 |
| GraalVM ネイティブイメージテスト | ネイティブバイナリでの統合テスト | CI/CD実行時 |

## テスト環境

| 環境 | 用途 | 構成 |
| --- | --- | --- |
| ローカル開発環境 | 開発時の単体テスト実行 | JDK 11以上、Clojure CLI、Babashka |
| GitHub Actions (ubuntu-22.04) | Linux環境でのテスト実行 | JDK 11, 15, 17, 19、Clojure CLI 1.12.0.1495、Babashka 0.9.161 |
| GitHub Actions (macos-latest) | macOS環境でのテスト実行 | JDK 11/17、Clojure CLI、Babashka |
| GitHub Actions (windows-latest) | Windows環境でのテスト実行 | JDK 11/17、Clojure CLI、Babashka |
| GraalVM環境 | ネイティブイメージビルド・テスト | GraalVM 21、musl対応（静的リンク用） |

## テストツール

| ツール | 用途 | バージョン |
| --- | --- | --- |
| Kaocha | テストランナー | 1.91.1392 |
| clojure.test | テストフレームワーク（標準） | Clojure 1.12.4同梱 |
| matcher-combinators | アサーションマッチャー | 3.9.2 |
| test.check | プロパティベーステスト | 1.1.3 |
| clj-kondo | 静的解析・lint | 2026.01.12 |
| cljfmt | コードフォーマッタ | 0.15.6 |
| Babashka | タスクランナー・統合テスト実行 | 0.9.161 |
| Cognitect test-runner | 代替テストランナー（オプション） | v0.5.1 |

## カバレッジ目標

| 対象 | 目標値 |
| --- | --- |
| 行カバレッジ | 明示的な目標値なし（テスト実行は必須） |
| 分岐カバレッジ | 明示的な目標値なし（テスト実行は必須） |

※ 本プロジェクトではカバレッジツールによる明示的な計測は設定されていませんが、機能単位での包括的なテストカバレッジが維持されています。

## テストデータ

テストデータは以下の方式で準備されます:

1. **インメモリデータ**: `clojure-lsp.test-helper`名前空間を使用し、テスト用コードをインメモリでロード・解析
2. **フィクスチャファイル**: `cli/integration-test/sample-test/`配下に各種プロジェクト構成のサンプルを配置
   - `sample-test/`: deps.ednベースのプロジェクト
   - `sample-test-lein/`: Leiningenプロジェクト
   - `sample-test-boot/`: Bootプロジェクト
   - `sample-test-shadow/`: Shadow-cljsプロジェクト
   - `sample-test-bb/`: Babashkaプロジェクト
3. **テストヘルパー**: `test-helper/`モジュールとして独立し、テスト用ユーティリティを提供

## 不具合管理

不具合はGitHub Issuesで管理されます。テスト失敗時のCI/CDパイプラインでの検出結果は、PRへのコメントおよびステータスチェックとして通知されます。

## CI/CD連携

### ワークフロー構成

| ワークフロー | トリガー | 内容 |
| --- | --- | --- |
| CI (`ci.yml`) | push (master), pull_request | lint、単体テスト、統合テスト、GraalVMビルド・テスト |
| Nightly (`nightly.yml`) | push (master) | 開発ビルドのリリース、クロスプラットフォームネイティブイメージビルド |
| Release (`release.yml`) | タグ作成時 | 本番リリースビルド |

### CIジョブ詳細

```yaml
lint:
  - namespaces clean check (bb lint-clean)
  - format check (bb lint-format)
  - diagnostics check (bb lint-diagnostics)

unit-test:
  - matrix: ubuntu-22.04 (JDK 11, 15, 17, 19), windows-latest (JDK 11), macos-latest (JDK 11)
  - command: bb test

jvm-integration-test:
  - matrix: ubuntu-22.04 (JDK 11, 15, 17), windows-latest (JDK 17), macos-latest (JDK 17)
  - commands: bb prod-cli, bb integration-test, bb pod-test

graalvm-build:
  - GraalVM 21 + musl（静的リンク）
  - UPX圧縮

graalvm-integration-test:
  - ネイティブバイナリでの統合テスト、Podテスト
```

### テスト実行コマンド

```bash
# 全単体テスト
bb test

# libモジュールのみ
bb test-lib

# cliモジュールのみ
bb test-cli

# リフレクションチェック
bb test-reflection

# 統合テスト（clojure-lspバイナリが必要）
bb prod-cli && bb integration-test

# Podテスト
bb pod-test

# Lint（dry run）
bb lint
```

## 備考

### テストアーキテクチャの特徴

1. **モジュール分離**: `lib/`（コアライブラリ）と`cli/`（CLIアプリケーション）で独立したテストスイートを持つ
2. **テストヘルパーの再利用**: `test-helper/`モジュールはMaven Centralにデプロイされ、外部プロジェクトでも利用可能
3. **クロスプラットフォーム対応**: Windows/Unix間のパス差異を吸収するヘルパー関数を提供
4. **LSPプロトコル準拠テスト**: 実際のLSPリクエスト/レスポンスをシミュレートする統合テスト

### テスト実装パターン

```clojure
;; 単体テストの例
(ns clojure-lsp.feature.xxx-test
  (:require
   [clojure-lsp.test-helper.internal :as h]
   [clojure.test :refer [deftest is testing]]))

(h/reset-components-before-test)

(deftest test-xxx
  (h/load-code-and-locs (h/code "(ns sample)" "(defn foo [])"))
  (testing "description"
    (is (= expected (function-under-test)))))
```

```clojure
;; 統合テストの例
(ns integration.xxx-test
  (:require
   [integration.fixture :as fixture]
   [integration.lsp :as lsp]
   [clojure.test :refer [deftest testing]]))

(lsp/clean-after-test)

(deftest xxx-test
  (lsp/start-process!)
  (lsp/request! (fixture/initialize-request {...}))
  (lsp/notify! (fixture/initialized-notification))
  (testing "description"
    (let [result (lsp/request! (fixture/xxx-request ...))]
      (h/assert-submap expected result))))
```
