133
Юнит-тестирование Lua-кода при помощи TAP Илья Чесноков

Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

  • Upload
    others

  • View
    17

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Юнит-тестирование Lua-кода

при помощи TAPИлья Чесноков

Page 2: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Все началось...

!2

Page 3: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

С маленькой программки на Lua

!3

Page 4: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

...несколько юнит-тестов...

!4

Page 5: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

lua-TestMore

!5

Page 6: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Test Anything Protocol (TAP)

!6

Page 7: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Test Anything Protocol (TAP)

• Текстовый интерфейс между тестовыми модулями и средой

• Во многих ЯП есть библиотеки для генерации

• Потребляется большинством CI-систем

!7

Page 8: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

TAP output

1..4 ok 1 - Input file opened not ok 2 - First line of the input valid ok 3 - Read the rest of the file not ok 4 - Summarized correctly # TODO Not written yet

!8

Page 9: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

TAP output: test plan

1..4 ok 1 - Input file opened not ok 2 - First line of the input valid ok 3 - Read the rest of the file not ok 4 - Summarized correctly # TODO Not written yet

!9

Page 10: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

TAP output: test result

1..4 ok 1 - Input file opened not ok 2 - First line of the input valid ok 3 - Read the rest of the file not ok 4 - Summarized correctly # TODO Not written yet

!10

Page 11: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

TAP output: test number

1..4 ok 1 - Input file opened not ok 2 - First line of the input valid ok 3 - Read the rest of the file not ok 4 - Summarized correctly # TODO Not written yet

!11

Page 12: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

TAP output: description

1..4 ok 1 - Input file opened not ok 2 - First line of the input valid ok 3 - Read the rest of the file not ok 4 - Summarized correctly # TODO Not written yet

!12

Page 13: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

TAP output: directives

1..4 ok 1 - Input file opened not ok 2 - First line of the input valid ok 3 - Read the rest of the file not ok 4 - Summarized correctly # TODO Not written yet

!13

Page 14: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

To planor not to plan?

!14

Page 15: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/plan2.lua#!/usr/bin/env lua

require 'Test.More'

plan(2) pass('First test') pass('Second test') pass('Third test')

!15

Page 16: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/plan2.lua#!/usr/bin/env lua

require 'Test.More'

plan(2) pass('First test') pass('Second test') pass('Third test')

!16

Page 17: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/plan2.lua#!/usr/bin/env lua

require 'Test.More'

plan(2) pass('First test') pass('Second test') pass('Third test')

!17

Page 18: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

lua t/plan2.lua

1..2 ok 1 - First test ok 2 - Second test ok 3 - Third test

!18

Page 19: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/plan2.luat/plan2.lua .. 1..2 ok 1 - First test ok 2 - Second test ok 3 - Third test All 2 subtests passed

Test Summary Report ------------------- t/plan2.lua (Wstat: 0 Tests: 3 Failed: 1) Failed test: 3 Parse errors: Bad plan. You planned 2 tests but ran 3. Files=1, Tests=3, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!19

Page 20: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/plan2.luat/plan2.lua .. 1..2 ok 1 - First test ok 2 - Second test ok 3 - Third test All 2 subtests passed

Test Summary Report ------------------- t/plan2.lua (Wstat: 0 Tests: 3 Failed: 1) Failed test: 3 Parse errors: Bad plan. You planned 2 tests but ran 3. Files=1, Tests=3, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!20

Page 21: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/done_testing.luarequire 'Test.More'

pass('First test') pass('Second test') pass('Third test')

done_testing()

!21

Page 22: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/done_testing.luat/plan2.lua .. ok 1 - First test ok 2 - Second test ok 3 - Third test 1..3 ok All tests successful. Files=1, Tests=3, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: PASS

!22

Page 23: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Директива TODO

!23

Page 24: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/todo.luarequire 'Test.More'

pass('Passing test') todo('Will fix later', 1) fail('Failing test')

done_testing()

!24

Page 25: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/todo.luat/todo.lua .. ok 1 - Passing test not ok 2 - Failing test # TODO Will fix later # Failed (TODO) test (t/todo.lua at line 7) 1..2 ok All tests successful. Files=1, Tests=2, 0 wallclock secs ( 0.04 usr + 0.01 sys = 0.05 CPU) Result: PASS

!25

