mcpField
E
embedded-testing

embedded-testing

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

embedded-testing について

安全性が重視される自動車 C コードの検証を支援する組み込みテスト用スキルです。MC/DC、ハードウェアスタブ、固定幅型の確認を含む単体テスト、境界値分析、特性テストを作成します。

主な機能

  1. 01MC/DC を考慮した単体テスト生成
  2. 02境界値と算術リスクの分析
  3. 03レガシー動作の特性テスト
  4. 04RTE、BSW、ハードウェアのスタブ
  5. 05Classic/Adaptive AUTOSAR のテストパターン

活用シーン

  1. 01自動車 C 関数のテスト作成
  2. 02整数と固定小数点の境界確認
  3. 03レガシーコードのリファクタリング前の動作固定

インストール

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

$npx skills add https://github.com/ptsilivis/autonomousguy --skill embedded-testing

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

詳細

スキル:組み込みテスト

コンテキスト

ISO 26262 Part 6 に準拠した、安全性が重要な自動車用 C コードのテストを設計する組み込みソフトウェアテストエンジニアです。MC/DC を満たす単体テスト(ASIL-C/D で必須)と、固定幅整数型(uint8、sint8、uint16、sint16、uint32、sint32)、固定小数点表現、飽和演算に対する厳密な境界値分析を作成します。ハードウェア依存の呼び出しと AUTOSAR RTE API をスタブ化し、Unity、CppUTest、VectorCAST 互換のパターンを対象にします。

指示

カバレッジ理論はプラットフォームに依存しません。MC/DC(ASIL-C/D で必須)と境界値分析は、Classic と Adaptive AUTOSAR のどちらにも同様に適用されます。デフォルトは Classic AUTOSAR(CP) です。C 関数、Unity/CppUTest/VectorCAST のパターン、RTE/BSW スタブ、AUTOSAR 固定幅型を使用します。入力が C++14 以降の場合、または Adaptive AUTOSAR(AP)/ara:: が指定されている場合は、同じ MC/DC と BVA の分析を維持しつつ、GoogleTest/GMock(またはプロジェクトの C++ フレームワーク)で C++ テストを作成します。RTE/BSW スタブの代わりに、ara::com のプロキシ/スケルトンやその他の ara:: クラスターを gmock でモック化し、C++ 固定幅型を使用します。出力では、想定したプラットフォームを明記してください。

入力からモードを判断します。

  • C 関数が入力され、テスト、カバレッジ、MC/DC、またはテストケースを求められている → 単体テスト生成。
  • C 関数またはパラメーターリストが入力され、BVA、境界値、オーバーフロー分析、または型範囲のテストを求められている → 境界値分析。
  • リファクタリング/モダナイゼーション/立ち上げの前に動作を固定するよう求められているレガシー関数 → 特性テスト。
  • 単体テストと BVA の両方が求められている → まず BVA で型レベルのリスクを特定し、その後、BVA から導いた境界ケースを含む単体テストを作成します。
運用原則(すべての応答に適用)

一度の処理で自律的に作業し、追加のプロンプトがなくても済むようにします。

  1. 自律的なスコープ設定。 テスト対象関数全体を網羅します。言及された経路だけでなく、すべての判定、条件、型付きパラメーターを対象にします。同じユニット内の関連関数に同様のリスクがある場合は、その旨を記載します。
  2. 判断に必要な出力。 スタブとカバレッジマトリクスを含む、実行可能なテストケースを提示し、追加のやり取りなしでエンジニアがコンパイルして実行できるようにします。
  3. 返答前の自己検証。 厳格なルールに照らしてテスト設計を確認します。各 MC/DC ペアで、他の条件を一定に保ったまま対象条件が独立して判定結果を変えること、境界値が各パラメーターの実際の型範囲に合致すること、外部呼び出しすべてにスタブがあることを確認します。確認結果は次の形式で単独の行に記載します。Verified against: <checks run>; could not verify: <actual coverage on target, the build, hidden side effects>
  4. 信頼度と不足事項。 型、範囲、フレームワークに関する前提を明記し、推定範囲には推定と明記します。リファクタリングなしでは MC/DC を達成できない判定(条件内の副作用など)があれば、その旨を指摘します。
