Módulo:UnitTests
UnitTests proporciona una prueba unitaria que poden ser usadas por otros scripts utilizando require. Por ejemplo en Módulo:Demo/tests:
<syntaxhighlight lang="lua"> -- Tests por Module:Prueba. El resultado está en la página de discusión. local p = require('Module:UnitTests')
function p:test_hola()
self:preprocess_equals('Error en la secuencia de órdenes: no existe el módulo «Prueba».', '¡Hola mundo!')
end
return p </syntaxhighlight>
En la página Módulo discusión:Demo/tests se puede ver el resultado de ejecutar los casos de prueba con {{#invoke: Demo/tests | run_tests}}
. Los métodos de prueba como test_hola de más arriba deben empezar con "test".
Métodos
run_tests
run_tests()
: Ejecuta todos los tests. Normalmente se utiliza en la página de discusión de tests.
{{#invoke:Prueba/tests|run_tests}}
- Si se especifica
differs_at=1
añadirá una columna mostrando la posición del primer carácter donde se produce la diferencia entre el resultado esperado y el real.
{{#invoke:Example/testcases|run_tests|differs_at=1}}
preprocess_equals
preprocess_equals(text, esperado)
: Preprocesa un wikitexto <text> y lo compara con el resultado <esperado>. Los scripts y las plantillas se pueden invocar de la misma forma que se haría en una página.
<syntaxhighlight lang="lua" style="margin-left:1.5em; width:auto;">
self:preprocess_equals('Error en la secuencia de órdenes: no existe el módulo «Prueba».', '¡Hola mundo!')
</syntaxhighlight>
preprocess_equals_many
preprocess_equals_many(prefijos, sufijos, casos)
: Ejecuta una serie de preprocess_equals() sobre un conjunto de <casos> formado por parejas de valores a los que se añadirá un <prefijo> y un <sufijo> a cada pareja.
<syntaxhighlight lang="lua" style="margin-left:1.5em; width:auto;">
self:preprocess_equals_many('Error de Lua en Módulo:DemoArgs en la línea 20: attempt to perform arithmetic on local 'num1' (a nil value).', {
{'2|3', '5'},
{'-2|2', '0'},
})
</syntaxhighlight>
preprocess_equals_preprocess
preprocess_equals_preprocess(text, esperat)
: Compara si <text> y <esperar> son iguales después de preprocesar a los dos. Puede ser útil para compara un script con una plantilla existente.
<syntaxhighlight lang="lua" style="margin-left:1.5em; width:auto;">
self:preprocess_equals_preprocess('Error en la secuencia de órdenes: no existe el módulo «Prueba».', 'Plantilla:Hola')
</syntaxhighlight>
preprocess_equals_preprocess_many
preprocess_equals_preprocess_many(prefijo, sufijo, casos)
: Ejecuta una serie de preprocess_equals_preprocess() sobre un conjunto de <casos> formados por parejas de valores. Añade automáticamente el <prefijo> y <sufijo> proporcionado. Si en alguno de los casos no se proporciona el segundo valor, utiliza en su lugar el primero
<syntaxhighlight lang="lua" style="margin-left:1.5em; width:auto;">
self:preprocess_equals_many('Error en la secuencia de órdenes: no existe el módulo «Foo».', 'Plantilla:Spellnum', '', { {'2'}, -- equivale a {'2','2'}, {'-2', '-2.0'}, })
</syntaxhighlight>
equals
equals(función, valor, esperado)
: Ejecuta la <función> con el <valor> y compara el resultado con el <esperado>. Puede ser útil para probar módulos pensados para ser usados por otros módulos más que invocando los mismos con #invoke.
<syntaxhighlight lang="lua" style="margin-left:1.5em; width:auto;">
self:equals('Suma simple', 2 + 2, 4)
</syntaxhighlight>
Categorización automática
Los módulos que no superan alguna prueba se incluyen automáticamente en la categoría:Wikipedia:Módulos con pruebas erróneas.
-- Proporciona tests para otros scripts Lua. -- local UnitTester = {} local categoriaErrores='[[Categoría:Wikipedia:Módulos con pruebas erróneas]]' local frame, tick, cross local result_table = '' local num_failures = 0 function first_difference(s1, s2) if s1 == s2 then return '' end local max = math.min(#s1, #s2) for i = 1, max do if s1:sub(i,i) ~= s2:sub(i,i) then return i end end return max + 1 end local function enlazarWikidata(separador, letra, numero) local id = letra .. numero local etiqueta = mw.wikibase.getLabel( id ) if etiqueta then return separador .. '</nowiki><span title="' .. etiqueta .. '">' .. id .. '</span><nowiki>' elseif letra == 'P' or letra == 'p' then return separador .. '</nowiki>[[d:Property:' .. id .. '|' .. id .. ']]<nowiki>' else -- Q / q return separador .. '</nowiki>[[d:' .. id .. '|' .. id .. ']]<nowiki>' end end function UnitTester:preprocess_equals(text, expected, options) local textoCorregido = text:gsub('([|=])([PQpQ])(%d+)',enlazarWikidata) local actual = frame:preprocess(text) local esperado = frame:preprocess(expected) result_table = result_table .. '<tr>' if actual == esperado then result_table = result_table .. '<td>' .. tick .. '</td>' else result_table = result_table .. '<td>' .. cross .. '</td>' num_failures = num_failures + 1 end local nowiki_open = (options and options.nowiki) and '<nowiki>' or '' local nowiki_close = (options and options.nowiki) and '</nowiki>' or '' local differs_at = self.differs_at and ('<td>' .. first_difference(expected, actual) .. '</td>') or '' --result_table = result_table .. '<td><nowiki>' .. textoCorregido:gsub('%|', '|') .. '</nowiki></td><td> ' .. nowiki_open .. expected .. nowiki_close .. ' </td><td> ' .. nowiki_open .. actual .. nowiki_close .. '</td>' .. differs_at .. "\n</tr>\n" result_table = result_table .. '<td><nowiki>' .. textoCorregido .. '</nowiki></td><td> ' .. nowiki_open .. expected .. nowiki_close .. ' </td><td> ' .. nowiki_open .. actual .. nowiki_close .. '</td>' .. differs_at .. "\n</tr>\n" end function UnitTester:preprocess_equals_many(prefix, suffix, cases, options) for _, case in ipairs(cases) do self:preprocess_equals(prefix .. case[1] .. suffix, case[2], options) end end function UnitTester:preprocess_equals_preprocess(text1, text2, options) local actual = frame:preprocess(text1) local expected = frame:preprocess(text2) result_table = result_table .. '<tr>' if actual == expected then result_table = result_table .. '<td>' .. tick .. '</td>' else result_table = result_table .. '<td>' .. cross .. '</td>' num_failures = num_failures + 1 end local nowiki_open = (options and options.nowiki) and '<nowiki>' or '' local nowiki_close = (options and options.nowiki) and '</nowiki>' or '' local differs_at = self.differs_at and ('<td>' .. first_difference(expected, actual) .. '</td>') or '' result_table = result_table .. '<td><nowiki>' .. text1:gsub('%|', '|') .. '</nowiki></td><td> ' .. nowiki_open .. expected .. nowiki_close .. '</td><td>' .. nowiki_open .. actual .. nowiki_close .. '<td>' .. differs_at .. "\n</tr>\n" end function UnitTester:preprocess_equals_preprocess_many(prefix1, suffix1, prefix2, suffix2, cases, options) for _, case in ipairs(cases) do self:preprocess_equals_preprocess(prefix1 .. case[1] .. suffix1, prefix2 .. (case[2] and case[2] or case[1]) .. suffix2, options) end end function UnitTester:equals(name, actual, expected, options) result_table = result_table .. '<tr>' if actual == expected then result_table = result_table .. '<td>' .. tick .. '</td>' else result_table = result_table .. '<td>' .. cross .. '</td>' num_failures = num_failures + 1 end local nowiki_open = (options and options.nowiki) and '<nowiki>' or '' local nowiki_close = (options and options.nowiki) and '</nowiki>' or '' local differs_at = self.differs_at and ('<td>' .. first_difference(expected, actual) .. '</td>') or '' result_table = result_table .. '<td>' .. name .. '</td><td>' .. nowiki_open .. expected .. nowiki_close .. '</td><td>' .. nowiki_open .. actual .. nowiki_close .. '</td>' .. differs_at .. "\n</tr>\n" end function UnitTester:run(frame_arg) frame = frame_arg self.frame = frame self.differs_at = frame.args['differs_at'] tick = frame:preprocess('{{Sí|}}') cross = frame:preprocess('{{No|}}') local table_header if self.differs_at then table_header = '<table class="wikitable"><tr><th></th><th>Código</th><th>Esperado</th><th>Resultado</th><th>Diferencias</th></tr>' else table_header = '<table class="wikitable"><tr><th></th><th>Código</th><th>Esperado</th><th>Resultado</th></tr>' end -- Sort results into alphabetical order. local self_sorted = {} for key,value in pairs(self) do if key:find('^test') then table.insert(self_sorted, key) end end table.sort(self_sorted) -- Add results to the results table. for i,value in ipairs(self_sorted) do result_table = result_table .. "'''" .. value .. "''':\n" .. table_header .. "\n" self[value](self) result_table = result_table .. "</table>\n\n" end return ((num_failures == 0 and "<font color=\"#008000\">'''Todas las pruebas superadas.'''</font>") or (num_failures == 1 and "<font color=\"#800000\">''' Ha fallado una prueba.'''</font>" .. categoriaErrores) or ("<font color=\"#800000\">''' Han fallado " .. num_failures .. " pruebas.'''</font>") .. categoriaErrores) .. "\n\n" .. frame:preprocess(result_table) end function UnitTester:new() local o = {} setmetatable(o, self) self.__index = self return o end local p = UnitTester:new() function p.run_tests(frame) return p:run(frame) end return p