Page 26: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/todo.luat/todo.lua .. ok 1 - Passing test not ok 2 - Failing test # TODO Will fix later # Failed (TODO) test (t/todo.lua at line 7) 1..2 ok All tests successful. Files=1, Tests=2, 0 wallclock secs ( 0.04 usr + 0.01 sys = 0.05 CPU) Result: PASS

!26

Page 27: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/todo.luat/todo.lua .. ok 1 - Passing test not ok 2 - Failing test # TODO Will fix later # Failed (TODO) test (t/todo.lua at line 7) 1..2 ok All tests successful. Files=1, Tests=2, 0 wallclock secs ( 0.04 usr + 0.01 sys = 0.05 CPU) Result: PASS

!27

Page 28: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Директива SKIP

!28

Page 29: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/skip_all.luarequire 'Test.More'

local Redis = require 'redis' if not pcall(Redis.connect) then skip_all('Redis is not available') end

-- ...

done_testing()

!29

Page 30: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/skip_all.luarequire 'Test.More'

local Redis = require 'redis' if not pcall(Redis.connect) then skip_all('Redis is not available') end

-- ...

done_testing()

!30

Page 31: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/skip_all.lua

t/skip_all.lua .. skipped: Redis is not available Files=1, Tests=0, 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) Result: NOTESTS

!31

Page 32: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/skip_all.lua

t/skip_all.lua .. skipped: Redis is not available Files=1, Tests=0, 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) Result: NOTESTS

!32

Page 33: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

testanything.org

!33

Page 34: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Test.More

!34

Page 35: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Test.More asserts• ok(got, title) - проверка на true

• is(got, expected, title) - проверка got == expected

• like(got, pattern, title) - проверка на regex

• cmp_ok(this, op, that, title) - сравнение оператором op

• и др.

!35

Page 36: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Test.More asserts• ok(got, title) - проверка на true

• is(got, expected, title) - проверка got == expected

• like(got, pattern, title) - проверка на regex

• cmp_ok(this, op, that, title) - сравнение оператором op

• и др.

!36

Page 37: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Пример: lib/adder.lua

return {

-- add() - sums up 2 numbers and returns result add = function(x, y) return x + y end

}

!37

Page 38: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/adder.lua-- Export all the Test.More functions as globals require('Test.More') local adder = require('adder')

plan(2) -- Plan 2 tests is(adder.add(2.0001, 1.9999), 4, '2.0001 + 1.9999 == 4') is(adder.add(1e100, 2e100), 3e100, '1e100 + 2e100 == 3e100')

!38

Page 39: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/adder.lua-- Export all the Test.More functions as globals require('Test.More') local adder = require('adder')

plan(2) -- Plan 2 tests is(adder.add(2.0001, 1.9999), 4, '2.0001 + 1.9999 == 4') is(adder.add(1e100, 2e100), 3e100, '1e100 + 2e100 == 3e100')

!39

Page 40: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/adder.lua-- Export all the Test.More functions as globals require('Test.More') local adder = require('adder')

plan(2) -- Plan 2 tests is(adder.add(2.0001, 1.9999), 4, '2.0001 + 1.9999 == 4') is(adder.add(1e100, 2e100), 3e100, '1e100 + 2e100 == 3e100')

!40

Page 41: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/adder.lua-- Export all the Test.More functions as globals require('Test.More') local adder = require('adder')

plan(2) -- Plan 2 tests is(adder.add(2.0001, 1.9999), 4, '2.0001 + 1.9999 == 4') is(adder.add(1e100, 2e100), 3e100, '1e100 + 2e100 == 3e100')

!41

Page 42: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/adder.lua

!42

Page 43: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/adder.lua .. 1..2 ok 1 - 2.0001 + 1.9999 == 4 not ok 2 - 1e100 + 2e100 == 3e100 # Failed test (t/adder.lua at line 10) # got: 3e+100 # expected: 3e+100 Failed 1/2 subtests

Test Summary Report ------------------- t/adder.lua (Wstat: 0 Tests: 2 Failed: 1) Failed test: 2 Files=1, Tests=2, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!43

Page 44: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Программа выросла: больше юнит-тестов

!44

Page 45: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Пожелания для юнит-тестирования• Структуризация

• Один класс / модуль — один тестовый файл

• Один метод класса — один тестовый метод

• Повторное использование кода в ООП-стиле

