このモジュールは、他のLuaモジュールのためのユニットテストを提供します。モジュールをテストする際には、通常、Module:Module name/testcasesの場所にテスト用の専用モジュールを作成します。テストはScribuntoUnitモジュールによって行われ、テストモジュールで定義された動作が期待通りの結果を出力するかを検証します。

テストモジュールの構造

編集

テストモジュール(テストスイート)を作成するには、次のコードから始めます。

local myModule = require('Module:MyModule') -- テストするモジュール
local ScribuntoUnit = require('Module:ScribuntoUnit')
local suite = ScribuntoUnit:new()

これを行った後、各テスト関数をsuiteオブジェクトに追加することができます。testで始まる関数はテストとして認識されます。(一方、その他の関数はScribuntoUnitには無視されますが、テストの中で利用は可能です。)

function suite:testSomeCall()
    self:assertEquals('expected value', myModule.someCall(123))
    self:assertEquals('other expected value', myModule.someCall(456))
end

function suite:testSomeOtherCall()
    self:assertEquals('expected value', myModule.someOtherCall(123))
    self:assertEquals('other expected value', myModule.someOtherCall(456))
end

作成するテストにはアサーションの設定が必要で、ScribuntoUnitはそのアサーションが真かどうかを検証します。例えば、assertEqualsは与えられた二つの引数が等しいかを確認します。ScribuntoUnitがアサーションを真と判断できない場合、テストは失敗となり、エラーメッセージが表示されます。このエラーメッセージは、問題のあるアサーションを示すものです。(その時点では、他のアサーションの検証は行われません)

テストモジュールを完了するには、suiteオブジェクトを返す必要があります。

return suite

テストの実行

編集

テストは2つの方法で実行できます。一つ目はLuaデバッグコンソールを使用する方法、もう一つは#invokeを利用してWikiページから実行する方法です。デバッグコンソールでの実行には、require('Module:MyModule/testcases').run()というコードを使います。一方、Wikiページからの実行では、{{#invoke:MyModule/testcases|run}}を使用します。これにより、結果を示す表が表示されます。もし結果をよりコンパクトな形式で表示したい場合は、{{#invoke:MyModule/testcases|run displayMode=short}}を利用します。

テスト

編集

エラーメッセージ

編集

全てのテストメソッドにおいて、最後のパラメータは検証失敗時に表示されるメッセージとなります。

self:assertEquals("expected value", myModule.someCall(123), "The call to myModule.someCall(123) didn't return the expected value.")
self:fail(message)

無条件に検証に失敗します。

self:fail("Test failed because of X.")

assertTrue, assertFalse

編集
self:assertTrue(expression, message)
self:assertFalse(expression, message)

これらは、指定された式がtruefalseに評価されるかを検証します。Luaでは、falsenilだけがfalseとして評価され、それ以外の値は全てtrueとして評価されることに注意してください。

self:assertTrue(2 + 2 == 4)
self:assertTrue('foo')
self:assertFalse(2 + 2 == 5)
self:assertFalse(nil)

assertStringContains

編集
self:assertStringContains(pattern, s, plain, message)

これは、文字列s内にpatternが存在するかどうかを検証します。plainがtrueである場合、patternはリテラルテキストとして扱われます。そうでない場合は、patternustring パターンとして解釈されます。

self:assertStringContains("foo", "foobar") -- passes
self:assertStringContains("foo", "fobar") -- fails
self:assertStringContains(".oo", "foobar") -- passes: matches "foo"
self:assertStringContains(".oo", "foobar", true) -- fails: . is interpreted as a literal character

assertNotStringContains

編集
self:assertNotStringContains(pattern, s, plain, message)

これはassertStringContainsの逆の動作をします。文字列s内にpatternが存在する場合、検証は失敗となります。plainがtrueである場合、patternはリテラルテキストとして扱われます。そうでない場合は、patternustring パターンとして解釈されます。

self:assertNotStringContains("foo", "foobar") -- fails
self:assertNotStringContains("foo", "fobar") -- passes
self:assertNotStringContains(".oo", "foobar") -- fails: matches "foo"
self:assertNotStringContains(".oo", "foobar", true) -- passes: . is interpreted as a literal character

assertEquals

編集
self:assertEquals(expected, actual, message)

