Как написать тестовые модульные тесты для функций, которые возвращают нормально, ошибаться?
У меня есть функция Lua, которая возвращает false
сопровождаемое сообщением об ошибке и желающим проверить его поведение, используя встроенную платформу тестирования. Прямо сейчас я делаю это примерно так:
function safe_divide(a, b)
if b > 0 then -- buggy! should be b ~= 0
return a / b
else
return false, "division by zero"
end
end
describe("safe_divide", function()
it("can divide by positive numbers", function()
local ok, err = safe_divide(10.0, 5.0)
assert.truthy(ok)
assert.are.same(2.0, ok)
end)
it("errors when dividing by zero", function()
local ok, err = safe_divide(10.0, 0.0)
assert.not_truthy(ok)
assert.are.same("division by zero", err)
end)
it("can divide by negative numbers", function()
local ok, err = safe_divide(-10.0, -5.0)
assert.truthy(ok)
assert.are.same(2.0, ok)
end)
end)
Есть две вещи, которые мне не нравятся в моем нынешнем подходе:
- Каждый тест состоит из 3 строк вместо одной чистой строки
- Когда 3-й тест не проходит, Busted просто говорит, что
false
не является истинным значением, как ожидалось, и никогда не упоминает сообщение об ошибке "делить на ноль".
Есть ли способ улучшить мой тестовый файл, чтобы избежать этих проблем?
Я думаю, что то, что я хочу сделать, похоже на has_error
утверждение в busted, но это, кажется, только для функций, которые на самом деле вызывают исключения, а не для функций, которые возвращают false
с последующим сообщением об ошибке.
1 ответ
Busted использует luassert, который может быть расширен вашими утверждениями.
Например, следующий код использует пользовательское утверждение answers
в качестве первого параметра берется таблица ожидаемого результата, а эффективная функция - в качестве оставшихся параметров.
local assert = require "luassert"
local function safe_divide(a, b)
if b > 0 then -- buggy! should be b ~= 0
return a / b
else
return false, "division by zero"
end
end
local function answers(state, arguments)
local expected = arguments[1]
assert(type(expected) == "table")
for i = 2, #arguments do
if arguments[i] ~= expected[i-1] then
state.failure_message = "unexpected result " .. tostring (i-1) .. ": " .. tostring (arguments [i])
return false
end
end
return true
end
assert:register("assertion", "answers", answers)
describe("safe_divide", function()
it("can divide by positive numbers", function()
assert.answers({ 2.0 }, safe_divide(10.0, 5.0))
end)
it("errors when dividing by zero", function()
assert.answers({ false, "division by zero" }, safe_divide(10.0, 0.0))
end)
it("can divide by negative numbers", function()
assert.answers({ 2.0 }, safe_divide(-10.0, -5.0))
end)
end)
В этом коде отсутствует правильное форматирование сообщения подтверждения. Вы можете посмотреть на luaassert
документация или по заранее определенным утверждениям. Он содержит say
модуль для перевода сообщений.