• Возможность подготовки / очистки тестовых данных

• Запуск тестов для отдельного класса / метода

!45

Page 46: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Лаконичные assert-ы

Структури-зация Наследование

Подготовка/очистка данных

Выборочный запуск

Test.More

!46

Page 47: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Lua-фреймворки

• Busted

• LuaUnit

• Telescope, lunit, ...

• http://lua-users.org/wiki/UnitTesting

!47

Page 48: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Busted

!48

Page 49: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Busted asserts: luassert

• assert.is_true(got), assert.is_not.True(got), ...

• assert.are.equal(expected, got), ...

• assert.has.errors(function() error("this should fail") end)

• ...

!49

Page 50: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Busted asserts: luassert

• Можно добавлять свои assert-ы

• Поддерживаются моки, асинхронные тесты и т.д.

!50

Page 51: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

busted/adder_spec.luarequire('busted.runner')() local adder = require('adder') local assert = require('luassert')

describe("Function add()", function()

it('can add 2.0001 and 1.9999', function() assert.are.equal(4, adder.add(2.0001, 1.9999)) end)

it('can add 1e100 and 2e100', function() assert.are.equal(3e100, adder.add(1e100, 2e100)) end) end)

!51

Page 52: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

busted/adder_spec.luarequire('busted.runner')() local adder = require('adder') local assert = require('luassert')

describe("Function add()", function()

it('can add 2.0001 and 1.9999', function() assert.are.equal(4, adder.add(2.0001, 1.9999)) end)

it('can add 1e100 and 2e100', function() assert.are.equal(3e100, adder.add(1e100, 2e100)) end) end)

!52

Page 53: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

busted/adder_spec.luarequire('busted.runner')() local adder = require('adder') local assert = require('luassert')

describe("Function add()", function()

it('can add 2.0001 and 1.9999', function() assert.are.equal(4, adder.add(2.0001, 1.9999)) end)

it('can add 1e100 and 2e100', function() assert.are.equal(3e100, adder.add(1e100, 2e100)) end) end)

!53

Page 54: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

.busted

return { _all = { output = 'TAP', }, }

!54

Page 55: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm busted/adder_spec.lua

!55

Page 56: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

busted/adder_spec.lua .. ok 1 - Function add() can add 2.0001 and 1.9999 not ok 2 - Function add() can add 1e100 and 2e100 # busted/adder_spec.lua @ 13 # Failure message: busted/adder_spec.lua:14: Expected objects to be equal. # Passed in: # (number) 3.000000000000000242e+100 # Expected: # (number) 2.9999999999999998534e+100 1..2 Dubious, test returned 1 (wstat 256, 0x100) Failed 1/2 subtests

Test Summary Report ------------------- busted/adder_spec.lua (Wstat: 256 Tests: 2 Failed: 1) Failed test: 2 Non-zero exit status: 1 Files=1, Tests=2, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.02 cusr 0.01 csys = 0.05 CPU) Result: FAIL

!56

Page 57: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

busted/adder_spec.lua .. ok 1 - Function add() can add 2.0001 and 1.9999 not ok 2 - Function add() can add 1e100 and 2e100 # busted/adder_spec.lua @ 13 # Failure message: busted/adder_spec.lua:14: Expected objects to be equal. # Passed in: # (number) 3.000000000000000242e+100 # Expected: # (number) 2.9999999999999998534e+100 1..2 Dubious, test returned 1 (wstat 256, 0x100) Failed 1/2 subtests

Test Summary Report ------------------- busted/adder_spec.lua (Wstat: 256 Tests: 2 Failed: 1) Failed test: 2 Non-zero exit status: 1 Files=1, Tests=2, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.02 cusr 0.01 csys = 0.05 CPU) Result: FAIL

!57

Page 58: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Лаконичные assert-ы

Структури-зация Наследование

Подготовка/очистка данных

Выборочный запуск

Test.More

Busted

!58

Page 59: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

LuaUnit

!59

Page 60: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

LuaUnit asserts• assert_true(value) / assert_false(value)

• assert_nil(value) / assert_not_nil(value)

• assert_equals(actual, expected) / assert_not_equals(actual, expected)

• assert_str_contains(str, sub, [, useRe])

• ...

!60

Page 61: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

luaunit/tests/TestAdder.lua-- Global table! TestAdder = {}

local adder = require('adder')