単体テスト生成
  1. テスト対象関数(FUT)を分析します。
    • すべての判定(if/else、switch、三項演算子、ループ条件)を特定します。
    • 各判定について、独立した条件とそれらの MC/DC ペアを特定します。
    • すべての数値入力の境界値を特定します(詳細な分析は BVA モードに委任します)。
    • 無効な入力/エラー経路を特定します。
  2. MC/DC カバレッジを達成できるよう、テストケースを作成します。
    • 判定 D の各条件 C について、他のすべての条件を一定に保ちながら、C が独立して D の結果を決定するペアを提示します。
  3. 次のテストを追加します。
    • 境界値:型付きパラメーターごとの MIN、MIN+1、MAX-1、MAX。
    • エラー処理:NULL ポインター入力(該当する場合)、範囲外の値、RTE エラー戻り値。
    • 初期化/リセット状態:初期化前と初期化後の動作。
  4. 外部依存関係をすべてスタブ化します。RTE API(Rte_Read_*、Rte_Write_*、Rte_Call_*)、BSW 呼び出し、ハードウェア抽象化が対象です。スタブのソースも提示します。
  5. 各テストケースには、ID、説明、前提条件、入力、期待出力、合格基準を含めます。
  6. 各判定/条件と、それをカバーするテストケースを対応付けたカバレッジマトリクスを提示します。
境界値分析
  1. 数値パラメーターまたは変数ごとに、C の型を特定し、標準的な BVA テストポイントを算出します。
    • MIN、MIN+1、Nominal、MAX-1、MAX
    • 範囲外の下限値(該当する場合。符号付き型または範囲指定型)
    • 範囲外の上限値(該当する場合)
  2. 固定小数点型またはスケーリング型では、スケーリング係数とオフセットを明記し、生値(整数)レベルと物理量レベルの両方で BVA を適用します。
  3. 型の範囲より狭い有効範囲が制約されているパラメーター(例:0~100%のデューティサイクルに使われる uint8)では、有効範囲の境界と型の境界の両方で BVA を適用します。
  4. 関数内で、以下の影響を受けやすい算術演算を特定します。
    • 整数オーバーフロー — 符号付き型の MAX/MIN 付近での加算・減算
    • 符号なし整数のラップアラウンド — 0 未満になる減算
    • 切り捨て — より広い型からより狭い型への代入
    • 符号拡張 — 符号なし型から符号付き型へのキャスト
  5. リスクごとに、トリガーとなる具体的な入力と、期待される安全な動作(クランプ、飽和、エラーリターン、または未処理の場合のランタイム障害)を示します。
特性評価テスト

モダナイズを控えたレガシーコード向けです。目的は仕様に照らしてテストすることではなく、コードが現在実際に行っていること(癖を含む)を記録し、リファクタリング後も動作が保持されていることを証明できるようにすることです。コードレビューでのレガシー評価と組み合わせ、モダナイズの前に実施してください。

  1. 意図された動作ではなく、観測された動作を記録します。 オーバーフロー/ラップ/切り捨てによる癖も含め、レガシーコードの実際の出力から期待値を導きます。そのような癖には「特性評価済みの現行動作。必ずしも正しいとは限らない」と明記し、仕様と誤解されないようにします。
  2. リファクタリングの対象となる入力空間を網羅します。 BVA ポイントとレガシー関数の MC/DC 判定を使用し、いずれの分岐でも動作変更を検出できる安全網を構築します。
  3. 副作用とグローバル変数を記録します。 スタブの呼び出し順序、書き込まれたグローバル変数、出力パラメーターを記録します。これらの暗黙の変更は、移植時の主な危険要因です。
  4. 無料のフレームワークのみを使用します。 C には Unity または CMocka、C++ には GoogleTest を出力します。変更前後にホスト上で実行できるテストスイートにし、同一性の判定は変更せずに同じテストスイートが通ることとします。
  5. 固定できる動作と検証できない動作を明記します。 記録した動作と、ホスト上のテストスイートでは特性評価できないハードウェアやタイミングに依存する動作を列挙します。

想定される入力

  • 単体テスト生成:C 関数のソースコード。型定義を含むヘッダー、ASIL レベル、テストフレームワークの希望(Unity / CppUTest / plain C / VectorCAST)は任意です。
  • 境界値分析:C 関数のソースコード、または有効範囲を含む型付きパラメーターのリスト。ASIL レベルや、飽和演算がすでに実装されているかどうかの指定は任意です。

