Выбрать главу

def number_decomposition(number)

numl, num2 = number/2, number/2

while numl > 1 and num2 < number if prime?(num1) and prime?(num2)

return numl, num2

end

     numl -= 1 num2 += 1 end

     return nil end

if __FILE__ == $0

     p number_decomposition(142)

end

Метод number_decomposition использует рассмотренный (стр. 10) нами ранее метод prime? (проверка числа на простоту).

Исходная программа была подготовлена к процессу тестирования. Метод number_decomposition возвращает полученный результат (вместо печати, который мы будем сравнивать с набором подготовленных шаблонов). Тело условного оператора в конце программы будет выполнено только в случае, если интерпретатору на выполнение будет передан данный файл с программой, при подключении этого файла командой require условие __FILE__ == $0 будет ложно.

Для тестирования создадим подкласс базовой библиотеки тестирования. Обратите внимание на стили наименований: имя такого класса должно начинаться с префикса Test, а имена тестирующих методов – с лексемы test. Каждый тест содержит набор сравнений – специальных функций, имя которых начинается со слова assert.

Метод assert получает два аргумента (второй – необязательный): логическое выражение и текстовое сообщение. Если логическое выражение окажется ложно, то программа добавит 1 к числу неуспешных проверок и выведет сообщение о неудаче. Кроме этого, будет напечатано текстовое сообщение, переданное методу в качестве второго аргумента. Метод assert_equal получает три аргумента (третий – необязательный): ожидаемое значение, сравниваемое значение (как правило результат работы тестируемой функции) и сообщение, которое будет выведено при несовпадении первого и второго аргументов. Метод assert_nil проверяет, является ли аргумент объектом nil.

# подключение библиотеки тестирования require "test/unit"

# подключение файла с программой require "number_decomposition4test.rb"

class TestNumberDecomposition < Test::Unit::TestCase def setup

# набор начальных действий выполняемых

# перед запуском каждого тестового случая. end

# проверка работоспособности функции prime? def test_prime?

assert(false == prime?(1)) assert false == prime?(10)

assert_equal(true, prime?(2), "Ошибка при проверке числа 2") assert_equal true, prime?(7), "Ошибка при проверке числа 7" assert_equal(true, prime?(103)) end

def test_number_decomposition

assert_nil(number_decomposition(2)) assert_equal([5, 5], number_decomposition(10)) assert_equal [7, 11], number_decomposition(18) assert_equal [97, 103], number_decomposition(200) end end

Вы можете добавлять в класс вспомогательные методы и использовать их в тестовых случаях, но только методы, начинающиеся с test, будут запущены во время выполнения теста! Тесты вызываются в том порядке, в котором они представлены в программе. Если в тестирующем классе присутствуют методы с именами setup и (или) teardown, то они будут выполнены соответственно перед запуском всех тестов и после их завершения.

   Очень полезно писать тесты до начала программирования.

Посмотрим на результат работы данной программы. Его можно интерпретировать таким образом. Выполнено 2 теста (tests) и 9 сравнений (assertions). Обнаружено 0 сбоев (failures) и 0 ошибок (errors). Это означает, что программа теоретически работает и, наверное, все в порядке.

$ ruby test_number_decomposition.rb Loaded suite test_number_decomposition Started

Finished in 0.003189 seconds.

2 tests, 9 assertions, 0 failures, 0 errors $

Ради эксперимента искусственно внесем ошибку в метод prime?, сделав так, чтобы он считал единицу простым числом.

Запуск теста моментально обнаруживает ошибку, показав место, где произошел сбой – седьмую строку с выражением assert false == prime?(1) (отметим, что количество сбоев стало равным одному). Изучив тестовый случай, можно понять, где произошла ошибка и в чем причина. Теперь выполнять тесты стало очень легко.

$ ruby test_number_decomposition.rb Loaded suite test_number_decomposition Started.F

Finished in 0.061807 seconds.

1) Failure:

test_prime? (TestNumDecomposition) [test_number_decomposition.rb:7]: <false> is not true.

2 tests, 5 assertions, 1 failures, 0 errors $

Когда требуется ввести в программу новую функцию, начните с создания теста. Это не так странно, как может показаться. Когда вы пишите тест, то спрашиваете себя, что нужно сделать для добавления этой функции и как она должна работать.

3.2 Обработка исключительных ситуаций.

В большинстве современных языков программирования предусмотрена возможность работы с исключительными (особыми) ситуациями. В языке Ruby программисты могут работать как со встроенными ситуациями, так и с ситуациями, создаваемыми по указанию программиста при наличии того или иного события. Типичные встроенные ситуации – это «деление на ноль» (ZeroDivisionError) или «достижение конца файла» (EOFError).