function TestAdder:test_add() assert_equals(adder.add(2.0001, 1.9999), 4) assert_equals(adder.add(1e100, 2e100), 3e100) end

!61

Page 62: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

luaunit/run_tests.luaEXPORT_ASSERT_TO_GLOBALS = true local luaunit = require('luaunit')

-- Load test library require('TestAdder')

lu = luaunit.LuaUnit.new() lu:setOutputType('tap') lu:runSuite()

!62

Page 63: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm luaunit/run_tests.lua

!63

Page 64: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

luaunit/run_tests.lua .. 1..1 # Started on Sun May 6 19:15:46 2018 # Starting class: TestAdder not ok 1 TestAdder.test_add # luaunit/tests/TestAdder.lua:8: expected: 3e+100, actual: 3e+100 # Ran 1 tests in 0.001 seconds, 0 successes, 1 failure Failed 1/1 subtests

Test Summary Report ------------------- luaunit/run_tests.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!64

Page 65: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

luaunit/run_tests.lua .. 1..1 # Started on Sun May 6 19:15:46 2018 # Starting class: TestAdder not ok 1 TestAdder.test_add # luaunit/tests/TestAdder.lua:8: expected: 3e+100, actual: 3e+100 # Ran 1 tests in 0.001 seconds, 0 successes, 1 failure Failed 1/1 subtests

Test Summary Report ------------------- luaunit/run_tests.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!65

Page 66: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Лаконичные assert-ы

Структури-зация Наследование

Подготовка/очистка данных

Выборочный запуск

Test.More

Busted

LuaUnit

!66

Page 67: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

LuaUnit: особенности

• Каждый тест:

• в отдельной глобальной таблице (модуле) "by design"

• Тестовые сообщения задавать нельзя вообще

• Фреймворк "перегружен" лишними проверками и функциями

!67

Page 68: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Что можно сделать?

!68

Page 69: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Perl: Test::Class...

!69

Page 70: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

...основан на jUnit...

!70

Page 71: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

...использует Test::More!

!71

Page 72: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Lua: ...?

!72

Page 73: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

...lua-TestClass!

!73

Page 74: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tests/TestsFor/Adder.lualocal _M = require('middleclass')('TestsFor.Adder', require('Test.Class')) require('Test.More')

local adder = require('adder')

function _M:test_add() is(adder.add(2.0001, 1.9999), 4, '2.0001 plus 1.9999 equals 4') is(adder.add(1e100, 2e100), 3e100, '1e100 plus 2e100 equals 3e100') end

return _M

!74

Page 75: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tests/TestsFor/Adder.lualocal _M = require('middleclass')('TestsFor.Adder', require('Test.Class')) require('Test.More')

local adder = require('adder')

function _M:test_add() is(adder.add(2.0001, 1.9999), 4, '2.0001 plus 1.9999 equals 4') is(adder.add(1e100, 2e100), 3e100, '1e100 plus 2e100 equals 3e100') end

return _M

!75

Page 76: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tests/TestsFor/Adder.lualocal _M = require('middleclass')('TestsFor.Adder', require('Test.Class')) require('Test.More')

local adder = require('adder')

function _M:test_add() is(adder.add(2.0001, 1.9999), 4, '2.0001 plus 1.9999 equals 4') is(adder.add(1e100, 2e100), 3e100, '1e100 plus 2e100 equals 3e100') end

return _M

!76

Page 77: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tests/TestsFor/Adder.lualocal _M = require('middleclass')('TestsFor.Adder', require('Test.Class')) require('Test.More')

local adder = require('adder')

function _M:test_add() is(adder.add(2.0001, 1.9999), 4, '2.0001 plus 1.9999 equals 4') is(adder.add(1e100, 2e100), 3e100, '1e100 plus 2e100 equals 3e100') end

return _M

!77

Page 78: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tests/TestsFor/Adder.lualocal _M = require('middleclass')('TestsFor.Adder', require('Test.Class')) require('Test.More')

local adder = require('adder')

function _M:test_add() is(adder.add(2.0001, 1.9999), 4, '2.0001 plus 1.9999 equals 4') is(adder.add(1e100, 2e100), 3e100, '1e100 plus 2e100 equals 3e100') end

return _M

!78

Page 79: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tests/TestsFor/Adder.lualocal _M = require('middleclass')('TestsFor.Adder', require('Test.Class')) require('Test.More')

