Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:
Спецификация класса
binary_search
ясно указывает на то, что последовательность, в которой выполняется поиск, должна быть упорядоченной. Это не позволяет нам создавать многие изощренные модульные тесты. Однако очевидно, что существует возможность написать неправильный код, для которого мы не сможем изобрести тест, идентифицирующий ошибки (за исключением системных тестов). Можем ли мы использовать свое знание системных модулей (функций, классов и т.п.) для того, чтобы изобрести более хорошие тесты?
Рассмотрим функцию
binary_search
еще раз: мы не можем проверить, что входная последовательность [first:last]
действительно является последовательностью и что она была упорядочена (см. раздел 26.3.2.2). Однако можем написать функцию, которая выполняет эту проверку.
template<class Iter, class T>
bool b2(Iter first, Iter last, const T& value)
{
// проверяем, является ли диапазон [first:last)
// последовательностью:
if (last<first) throw Bad_sequence;
// проверяем, является ли последовательность упорядоченной :
for (Iter p = first+1; p<last; ++p)
if (*p<*(p–1)) throw Not_ordered;
// все хорошо, вызываем функцию binary_search:
return binary_search(first,last,value);
}
Перечислим причины, по которым функция
binary_search
не содержала таких проверок. • Условие
last<first
нельзя проверить для однонаправленного итератора; например, итератор контейнера std::list
не имеет оператора <
(раздел Б.3.2). В общем, на самом деле хорошего способа проверки того, что пара итераторов определяет последовательность, не существует (начинать перемещение с итератора first
, надеясь достигнуть итератора last
, — не самая хорошая идея). • Просмотр последовательности для проверки того, что ее значения упорядочены, является более затратным, чем выполнение самой функции
binary_search
(действительная цель выполнения функции binary_search
заключается не в слепом блуждании по последовательности в поисках значения, как это делает функция std::find
). Что же мы могли
binary_search
функцией b2
(впрочем, только для вызовов функции binary_search
с помощью итераторов произвольного доступа). В качестве альтернативы мы могли бы взять у разработчика функции binary_search
ее код, чтобы вставить в нее свой фрагмент.
template<class Iter, class T> // предупреждение:
// содержит псевдокод
bool binary_search (Iter first, Iter last, const T& value)
{
if ( тест включен ) {
if (Iter является итератором произвольного доступа) {
// проверяем, является ли [first:last)
// последовательностью :
if (last<first) throw Bad_sequence;
}
// проверяем является ли последовательность
// упорядоченной:
if (first!=last) {
Iter prev = first;
for (Iter p = ++first; p!=last; ++p, ++ prev)
if (*p<*prev) throw Not_ordered;
}
}
// теперь выполняем функцию binary_search
}
Поскольку смысл условия тест включен зависит от способа организации тестирования (для конкретной системы в конкретной организации), можем оставить его в виде псевдокода: при тестировании своего собственного кода можете просто использовать переменную
test_enabled
. Мы также оставили условие Iter является итератором произвольного доступа в виде псевдокода, поскольку не хотели объяснять свойства итератора. Если вам действительно необходим такой тест, посмотрите тему свойства итераторов (iterator traits) в более подробном учебнике по языку С++. 26.4. Проектирование с учетом тестирования
Приступая к написанию программы, мы знаем, что в итоге она должна быть полной и правильной. Мы также знаем, что для этого ее необходимо тестировать. Следовательно, разрабатывая программу, мы должны учитывать возможности ее тестирования с первого дня. Многие хорошие программисты руководствуются девизом “Тестируй заблаговременно и часто” и не пишут программу, если не представляют себе, как ее тестировать. Размышление о тестировании на ранних этапах разработки программы позволяет избежать ошибок (и помогает найти их позднее). Мы разделяем эту точку зрения. Некоторые программисты даже пишут тесты для модулей еще до реализации самих модулей.
Поделиться:
Популярные книги
Держать удар
11. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Изгой. Пенталогия
Изгой
Фантастика:
фэнтези
9.01
рейтинг книги
Имперец. Земли Итреи
11. Путь
Фантастика:
героическая фантастика
боевая фантастика
5.25
рейтинг книги
Генерал Империи
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Хозяйка лавандовой долины
2. Хозяйка своей судьбы
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Аристократ из прошлого тысячелетия
3. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Войны Наследников
9. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXIV
24. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сын Петра. Том 1. Бесенок
1. Сын Петра
Фантастика:
попаданцы
альтернативная история
6.80
рейтинг книги
На изломе чувств
Любовные романы:
современные любовные романы
6.83
рейтинг книги
Газлайтер. Том 16
16. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
На границе империй. Том 9. Часть 5
18. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Без шансов
2. Пробуждение Системы
Фантастика:
боевая фантастика
рпг
постапокалипсис
5.00
рейтинг книги
Последний попаданец 2
2. Последний попаданец
Фантастика:
юмористическая фантастика
попаданцы
рпг
7.50