Еще до RSpec и Cucumber существовала базовая библиотека в Ruby под названием Test Unit . Это была просто основа для модульного тестирования кода. Однако, начиная с Ruby 1.9.3, Test Unit был заменен Minitest в качестве включенной среды тестирования для Ruby. В этой статье мы рассмотрим Minitest (поскольку он теперь заменил Test Unit) и преимущества musta-context , инфраструктуры Test::Unit
Minitest
Предпосылки
- Рубин (дух; текущий 2.1.2 будет лучшим)
- Возможность запуска
gem install GEM
- Небольшое количество знаний о TDD, с разбрызгиванием BDD.
Разработка через тестирование (TDD) всегда была постоянным явлением в сообществе Ruby. Это ключевая концепция экстремального программирования и используется практически в каждом проекте Ruby. Создание модульных тестов с помощью Minitest очень просто, но для начала нам нужна библиотека Ruby для тестирования. Наша окончательная структура проекта будет выглядеть так:
.
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── lib
│ └── calculator.rb
└── test
├── test_calculator.rb
├── test_calculator_basic.rb
└── test_helper.rb
Вы можете найти репо для этого проекта здесь .
Наша библиотека представляет собой калькулятор с двумя методами: add
subtract
class Calculator
def add(num1, num2)
num1 + num2
end
def subtract(num1, num2)
num1 - num2
end
end
Чтобы протестировать эту библиотеку с помощью Minitest, создайте тестовый класс, который наследуется от Minitest::Test
# file: test/test_calculator_basic.rb
require 'minitest/autorun'
require 'calculator' # don't worry, this works
class TestCalculator < Minitest::Test
end
Тесты внутри этого класса — это методы, которые начинаются с test_
# file: test/test_calculator_basic.rb
require 'minitest/autorun'
require 'calculator'
class TestCalculator < Minitest::Test
def setup
@calc = Calculator.new
end
def test_proper_addition
assert_equal 4, @calc.add(2, 2)
end
def test_proper_subtraction
assert_equal 0, @calc.subtract(2, 2)
end
end
Чтобы запустить этот тест, используйте следующую команду: $ ruby -I test:lib test/test_calculator_basic.rb
Это может показаться немного повторяющимся, особенно если вы планируете использовать CI-сервер, поэтому мы можем использовать простую задачу Rake для автоматизации.
# file: Rakefile
require 'rake/testtask'
Rake::TestTask.new do |task|
task.libs << %w(test lib)
task.pattern = 'test/test_*.rb'
end
task :default => :test
Теперь тесты запускаются простым вызовом rake
rake test
Это должно дать нам следующий вывод:
Run options: --seed 41508
# Running:
..
Finished in 0.001047s, 1910.2197 runs/s, 1910.2197 assertions/s.
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
Как видите, наши тесты пройдены. Давайте добавим еще немного …
# file: lib/test_calculator_basic.rb
require 'minitest/autorun'
require 'calculator'
class TestCalculator < Minitest::Test
def setup
@calc = Calculator.new
end
# add
def test_add
assert_equal 4, @calc.add(2, 2)
end
def test_failing_add
refute_equal 5, @calc.add(2, 2)
end
# subtract
def test_subtract
assert_equal 0, @calc.subtract(2, 2)
end
def test_failing_subtract
refute_equal -1, @calc.subtract(2, 2)
end
end
Результаты этого аналогичны последним.
Run options: --seed 4571
# Running:
....
Finished in 0.001081s, 3700.2775 runs/s, 3700.2775 assertions/s.
4 runs, 4 assertions, 0 failures, 0 errors, 0 skips
Возможно, вы заметили, что методы тестирования становятся все более запутанными для чтения. Это потому, что вы ограничены_underscored_names_as_tests. Вот тут-то и должен появиться контекст контекстной рекламы . Хорошие ребята из сайта Thinkbot создали эту библиотеку, чтобы помочь предоставить контекст для модульных тестов. Вот вышеописанный тест, написанный в формате musta-context:
by_underscored_names_as_tests
Если вы еще этого не сделали, запустите # file: lib/test_calculator.rb
require 'minitest/autorun'
require 'shoulda/context'
require 'calculator'
class TestCalculator < Minitest::Test
context 'a calculator' do
setup do # notice the difference
@calc = Calculator.new
end
should 'add two numbers properly' do
assert_equal 4, @calc.add(2, 2)
end
should 'not add incorrectly' do
refute_equal 5, @calc.add(2, 2)
end
should 'subtract two numbers properly' do
assert_equal 0, @calc.subtract(2, 2)
end
should 'not subtract incorrectly' do
refute_equal -1, @calc.subtract(2, 2)
end
end
end
Как видите, тесты гораздо более читабельны. Человек может читать тесты следующим образом: gem install shoulda-context
Например, первый тест можно прочитать так: context: should 'do something'
Это гораздо более выразительно, чем в предыдущем примере. Тесты теперь кажутся более Ruby-esque.
Расширение: Выход
Если вы следовали вместе с примерами кода, то можете заметить, что результаты теста не так хороши, как результаты RSpec или Cucumber. Чтобы исправить это, мы можем использовать маленький драгоценный камень под названием minitest-reporters .
Во-первых, мы собираемся разделить наши тесты немного больше. Если у вас есть опыт работы с Rails и тестированием, то вы, вероятно, использовали a calculator should add two numbers properly
Мы можем сделать то же самое в нашем проекте, просто создав файл в нашей test_helper.rb
test_helper.rb
Внутри test_helper.rb
require
# file: test/test_helper.rb
require 'minitest/autorun'
require 'shoulda/context'
Обратите внимание, что мы не включили require 'calculator'
Это сделано потому, что мы могли бы расширить нашу библиотеку в какой-то момент за пределы класса Calculator
Поскольку не все, что мы тестируем в нашей библиотеке, нужно будет включать calculator
test_helper.rb
Наш тестовый файл калькулятора должен выглядеть примерно так:
# file: test/test_calculator.rb
require 'test_helper'
require 'calculator'
# ... lots of tests ...
Чтобы настроить minitest-reporters с нашей новой настройкой, сначала установите gem ( gem install minitest-reporters
Теперь снова откройте test_helper.rb
# file: test/test_helper.rb
require 'minitest/autorun'
require 'minitest/reporters' # requires the gem
require 'shoulda/context'
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new # spec-like progress
Если мы запустим тесты ( ruby -I test:lib test/test_calculator.rb
rake test
Started
TestCalculator
test: a calculator should subtract two numbers properly. PASS (0.00s)
test: a calculator should not add incorrectly. PASS (0.00s)
test: a calculator should add two numbers properly. PASS (0.00s)
test: a calculator should not subtract incorrectly. PASS (0.00s)
Finished in 0.00141s
4 tests, 4 assertions, 0 failures, 0 errors, 0 skips
Гораздо читабельнее и имеет цвет! Обратите внимание, что формат такой же, как и при чтении тестов для человека. Так и должно быть.
Вывод
Тестирование не только рекомендуется, но и практически необходимо при работе над проектом Ruby. Такие инструменты, как musta-context , помогут вам облегчить этот процесс. Мы рассмотрели основы Minitest, автоматизированное тестирование, контекст «следует» и причудливый (цветной, читаемый человеком) вывод. Если вы хотите узнать больше, проверьте эти ссылки:
- Библиотека Минитест (входит в состав Ruby)
- Минитест Репо (официальный репозиторий)
- musta-context (musta-context страница GitHub)
- minitest-репортеры (страница minitest-репортеров GitHub)
- Код из этой статьи (весь код из этой статьи)
- Экстремальное программирование — Википедия (страница Википедии о XP)
- Экстремальное программирование — Официально (официальный сайт XP)
- DDH Обиделся RSpec (старый, но все еще актуальный)