local adder = require('adder')

function _M:test_add() is(adder.add(2.0001, 1.9999), 4, '2.0001 plus 1.9999 equals 4') is(adder.add(1e100, 2e100), 3e100, '1e100 plus 2e100 equals 3e100') end

return _M

!79

Page 80: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tests/TestsFor/Adder.lualocal _M = require('middleclass')('TestsFor.Adder', require('Test.Class')) require('Test.More')

local adder = require('adder')

function _M:test_add() is(adder.add(2.0001, 1.9999), 4, '2.0001 plus 1.9999 equals 4') is(adder.add(1e100, 2e100), 3e100, '1e100 plus 2e100 equals 3e100') end

return _M

!80

Page 81: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.luarequire('TestsFor.Adder')

local tc = require('Test.Class') tc.run_tests()

!81

Page 82: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

prove -vm t/tc.lua

!82

Page 83: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.lua .. # Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # Failed test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 not ok 1 - test_add # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 53) 1..1 not ok 1 - TestsFor.Adder # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 18) 1..1 Failed 1/1 subtests

Test Summary Report ------------------- t/tc.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!83

Page 84: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.lua .. # Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # Failed test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 not ok 1 - test_add # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 53) 1..1 not ok 1 - TestsFor.Adder # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 18) 1..1 Failed 1/1 subtests

Test Summary Report ------------------- t/tc.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!84

Page 85: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.lua .. # Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # Failed test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 not ok 1 - test_add # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 53) 1..1 not ok 1 - TestsFor.Adder # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 18) 1..1 Failed 1/1 subtests

Test Summary Report ------------------- t/tc.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!85

Page 86: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.lua .. # Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # Failed test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 not ok 1 - test_add # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 53) 1..1 not ok 1 - TestsFor.Adder # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 18) 1..1 Failed 1/1 subtests

Test Summary Report ------------------- t/tc.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!86

Page 87: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.lua .. # Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # Failed test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 not ok 1 - test_add # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 53) 1..1 not ok 1 - TestsFor.Adder # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 18) 1..1 Failed 1/1 subtests

Test Summary Report ------------------- t/tc.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!87

Page 88: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.lua .. # Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # Failed test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 not ok 1 - test_add # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 53) 1..1 not ok 1 - TestsFor.Adder # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 18) 1..1 Failed 1/1 subtests

Test Summary Report ------------------- t/tc.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!88

Page 89: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.lua .. # Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # Failed test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 not ok 1 - test_add # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 53) 1..1 not ok 1 - TestsFor.Adder # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 18) 1..1 Failed 1/1 subtests

Test Summary Report ------------------- t/tc.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!89

Page 90: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.lua .. # Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # Failed test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 not ok 1 - test_add # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 53) 1..1 not ok 1 - TestsFor.Adder # Failed test (/Users/ichesnokov/git/lua-TestClass/lib/Test/Class.lua at line 18) 1..1 Failed 1/1 subtests

Test Summary Report ------------------- t/tc.lua (Wstat: 0 Tests: 1 Failed: 1) Failed test: 1 Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: FAIL

!90

Page 91: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Добавим ещё один класс

!91

Page 92: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

lib/Subtractor.luareturn {

-- subtract() - subtracts y from x and returns result subtract = function(x, y) return x - y end

}

!92

Page 93: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.luarequire('TestsFor.Adder') require('TestsFor.Subtractor')

local tc = require('Test.Class') tc.run_tests()

!93

Page 94: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

# Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # TODO FP precision error # Failed (TODO) test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 ok 1 - test_add 1..1 ok 1 - TestsFor.Adder # Running tests for TestsFor.Subtractor # # Subtest: TestsFor.Subtractor # TestsFor.Subtractor.test_subtract() # Subtest: test_subtract ok 1 - 1 minus 1 equals 0 ok 2 - 0 minus -100 equals 100 1..2 ok 1 - test_subtract 1..1 ok 2 - TestsFor.Subtractor

!94

Page 95: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

# Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # TODO FP precision error # Failed (TODO) test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 ok 1 - test_add 1..1 ok 1 - TestsFor.Adder # Running tests for TestsFor.Subtractor # # Subtest: TestsFor.Subtractor # TestsFor.Subtractor.test_subtract() # Subtest: test_subtract ok 1 - 1 minus 1 equals 0 ok 2 - 0 minus -100 equals 100 1..2 ok 1 - test_subtract 1..1 ok 2 - TestsFor.Subtractor

