Шаг 10. Тесты
Зачем#
Если тесты — это отдельный фреймворк со своими соглашениями, их пишут реже. В OxL test — объявление языка: компилятор
знает о тестах, не включает их в обычную сборку и проверяет вместе с остальным кодом. Утверждения assert печатают значения
всех подвыражений при падении, так что сообщение о сбое обычно понятно без отладчика.
Первый тест#
Тест — test "имя" { … } рядом с кодом или в каталоге tests/. Запуск — oxl test (для одного файла: oxl test файл.oxl).
fn clamp(x: i32, lo: i32, hi: i32) -> i32 pure => if x < lo { lo } else if x > hi { hi } else { x }
test "clamp keeps values inside the range" {
assert_eq(clamp(5, 0, 10), 5)
assert_eq(clamp(-3, 0, 10), 0)
assert_eq(clamp(99, 0, 10), 10)
}
test "table-driven" { // табличный тест: данные + цикл
let cases = [(1, 0, 3, 1), (-5, 0, 3, 0), (7, 0, 3, 3)]
for (x, lo, hi, want) in cases {
assert_eq(clamp(x, lo, hi), want)
}
}
test fuzz "clamp stays in range" (x: i32, lo: i32) { // фаззинг: аргументы генерирует рантайм
let hi = lo.saturating_add(10)
let c = clamp(x, lo, hi)
assert c >= lo && c <= hi
}Вывод oxl test:
running 2 tests
test main::clamp keeps values inside the range ... ok
test main::table-driven ... ok
test result: ok. 2 passed; 0 failed; 0 skippedРазбор#
assert_eq(a, b)печатает обе стороны при расхождении;assert cond,assert x is T,assert_ne,assert_fails(expr, ErrorType)иassert_snapshot(&value)— остальные утверждения (§18.2).- Табличный тест — это обычный список кортежей и цикл
for: отдельного синтаксиса не нужно. Добавьте строку в таблицу — получите новый случай. test fuzz "…" (x: i32, lo: i32)— фаззинг: параметры теста генерирует рантайм (с учётом уточнённых типов), а упавший вход сохраняется для повторного запуска (oxl test --kind fuzz, руководство).- Тело теста может использовать
?— ошибка проваливает тест с выводом ошибки.
Фикстуры, моки и симуляция#
fixture name() -> T { …; yield value; …очистка }иtest "…" with name as x { … }— подготовка и очистка ресурсов.mock Service { метод(образец) => ответ once, then … }подменяет сервис,Service.calls(.метод)записывает вызовы.test sim "…" seeds 1..=300— детерминированная симуляция с виртуальными часами и сетью: час проходит мгновенно, а упавшийseedвоспроизводится командойoxl test --seed N.
Примеры всех трёх — в туре по тестам и в рецептах.
Типичная ошибка: параметры у обычного теста#
Параметры допустимы только у test fuzz. Обычный тест с параметром — ошибка test-decl:
test "sum" (x: i64) {
assert x + 0 == x
}error
test-decl
Замените test "sum" на test fuzz "sum".
Что запомнить#
test— объявление языка;oxl testзапускает тесты параллельно.- Табличные тесты — цикл по списку; фаззинг —
test fuzzс параметрами. - Держите логику
pure: её тестировать проще всего (шаг 8).
Дальше: конкурентность.