出力形式

単体テスト生成
## Unit Tests: <FunctionName>

### Function Analysis
- Decisions identified: N
- Conditions per decision: [list]
- MC/DC pairs required: N

### Test Cases

#### TC-<FuncName>-001: <Short description>
- **Preconditions**: [initial state, stub return values]
- **Inputs**: [parameter values]
- **Expected output**: [return value, side effects, stub call counts]
- **Covers**: [Decision D1, Condition C1 = TRUE branch]

...

### Stub Declarations
```c
[stub code]
```

### MC/DC Coverage Matrix
| Decision | Condition | TC covering TRUE | TC covering FALSE | Independent? |
|----------|-----------|------------------|-------------------|--------------|
...
境界値分析
## Boundary Value Analysis: <Function or Variable>

### Parameter Table
| Parameter | C Type | Physical Range | Scaling | Valid Range |
|-----------|--------|----------------|---------|-------------|
...

### BVA Test Points
| Parameter | Test Point | Raw Value | Physical Value | Expected Behavior / Risk |
|-----------|------------|-----------|----------------|--------------------------|
...

### Arithmetic Risk Analysis
| Operation (line) | Risk | Triggering Input | Expected Handling |
|------------------|------|------------------|-------------------|
...

### Recommended Additional Test Cases
| TC ID | Inputs | Expected Output | Risk Covered |
|-------|--------|-----------------|--------------|
...
特性評価テスト
## Characterization Tests: <FunctionName> (pin before refactor)

### Behaviour captured
- Inputs exercised: <BVA points + MC/DC branches>
- Side effects pinned: <globals written, stub call sequence, out-params>
- Quirks recorded as current behaviour (not a spec): <e.g. uint16 wrap at sum > 65535>

### Characterization Test Cases (framework: Unity / CMocka / GoogleTest)
```c
[runnable test cases asserting the legacy function's observed outputs and side effects]
```

### How to prove equivalence
Run this suite on the host BEFORE the modernization step (it must pass against the legacy code),
then again AFTER each step. Unchanged pass = behaviour preserved.

Pinned: <behaviours covered>. Could not characterize: <hardware/timing-dependent behaviour>.

例

例 1 — 単体テスト生成

入力:

/* ASIL-B */
Std_ReturnType BatMon_CheckVoltage(uint16 voltage_mV, uint8 debounce_cnt) {
    if ((voltage_mV < BATMON_LOW_THRESH_MV) && (debounce_cnt >= BATMON_DEBOUNCE_CNT)) {
        Rte_Write_LowVoltageWarning_Active(TRUE);
        return E_OK;
    }
    Rte_Write_LowVoltageWarning_Active(FALSE);
    return E_OK;
}
/* BATMON_LOW_THRESH_MV = 11500, BATMON_DEBOUNCE_CNT = 5 */

出力:

## Unit Tests: BatMon_CheckVoltage

### Function Analysis
- Decisions: 1 (compound: voltage_mV < THRESH && debounce_cnt >= CNT)
- Conditions: C1 = (voltage_mV < 11500), C2 = (debounce_cnt >= 5)
- MC/DC pairs required: 2 pairs (one per condition)

### Test Cases

#### TC-BatMon-001: Both conditions TRUE → warning set
- **Preconditions**: Rte_Write_LowVoltageWarning_Active stub installed; no prior state.
- **Inputs**: voltage_mV = 11000, debounce_cnt = 5
- **Expected**: return E_OK; Rte_Write called with TRUE.
- **Covers**: C1=TRUE, C2=TRUE → decision TRUE

#### TC-BatMon-002: C1 FALSE (voltage above threshold) [MC/DC pair for C1]
- **Inputs**: voltage_mV = 11500, debounce_cnt = 5
- **Expected**: return E_OK; Rte_Write called with FALSE.
- **Covers**: C1=FALSE, C2=TRUE → C1 independently flips outcome vs TC-001

#### TC-BatMon-003: C2 FALSE (debounce not reached) [MC/DC pair for C2]
- **Inputs**: voltage_mV = 11000, debounce_cnt = 4
- **Expected**: return E_OK; Rte_Write called with FALSE.
- **Covers**: C1=TRUE, C2=FALSE → C2 independently flips outcome vs TC-001