!95

Page 96: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

# Running tests for TestsFor.Adder # # Subtest: TestsFor.Adder # TestsFor.Adder.test_add() # Subtest: test_add ok 1 - 2.0001 plus 1.9999 equals 4 not ok 2 - 1e100 plus 2e100 equals 3e100 # TODO FP precision error # Failed (TODO) test (t/tests/TestsFor/Adder.lua at line 9) # got: 3e+100 # expected: 3e+100 1..2 ok 1 - test_add 1..1 ok 1 - TestsFor.Adder # Running tests for TestsFor.Subtractor # # Subtest: TestsFor.Subtractor # TestsFor.Subtractor.test_subtract() # Subtest: test_subtract ok 1 - 1 minus 1 equals 0 ok 2 - 0 minus -100 equals 100 1..2 ok 1 - test_subtract 1..1 ok 2 - TestsFor.Subtractor

!96

Page 97: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Как загрузить много тестовых классов?

!97

Page 98: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc.luarequire('TestsFor.Adder') require('TestsFor.Subtractor') require('TestsFor.Multiplier') require('TestsFor.Divider') require('TestsFor.Utils') require('TestsFor.Context') require('TestsFor.Character') require('TestsFor.Station') require('TestsFor.Travel')

-- ...

local tc = require('Test.Class') tc.run_tests()

!98

Page 99: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc-load.lualocal tc = require('Test.Class')

tc.load_classes('t/tests') tc.run_tests()

!99

Page 100: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

load_classes(dir)• Рекурсивно обходит указанную директорию в поисках .lua файлов

• Для каждого найденного файла:

• Преобразует имя файла в имя модуля

• Загружает его при помощи require()

• Если это наследник Test.Class - добавляет в список для запуска

!100

Page 101: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc-load.lualocal tc = require('Test.Class')

tc.load_classes('t/tests') tc.run_tests()

!101

Page 102: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

run_tests(arg)• Для каждого тестового класса из списка:

• создает объект при помощи new()...

• ...и запускает на нем тестовые методы

• arg - таблица с опциональным параметром:

• include - регулярное выражение, ограничивающее методы для запуска

!102

Page 103: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Подготовка / очистка тестовых данных

!103

Page 104: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

...для тестового класса

• test_startup() - подготовка

• test_shutdown() - очистка

!104

Page 105: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

...для тестового метода

• test_setup() - подготовка

• self.current_method - имя метода

• test_teardown() - очистка

!105

Page 106: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Наследование

!106

Page 107: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

– Принцип подстановки Барбары Лисков (определение Роберта С. Мартина)

“Функции, которые используют базовый тип, должны иметь возможность

использовать подтипы базового типа, не зная об этом.”

!107

Page 108: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Parent', require('Test.Class')) require 'Test.More'

function _M:test_parent() pass('I am a test of parent') end

return _M

!108

Page 109: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Parent', require('Test.Class')) require 'Test.More'

function _M:test_parent() pass('I am a test of parent') end

return _M

!109

Page 110: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Parent', require('Test.Class')) require 'Test.More'

function _M:test_parent() pass('I am a test of parent') end

return _M

!110

Page 111: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Parent', require('Test.Class')) require 'Test.More'

function _M:test_parent() pass('I am a test of parent') end

return _M

!111

Page 112: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Child', require('TestsFor.Parent')) require 'Test.More'

function _M:test_child() pass('I am a test of child') end

return _M

!112

Page 113: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Child', require('TestsFor.Parent')) require 'Test.More'

function _M:test_child() pass('I am a test of child') end

return _M

!113

Page 114: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Child', require('TestsFor.Parent')) require 'Test.More'

function _M:test_child() pass('I am a test of child') end

return _M

!114

Page 115: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc-inheritance.lua .. # Running tests for TestsFor.Parent # # Subtest: TestsFor.Parent # TestsFor.Parent.test_parent() # Subtest: test_parent ok 1 - I am a test of parent 1..1 ok 1 - test_parent 1..1 ok 1 - TestsFor.Parent

# Running tests for TestsFor.Child # ...

!115

Page 116: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

