Crystal поставляется в комплекте с модулем Spec
def add(value1, value2)
valuel + value2
end
Соответствующие тесты для этого могут выглядеть так:
require "spec"
require "./add"
describe "#add" do
it "adds with positive values" do
add(1, 2).should eq 3
end
it "adds with negative values" do
add(-1, -2).should eq -3
end
it "adds with mixed signed values" do
add(-1, 2).should eq 1
end
end
Сначала нам нужен модуль Spec
#describe
для создания группы связанных тестов — в данном случае всех тех, которые связаны с методом #add
. Затем мы используем метод #it
для определения конкретных тестовых случаев, в которых мы утверждаем, что он возвращает правильное значение. У нас есть некоторые из них, определенные для примера. В идеале у вас должен быть тестовый пример для каждого потока, через который может пройти код, и обязательно добавлять новые по мере исправления ошибок.Если вы тестировали этот метод как часть сегмента, вам нужно было бы создать файл в папке
_spec
, например --order=random
для crystal spec
. Это запустит все тестовые примеры в случайном порядке, что может помочь выявить случаи, когда одна спецификация требует запуска предыдущей, а это не то, что вам нужно.Файл
crystal init
, используется в качестве точки входа в тесты проекта. Этот файл обычно требует спецификации, исходного кода проекта, а также любых других файлов, специфичных для спецификации, таких как фикстуры или макеты. Здесь также могут быть определены глобальные помощники тестирования. Каждый тест должен требовать, чтобы этот файл имел доступ к модулю Spec
и другим помощникам.В предыдущем примере мы использовали только утверждение eq
Spec
предоставляет множество других утверждений, как показано в следующем примере:require "spec"
it do
true.should be_true
nil.should be_nil
10.should be >= 5
"foo bar baz".should contain "bar"
10.should_not eq 5
expect_raises Exception, "Err" do
raise Exception.new "Err"
end
end
Полный список см. на https://crystal-lang.org/api/Spec/Expectations.html
. Этот пример также демонстрирует, что внешний блок #describe не требуется. Однако обычно рекомендуется включить один из них, поскольку он помогает в организации тестов. Однако блок#it
По мере роста количества кода в приложении будет расти и количество тестов. Это может затруднить отладку конкретных тестовых случаев. В этом случае аргумент focus: true
#describe
или #it
. При этом будет выполнена только одна спецификация, как в следующем примере:it "does something", focus: true do
1.should eq 1
end
Только не забудьте удалить его перед совершением!
Модуль Spec
• #pending
"check cat" { cat.alive? }
. Блок метода никогда не выполняется, но может использоваться для описания того, что должен делать тест.• #pending!
#pending!
аналогичен предыдущему методу, но может использоваться для динамического пропуска тестового примера. Это может быть полезно для обеспечения выполнения зависимостей/требований системного уровня перед запуском тестового примера.