これは、最初のパラメータと2番目のパラメータが等しいかどうかを検証します。両方のパラメータが数値である場合、数値は限られた精度で浮動小数点数として表されるため、assertWithinDeltaを使用して、デルタとして1e-8(0.00000001)を指定し、値を比較します。

self:assertEquals(4, calculator.add(2, 2))

assertNotEquals

編集
self:assertNotEquals(expected, actual, message)

これは、最初のパラメータが2番目のパラメータと等しくないかどうかをテストします。両方のパラメータが数値である場合、数値は限られた精度で浮動小数点数として表されるため、assertWithinDeltaを使用して、デルタとして1e-8(0.00000001)を指定し、値を比較します。

self:assertNotEquals(5, calculator.add(2, 2))

assertWithinDelta

編集
self:assertWithinDelta(expected, actual, delta, message)

2つの数値を比較する際、最初の数値が2番目の数値から指定した距離(デルタ)以内にあるかどうかを検証します。これは、Luaで数値を倍精度浮動小数点数として表現する際の誤差を考慮してのことです。例えば、英語版ウィキペディアのScribtoでは、式0.3-0.2==0.1falseと評価されるのは、0.3-0.2が実際には0.09999999999999997780…0.10.10000000000000000555…と評価されるためです。この微小な誤差のため、2つの浮動小数点数を比較する際には、完全に一致するだけでなく、一定のデルタ内で近いかどうかを基準にする必要があります。なお、この問題は整数には適用されません。整数は、2^53の値までの倍精度浮動小数点数を使用して正確に表すことができます。

self:assertWithinDelta(0.1, calculator.subtract(0.3, 0.2), 1e-10)

assertNotWithinDelta

編集
self:assertNotWithinDelta(expected, actual, delta, message)

2つの数値について、最初の数値が2番目の数値から指定された距離内に位置していないかを検証します。このテストは、assertWithinDeltaの反対の動作をします。

self:assertNotWithinDelta(0.1, calculator.subtract(0.3, 0.1), 1e-10)

assertDeepEquals

編集
self:assertDeepEquals(expected, actual, message)

最初のパラメータと2番目のパラメータが等しいかどうかを検証します。パラメータがテーブルである場合、再帰的に比較が行われ、その際に__eq メタメソッドが考慮されます。

self:assertDeepEquals(table1, table2)

assertTemplateEquals

編集
self:assertTemplateEquals(expected, template, args, message)

この検証は、最初のパラメータがテンプレート呼び出しと一致するかどうかを確認します。2番目のパラメータはテンプレートの名前を指定し、3番目のパラメータはテンプレートの引数をテーブル形式で指定します。

self:assertTemplateEquals(4, 'add', {2, 2}) -- true if {{add|2|2}} equals 4

XML表記で書かれたタグの中には、正しく検証できないものがあることに注意してください。以下のassertResultEquals関数の注意を参照してください。


assertResultEquals

編集
self:assertResultEquals(expected, text, message)

これは、最初のパラメータが特定のウィキテキストの展開結果と一致するかどうかを検証します。2番目のパラメータには任意のウィキテキストを指定できます。

self:assertResultEquals(4, '{{#invoke:Calculator|add|2|2}}')

<pre><nowiki><gallery><ref>などのXML形式で記述される特定のタグは、正しく比較するのが難しい点に注意してください。これらのタグは、Luaで処理される前にストリップマーカーに変換されるためです。ストリップマーカーは、同じ入力からでも一意の値が生成されるので、これらのタグの等価性を検証するテストは失敗します。この特性は、assertTemplateEquals関数とassertSameResult関数にも影響します。

assertSameResult

編集
self:assertSameResult(text1, text2, message)

これは、指定されたwikitextの文字列が展開された結果が、別のwikitextの展開結果と一致するかどうかを検証します。これは、モジュールが置き換える予定のテンプレートが期待通りに動作しているかを確認する際に役立ちます

self:assertSameResult('{{add|2|2}}', '{{#invoke:Calculator|add|2|2}}')

XML表記で書かれたタグの中には、正しく検証できないものがあることに注意してください。上記のassertResultEquals関数の注意点を参照してください。

assertThrows

編集
self:assertThrows(fn, expectedMessage, message)

これは、指定された関数が例外を投げるかどうかを検証します。expectedMessagenilでない場合、そのエラーメッセージが例外として投げられたかどうかもチェックされます。

関連項目

編集