# Running tests for TestsFor.Child # # Subtest: TestsFor.Child # TestsFor.Child.test_child() # Subtest: test_child ok 1 - I am a test of child 1..1 ok 1 - test_child # TestsFor.Child.test_parent() # Subtest: test_parent ok 1 - I am a test of parent 1..1 ok 2 - test_parent 1..2 ok 2 - TestsFor.Child 1..2 ok All tests successful. Files=1, Tests=2, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: PASS

!116

Page 117: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Mixins

!117

Page 118: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

lib/MyTestMixin.luarequire 'Test.More'

return {

pi = 3.1415,

test_from_mixin = function() pass('This test always passes') end }

!118

Page 119: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tests/TestsFor/Mixin.lualocal _M = require('middleclass')('TestsFor.Mixin', require('Test.Class')) :include(require('MyTestMixin'))

function _M:test_pi() pass('PI is: ' .. self.pi) end

return _M

!119

Page 120: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Mixin', require('Test.Class')) :include(require('MyTestMixin'))

function _M:test_pi() pass('PI is: ' .. self.pi) end

return _M

t/tests/TestsFor/Mixin.lua

!120

Page 121: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

local _M = require('middleclass')('TestsFor.Mixin', require('Test.Class')) :include(require('MyTestMixin'))

function _M:test_pi() pass('PI is: ' .. self.pi) end

return _M

t/tests/TestsFor/Mixin.lua

!121

Page 122: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc-mixin.lua .. # Running tests for TestsFor.Mixin # # Subtest: TestsFor.Mixin # TestsFor.Mixin.test_from_mixin() # Subtest: test_from_mixin ok 1 - This test always passes 1..1 ok 1 - test_from_mixin # TestsFor.Mixin.test_pi() # Subtest: test_pi ok 1 - PI is: 3.1415 1..1 ok 2 - test_pi 1..2 ok 1 - TestsFor.Mixin 1..1 ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: PASS

!122

Page 123: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc-mixin.lua .. # Running tests for TestsFor.Mixin # # Subtest: TestsFor.Mixin # TestsFor.Mixin.test_from_mixin() # Subtest: test_from_mixin ok 1 - This test always passes 1..1 ok 1 - test_from_mixin # TestsFor.Mixin.test_pi() # Subtest: test_pi ok 1 - PI is: 3.1415 1..1 ok 2 - test_pi 1..2 ok 1 - TestsFor.Mixin 1..1 ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: PASS

!123

Page 124: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

t/tc-mixin.lua .. # Running tests for TestsFor.Mixin # # Subtest: TestsFor.Mixin # TestsFor.Mixin.test_from_mixin() # Subtest: test_from_mixin ok 1 - This test always passes 1..1 ok 1 - test_from_mixin # TestsFor.Mixin.test_pi() # Subtest: test_pi ok 1 - PI is: 3.1415 1..1 ok 2 - test_pi 1..2 ok 1 - TestsFor.Mixin 1..1 ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.02 usr + 0.00 sys = 0.02 CPU) Result: PASS

!124

Page 125: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Ок, с Test.Class мы можем...

!125

Page 126: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

С Test.Class мы можем• Написать юнит-тест

• Запустить тесты:

• Для выбранных или для всех классов в директории

• Для всех или выбранных методов

• Подготавливать / очищать данные для тестов

• Использовать наследование и примеси

!126

Page 127: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Лаконичные assert-ы

Структури-зация Наследование

Подготовка/очистка данных

Выборочный запуск

Test.More

Busted

LuaUnit

Test.Class

!127

Page 128: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Test.Class - особенности

• Работает только на *nix-based системах (сейчас)

• Нет тестов, документации

• Ранняя альфа версия - возможны (и наверняка будут) изменения

!128

Page 129: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Использовать на свой страх и риск ;-)

!129

Page 130: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Test.Class - wishlist / plans• Поддержка тестового плана

• "Автоплан" по количеству тестовых классов / методов

• Пропуск тестовых классов / методов

• Меньше boilerplate в начале тестовых классов

!130

Page 131: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Скачать (бесплатно, без sms)• Busted: luarocks.org

• LuaUnit: luarocks.org

• lua-TestMore: luarocks.org

• github.com/ichesnokov/lua-TestClass

!131

Page 132: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Вопросы?

!132

Page 133: Юнит тестирование Lua-кода при помощи TAP fileTest Anything Protocol (TAP) • Текстовый интерфейс между тестовыми модулями

Спасибо!