Testing
Testing
Section titled “Testing”wippy/test フレームワークで Lua コードのテストを記述して実行します。これはアサーション、ライフサイクルフック、モックを備えた BDD スタイルのランナーで、wippy run test コマンドによって実行されます。
構築するもの
Section titled “構築するもの”小さなライブラリと、それをカバーするテストスイート:
addとdiv関数を持つcalcライブラリ。- ケースを記述し、動作をアサートし、保留中のケースをスキップするテストエントリ。
wippy run testによるグリーンなテスト実行。
-
Wippy プロジェクト (app-template をクローンするか、空のディレクトリで
wippy initを実行)。 -
テストフレームワークとターミナルホストがインストールされていること:
Terminal window wippy add wippy/testwippy add wippy/terminalwippy installランナーはライブのターミナル UI をレンダリングするため、
wippy/testとともにwippy/terminalが必要です。
テスト対象のコード
Section titled “テスト対象のコード”-- src/calc.lualocal function add(a, b) return a + bend
local function div(a, b) if b == 0 then return nil, "division by zero" end return a / bend
return { add = add, div = div }テストは meta.type: test でタグ付けされた通常の function.lua エントリです。そのメソッドは test.run_cases(...) が生成する値を返し、ランナーがそれを呼び出します:
-- src/calc_test.lualocal test = require("test")local calc = require("calc")
local function define_tests() test.describe("calculator", function() local started = false
test.before_all(function() started = true end)
test.it("setup ran", function() test.is_true(started) end)
test.it("adds numbers", function() test.eq(calc.add(2, 3), 5) end)
test.it("returns error on divide by zero", function() local result, err = calc.div(1, 0) test.has_error(result, err) test.contains(err, "division by zero") end)
test.it_skip("not implemented yet", function() test.fail("should not run") end) end)end
return { run = test.run_cases(define_tests) }両方のエントリを登録します。検出は meta.type: test をキーにします。meta.suite は出力で結果をグループ化します:
version: "1.0"namespace: app
entries: - name: calc kind: library.lua source: file://calc.lua
- name: calc_test kind: function.lua meta: name: Calculator Test type: test suite: calculator source: file://calc_test.lua method: run imports: test: wippy.test:test calc: app:calcimports マップは、テスト内で require(...) が解決する対象を制御します。test はフレームワークをバインドし、calc はテスト対象のユニットをバインドします。
wippy run test反復作業中に単一のスイートに絞り込みます (エントリ ID またはスイート名に一致):
wippy run test calculator上記スイートの出力:
calculator (4) 3/4 1 skipped 1ms o setup ran o adds numbers o returns error on divide by zero - not implemented yet (skipped)
PASSED 3 tests 1 skipped 1mswippy run test はすべてのケースが合格すると 0 で、失敗があれば 1 で終了するため、そのまま CI に組み込めます。
アサーション
Section titled “アサーション”各アサーションは失敗時に例外を発生させます。型ガードは検証された値も返します。
| アサーション | チェック内容 |
|---|---|
test.eq(a, b) / test.neq(a, b) | 等価 / 非等価 |
test.ok(v) / test.fail(msg) | 真値 / 強制的に失敗させる |
test.is_nil(v) / test.not_nil(v) | Nil / 非 nil |
test.is_true(v) / test.is_false(v) | ブール値 |
test.is_string/number/table/function/boolean(v) | 型ガード (v を返す) |
test.contains(str, sub) / test.matches(str, pattern) | 部分文字列 / Lua パターン |
test.has_key(tbl, key) / test.len(v, n) | マップキー / 長さ |
test.gt/gte/lt/lte(a, b) | 数値比較 |
test.throws(fn) / test.has_error(val, err) / test.no_error(val, err) | エラー処理 |
すべてオプションの末尾メッセージ引数を取ります。
ライフサイクルとモック
Section titled “ライフサイクルとモック”これらは describe ブロック内で呼び出します:
test.before_all/test.after_all— ブロックごとに 1 回実行。test.before_each/test.after_each— すべてのケースの前後で実行。test.mock("module.field", fn)— 現在のケースに対して関数を置き換えます。モックは各ケースの後に自動的に復元されます。早期にクリアするにはtest.restore_all_mocks()を使用します。
ネストされた describe ブロックは親のフックを継承します (外側の before_* が先、内側の after_* が先)。
次のステップ
Section titled “次のステップ”- Hello World — 最小限のプロジェクトレイアウト
- エントリの種類 —
function.lua、library.luaなど - テストフレームワーク — ランナーとイベントプロトコルの完全なリファレンス