はじめに
Railsエンジニアとして毎日RSpecを書いているのに、JSTQBの参考書を開くと知らない用語だらけ——そんな経験はありませんか?
実は逆で、あなたはすでにJSTQBの概念の多くを実践しています。 名前を知らないだけで。
この記事では「RSpecで書いているアレって、JSTQBでいうコレのことだったのか!」という気づきを軸に、普段の開発行為とシラバスの概念を1対1で対応させて整理します。読み終わる頃には、JSTQBの試験範囲の約半分が「知っていること」に変わっているはずです。
大前提:JSTQBの「テストレベル」とRSpecの対応
まずここを押さえておくと、以降の話がスムーズです。
| JSTQBのテストレベル | Railsでの対応 | RSpecのファイル |
|---|---|---|
| コンポーネントテスト(単体テスト) | モデル・クラス単体の検証 |
spec/models/, spec/lib/
|
| 統合テスト | 複数コンポーネントの結合検証 |
spec/requests/, spec/services/
|
| システムテスト | ブラウザ経由のE2E検証 | spec/system/ |
| 受け入れテスト | ステークホルダーによる検証 | (手動 or Cucumber等) |
rails new したときに生成される spec/ の構造は、そのままJSTQBのテストレベルの階層になっています。
Chapter 4 の技法を、コードで読み解く
JSTQBの中で最も出題比率が高いのが Chapter 4「テスト分析とテスト設計」 です。ここの技法は、まさに日常的にやっていることそのものです。
同値分割法(Equivalence Partitioning)
「同じ動作をする入力値をグループに分け、代表値1つでテストする」手法です。
# 例:年齢バリデーション(有効範囲: 18〜65歳)
RSpec.describe User, type: :model do
# 有効同値クラス → 範囲内の代表値1つでOK
it "18〜65歳は有効" do
expect(build(:user, age: 30)).to be_valid
end
# 無効同値クラス① → 18歳未満の代表値
it "17歳以下は無効" do
expect(build(:user, age: 10)).not_to be_valid
end
# 無効同値クラス② → 65歳超の代表値
it "66歳以上は無効" do
expect(build(:user, age: 70)).not_to be_valid
end
end
「なんとなく正常値・異常値でテストしている」のは、すでに同値分割を実践しています。JSTQBではこれを**「同値クラスの代表値を選ぶ」**と表現します。
境界値分析(Boundary Value Analysis)
同値分割の境界の値そのものに注目する手法です。バグは境界付近で多く発生するため、特にここを重点的にテストします。
RSpec.describe User, type: :model do
# 有効境界値(最小)
it "18歳は有効" do
expect(build(:user, age: 18)).to be_valid
end
# 無効境界値(最小の外側)
it "17歳は無効" do
expect(build(:user, age: 17)).not_to be_valid
end
# 有効境界値(最大)
it "65歳は有効" do
expect(build(:user, age: 65)).to be_valid
end
# 無効境界値(最大の外側)
it "66歳は無効" do
expect(build(:user, age: 66)).not_to be_valid
end
end
「18 と 17 を両方テストする」——これが境界値分析です。30 だけテストして満足していませんか?
デシジョンテーブルテスト(Decision Table Testing)
複数の条件の組み合わせによって動作が変わるロジックに使います。
# 例:割引ロジック
# 会員種別(premium/regular)× クーポン有無 → 割引率
#
# | premium | coupon | 割引率 |
# |---------|--------|--------|
# | true | true | 30% |
# | true | false | 20% |
# | false | true | 10% |
# | false | false | 0% |
RSpec.describe DiscountCalculator do
it { expect(calc(premium: true, coupon: true )).to eq(0.30) }
it { expect(calc(premium: true, coupon: false)).to eq(0.20) }
it { expect(calc(premium: false, coupon: true )).to eq(0.10) }
it { expect(calc(premium: false, coupon: false)).to eq(0.00) }
end
context ブロックを条件ごとに切って書くのが習慣になっているなら、それはデシジョンテーブルテストの考え方です。
状態遷移テスト
オブジェクトの「状態」と「遷移」を網羅するテストです。Railsの aasm や state_machines を使っているプロジェクトでは特に馴染みのある概念です。
# 例:注文ステータス(draft → submitted → approved / rejected)
RSpec.describe Order, type: :model do
describe "状態遷移" do
let(:order) { create(:order, status: :draft) }
it "draft から submitted に遷移できる" do
expect { order.submit! }.to change(order, :status).from("draft").to("submitted")
end
it "draft から直接 approved には遷移できない" do
expect { order.approve! }.to raise_error(AASM::InvalidTransition)
end
it "submitted から approved に遷移できる" do
order.submit!
expect { order.approve! }.to change(order, :status).to("approved")
end
end
end
JSTQBでは「有効な遷移と無効な遷移の両方をテストする」ことが推奨されています。raise_error で無効遷移を確認するのは、まさにそれです。
探索的テスト
「事前にテストケースを決めず、テストしながら気づきを得て、次のテストを決める」アプローチです。
# 事前設計なしで実際に動かしながら気づくことが多い
# 例:複雑な検索機能を触っていたら
# 「空文字 + フィルター組み合わせ」でエラー発見
# → その場でテストケースを追加
it "空文字とカテゴリフィルターを同時に指定してもエラーにならない" do
expect { search(keyword: "", category: "tech") }.not_to raise_error
end
開発中に「あれ、これどうなるんだろう」と試しながらバグを見つけた経験は全員あるはず。それが探索的テストです。
Chapter 3「静的テスト」= コードレビューのことだった
「静的テスト」と聞くと難しく感じますが、プログラムを実行せずに成果物の欠陥を見つける活動のことです。つまりコードレビューがそのまま該当します。
| JSTQBの用語 | 開発現場での対応 |
|---|---|
| 静的テスト | コードレビュー、PRレビュー全般 |
| ウォークスルー | 作成者が説明しながら進めるレビュー(ペアレビュー等) |
| インスペクション | 役割分担・入出口基準が明確な正式なレビュー |
| 静的解析 | RuboCop、Brakeman、ESLint 等の自動チェック |
特に試験で問われるのが「最も形式的なレビューはどれか?」という設問で、答えは インスペクション です。
非公式レビュー < ウォークスルー < テクニカルレビュー < インスペクション
(形式度:低) (形式度:高)
Chapter 2「テストレベル」= リグレッションを理解する
RailsエンジニアならCIで毎回走る リグレッションテストは馴染み深いはず。これもJSTQBの重要概念です。
| 用語 | 意味 | Railsでの具体例 |
|---|---|---|
| 確認テスト(再テスト) | 修正した欠陥が直っているかの確認 | バグ修正後に該当 spec を単体で実行 |
| リグレッションテスト | 修正が既存の動作を壊していないかの確認 | CIで全 spec を実行(bundle exec rspec) |
「バグ直したら別のところが壊れた」——それはリグレッションテストが不十分だったサインです。JSTQBでは「変更の規模に関わらずリグレッションテストは必要」と明記されています。
Chapter 6「テスト自動化」の落とし穴——試験でも実務でも
Chapter 6 で問われる「テスト自動化のリスク」も、実務感覚で答えられます。
Q. テスト自動化の導入で最も考慮すべきリスクはどれか?
A. テスト実行速度が遅くなる
B. テストカバレッジが下がる
C. ツールの習得・保守にかかるコストと労力 ← 正解
D. 手動テストが完全に不要になる
「RSpec は書いたけど、メンテが追いつかずに全部 pending になっている」——これがまさにそのリスクです。
自動化が特に効果を発揮する場面として試験で頻出なのは「繰り返し実行される リグレッションテスト」です。逆に「探索的テスト」や「ユーザビリティ評価」は自動化に向かないものの代表例として問われます。
用語対応表:まとめ
保存しておきたい人向けに全部まとめます。
| RSpec / 開発現場の言葉 | JSTQBの正式用語 | シラバスの章 |
|---|---|---|
spec/models/ のテスト |
コンポーネントテスト(単体テスト) | 2.2 |
spec/system/ のテスト |
システムテスト | 2.2 |
| CIで全 spec を走らせる | リグレッションテスト | 2.2 |
| バグ修正後の確認テスト | 確認テスト(再テスト) | 2.2 |
| 正常値・異常値を分けてテスト | 同値分割法 | 4.2 |
18 と 17 の両方をテスト |
境界値分析 | 4.2 |
context で条件の組み合わせを網羅 |
デシジョンテーブルテスト | 4.2 |
state_machines の遷移テスト |
状態遷移テスト | 4.2 |
| 触りながら気づいてテストを追加 | 探索的テスト | 4.4 |
| コードレビュー・PRレビュー | 静的テスト | 3.1 |
| RuboCop / Brakeman | 静的解析(静的テストツール) | 3.1 |
| ペアレビュー | ウォークスルー | 3.2 |
| 役割分担ありの正式レビュー | インスペクション | 3.2 |
| RSpecをCIに組み込む行為 | テスト自動化 | 6.2 |
試験対策の次のステップ
「用語の対応がわかった」次は、実際の問題形式に慣れることが重要です。読んでいるだけでは本番で答えられません。
QAドリル では、この記事で紹介した全技法(同値分割・境界値分析・状態遷移テスト・探索的テスト・静的テストなど)をカバーしたJSTQB Foundation Level v4.0準拠の問題を無料で演習できます。
- この記事を読んだ直後に解くなら Chapter 3(静的テスト) と Chapter 4(テスト設計技法) がおすすめ
- 間違えた問題だけ繰り返す「苦手問題モード」と、章を指定して解ける「章別ドリル」で弱点を効率的につぶせます