Выбери любимый жанр

Выбрать книгу по жанру

Фантастика и фэнтези

Детективы и триллеры

Проза

Любовные романы

Приключения

Детские

Поэзия и драматургия

Старинная литература

Научно-образовательная

Компьютеры и интернет

Справочная литература

Документальная литература

Религия и духовность

Юмор

Дом и семья

Деловая литература

Жанр не определен

Техника

Прочее

Драматургия

Фольклор

Военное дело

Последние комментарии
оксана2018-11-27
Вообще, я больше люблю новинки литератур
К книге
Professor2018-11-27
Очень понравилась книга. Рекомендую!
К книге
Vera.Li2016-02-21
Миленько и простенько, без всяких интриг
К книге
ст.ст.2018-05-15
 И что это было?
К книге
Наталья222018-11-27
Сюжет захватывающий. Все-таки читать кни
К книге

Программист-прагматик. Путь от подмастерья к мастеру - Хант Эндрю - Страница 55


55
Изменить размер шрифта:

34

Программа, которую легко тестировать

Термин "программная интегральная схема" является метафорой, брошенной в ходе дискуссии о многократном использовании и компонентно-ориентированной разработке [39]. Идея заключается в том, что программные компоненты должны объединяться так же, как это происходит с чипами интегральной схемы. Этот подход срабатывает только в том случае, если известно, что используемые компоненты надежны.

Чипы предназначены душ тестирования не только на предприятии-изготовителе, не только при сборке, но и в сфере их применения. Более сложные чипы и системы могут снабжаться полномасштабными средствами самотестирования, которые осуществляют внутреннюю диагностику на базовом уровне, или тестовым стендом с комплектом измерительных кабелей инициирующим подачу тестовых входных сигналов и снимающим ответную информацию с чипа.

То же самое можно осуществить и с программным обеспечением. Подобно нашим коллегам, работающим с «железом», нам приходится с самого начала встраивать средства тестирования в программы и тщательно тестировать каждый фрагмент, перед тем как предпринять попытку их объединения.

Модульное тестирование

Тестирование аппаратных средств на уровне чипа отдаленно напоминает модульное тестирование программного обеспечения – тестируется каждый модуль по отдельности для проверки его поведения. Мы можем лучше представить себе, какова будет реакция модуля на внешний мир, если проведем его тщательное тестирование в контролируемых (и даже искусственных) условиях.

Модульный программный тест – это программа, испытывающая работу модуля. Обычно модульный тест задает некую искусственную среду, затем осуществляется вызов подпрограмм из проверяемого модуля. Потом происходит проверка полученных результатов, они сравниваются с известными величинами или с результатами предыдущих прогонов той же самой программы тестирования (регрессионное тестирование).

Когда мы объединим наши "программные интегральные схемы" в единую систему, мы будем уверены, что ее отдельные части работают предсказуемо, а затем можем применить те же средства модульного тестирования при проверке системы в целом. О подобном крупномасштабном тестировании речь идет в разделе "Безжалостное тестирование".

Но прежде чем выйти на этот уровень, необходимо решить, а что же мы будем тестировать на уровне блоков. Обычно программисты задают несколько случайных массивов данных и считают, что они провели тестирование. Но это можно сделать намного лучше, если использовать идеи, связанные с "программированием по контракту".

Тестирование в рамках контракта

Мы рассматриваем модульное тестирование, как тестирование исходя из контракта (см. "Проектирование по контракту"). Нам бы хотелось написать процедуры тестирования, гарантирующие, что данный модуль соблюдает соответствующий контракт. При этом выясняются два момента: отвечает ли программа условиям контракта, и означает ли контракт на самом деле то, что мы о нем думаем. Мы хотим проверить, обладает ли модуль функциональными характеристиками, которые в нем заложены, используя разнообразные тестовые процедуры и граничные условия.

Что это означает на практике? Рассмотрим подпрограмму извлечения квадратного корня, с которой мы впервые встретились в разделе "ППК и аварийное завершение работы программы". Ее контракт довольно прост:

require:

   argument >=0

ensure:

  abs((result*result)–argument) < epsilon

Он указывает на моменты, нуждающиеся в проверке:

• Передать отрицательный аргумент и удостовериться в том, что он отклонен

• Передать аргумент, равный нулю, и удостовериться в том, что он принят (это граничное значение)

• Передать значение в интервале от нуля до максимально выражаемого параметра и проверить, что разность между квадратом результата и исходным аргументом меньше некоторой величины "epsilon"

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

public void testValue(double num, double expected) {

double result = 0.0;

try {    // We may throw a

result = mySqrt(num); // precondition exception

}

catch (Throwable e) {

if (num