Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп
Книгу Программирование. Принципы и практика использования C++ Исправленное издание - Бьёрн Страуструп читаем онлайн бесплатно полную версию! Чтобы начать читать не надо регистрации. Напомним, что читать онлайн вы можете не только на компьютере, но и на андроид (Android), iPhone и iPad. Приятного чтения!
Шрифт:
Интервал:
Закладка:
Что мы можем тестировать, а что не можем? Для того чтобы тестировать класс Shape, мы должны попытаться протестировать его как отдельно, так и в сочетании с производными классами. Однако, для того чтобы проверить, что класс Shape работает правильно с конкретным производным классом, мы должны протестировать этот производный класс.
Ранее мы уже отметили, что объект класса Shape имеет состояние (значение), определенное четырьмя данными-членами.
vector<Point> points;
Color lcolor; // цвет линий и символов
Line_style ls;
Color fcolor; // цвет заполнения
Все, что мы можем сделать с объектом класса Shape, — внести в него изменения и посмотреть, что произойдет. К счастью, изменить данные-члены можно только с помощью интерфейса, определенного функциями-членами.
Простейшим объектом класса Shape является объект класса Line, поэтому начнем с создания одного такого объекта и внесем все возможные изменения (используя самый наивный стиль тестирования).
Line ln(Point(10,10), Point(100, 100));
ln.draw(); // смотрим, что произошло
// проверка точек:
if (ln.number_of_points() != 2)
cerr << "Неправильное количество точек ";
if (ln.point(0)!=Point(10,10)) cerr << "Неправильная точка 1";
if (ln.point(1)!=Point(100,100)) cerr << "Неправильная точка 2";
for (int i=0; i<10; ++i) { // смотрим на перемещения объекта
ln.move(i+5,i+5);
ln.draw();
}
for (int i=0; i<10; ++i) { // проверяем, возвращается ли объект
// в исходное положение
ln.move(i–5,i–5);
ln.draw();
}
if (point(0)!=Point(10,10))
cerr << "Неправильная точка 1 после перемещения";
if (point(1)!=Point(100,100))
cerr << "Неправильная точка 2 после перемещения";
for (int i = 0; i<100; ++i) { // смотрим, правильно ли изменяются
// цвета
ln.set_color(Color(i*100));
if (ln.color() != Color(i*100))
cerr << "Неправильное значение set_color";
ln.draw();
}
for (int i = 0; i<100; ++i) { // смотрим, правильно ли изменяется
// стиль
ln.set_style(Line_style(i*5));
if (ln.style() != Line_style(i*5))
cerr << "Неправильное значение set_style";
ln.draw();
}
В принципе эта программа тестирует создание, перемещение, цвет и стиль. На практике мы должны учесть много больше факторов (с учетом отклонений от сценария), как мы это делали при тестировании функции binary_search. И снова мы, скорее всего, убедимся в том, что считывать описание тестов из файла намного удобнее, а заодно придумаем более информативные сообщения об ошибках.
Кроме того, мы выясним, что совершенно не обязательно усаживать перед экраном компьютера человека, который отслеживал бы изменения состояния объектов класса Shape. Итак, у нас появляются две альтернативы:
• замедлить работу программы, чтобы за ней мог следить наблюдатель;
• найти такое представление класса Shape, чтобы мы могли читать и анализировать его с помощью программы.
Отметим, что мы еще не тестировали функцию add(Point). Для того чтобы проверить ее, мы, вероятно, должны были бы использовать класс Open_polyline.
26.3.6. Поиск предположений, которые не выполняются
Спецификация класса 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
Прочитали книгу? Предлагаем вам поделится своим отзывом от прочитанного(прослушанного)! Ваш отзыв будет полезен читателям, которые еще только собираются познакомиться с произведением.
Уважаемые читатели, слушатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.
- 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
- 2. Просьба отказаться от оскорблений, угроз и запугиваний.
- 3. Просьба отказаться от нецензурной лексики.
- 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.
Надеемся на Ваше понимание и благоразумие. С уважением, администратор knigkindom.ru.
Оставить комментарий
-
Christine26 июнь 01:23 Сначала было тежеловта читать, но потом всё изменилось, я с удовольствием прочитала, спасибо за книгу. Я прочитала весь цикл... Опасное влечение - Полина Лоранс
-
Тамаринда21 июнь 12:33 Редко что-то цепляет, но тут было всё живое, жизненное, чувственное, сильное, читайте, не пожалеете о своём времени...... Хрупкая связь - Ольга Джокер
-
Гость Марина20 июнь 06:08 Книга очень понравилась, хотя и длинная. Героиня сильная личность. Да и герой не подкачал. ... Странная - Татьяна Александровна Шумкова