Как написать тестовые модульные тесты для функций, которые возвращают нормально, ошибаться?

У меня есть функция 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 модуль для перевода сообщений.

Другие вопросы по тегам