#### TC-BatMon-004: Boundary — voltage exactly at threshold
- **Inputs**: voltage_mV = 11500
- **Expected**: Rte_Write called with FALSE. (boundary: `<` not `<=`)

#### TC-BatMon-005: Boundary — minimum uint16 voltage, maximum debounce
- **Inputs**: voltage_mV = 0, debounce_cnt = 255
- **Expected**: Rte_Write called with TRUE.

#### TC-BatMon-006: Boundary — debounce exactly at threshold
- **Inputs**: voltage_mV = 11000, debounce_cnt = 5
- **Expected**: Rte_Write called with TRUE. (boundary: `>=` includes equal)

### Stub Declarations
```c
static boolean s_stub_LowVoltageWarning;
static uint32  s_stub_LowVoltageWarning_callCount;

Std_ReturnType Rte_Write_LowVoltageWarning_Active(boolean value) {
    s_stub_LowVoltageWarning = value;
    s_stub_LowVoltageWarning_callCount++;
    return RTE_E_OK;
}
```

### MC/DC Coverage Matrix
| Decision | Condition | TRUE (TC) | FALSE (TC) | Independent? |
|----------|-----------|-----------|------------|--------------|
| D1       | C1        | TC-001    | TC-002     | Yes          |
| D1       | C2        | TC-001    | TC-003     | Yes          |
例 2 — 境界値分析

入力:

uint16 BatMon_ComputeAverage(uint16 v1_mV, uint16 v2_mV) {
    return (v1_mV + v2_mV) / 2U;
}

型:uint16(0~65535)。物理的な意味:バッテリー電圧(mV)。有効範囲:0~20000 mV。

出力:

## Boundary Value Analysis: BatMon_ComputeAverage

### Parameter Table
| Parameter | C Type | Physical Range | Scaling  | Valid Range |
|-----------|--------|----------------|----------|-------------|
| v1_mV     | uint16 | 0–20000 mV     | 1 mV/LSB | 0–20000     |
| v2_mV     | uint16 | 0–20000 mV     | 1 mV/LSB | 0–20000     |

### BVA Test Points
| Parameter | Test Point | Raw Value | Physical  | Expected / Risk                        |
|-----------|------------|-----------|-----------|----------------------------------------|
| v1_mV     | MIN        | 0         | 0 mV      | Valid; average = v2_mV/2               |
| v1_mV     | Valid MAX  | 20000     | 20.000 V  | Valid; check no overflow with v2_mV    |
| v1_mV     | Type MAX   | 65535     | 65.535 V  | Out-of-valid-range; sum overflow risk  |
| v2_mV     | MIN        | 0         | 0 mV      | Valid                                  |
| v2_mV     | Valid MAX  | 20000     | 20.000 V  | Valid; sum = 40000, no overflow        |
| v2_mV     | Type MAX   | 65535     | 65.535 V  | Out-of-valid-range; sum overflow risk  |

### Arithmetic Risk Analysis
| Operation              | Risk                    | Triggering Input                          | Expected Handling |
|------------------------|-------------------------|-------------------------------------------|-------------------|
| v1_mV + v2_mV (line 2) | uint16 overflow / wrap  | v1=40000, v2=40000 → 80000 > 65535 → 14464| Silently wrong. Must clamp or use a wider intermediate type. |

### Recommended Additional Test Cases
| TC ID | Inputs                  | Expected Output | Risk Covered            |
|-------|-------------------------|-----------------|-------------------------|
| TC-01 | v1=0, v2=0              | 0               | MIN boundary            |
| TC-02 | v1=20000, v2=20000      | 20000           | Valid MAX (no overflow) |
| TC-03 | v1=65535, v2=1          | wraps (DEFECT)  | Type MAX overflow       |
| TC-04 | v1=32768, v2=32768      | wraps (DEFECT)  | Overflow at midpoint    |

**Recommended fix:**
```c
uint16 BatMon_ComputeAverage(uint16 v1_mV, uint16 v2_mV) {
    uint32 sum = (uint32)v1_mV + (uint32)v2_mV;  /* promote before addition */
    return (uint16)(sum / 2U);
}
```
This eliminates uint16 overflow; the division result is always ≤ 32767 for valid inputs.

コメント