Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

26.3.3.4. Ветвление

Очевидно, что, делая выбор, мы можем принять неправильное решение. Из-за этого инструкции
if
и
switch
являются одними из основных целей для тестировщиков. Существуют две проблемы, которые необходимо исследовать.

• Все ли возможные варианты предусмотрены?

• Правильные ли действия связаны с правильными вариантами выбора?

Рассмотрим следующую бессмысленную функцию:

void do_branch1(int x, int y) // плохая функция

// неправильное использование инструкции if

{

if (x<0) {

if (y<0)

cout << "Большое отрицательное число \n";

else

cout << "Отрицательное число \n";

}

else if (x>0) {

if (y<0)

cout << "Большое положительное число \n";

else

cout << "Положительное число \n";

}

}

Наиболее очевидная ошибка в этом фрагменте заключается в том, что мы забыли о варианте, в котором переменная

x
равна нулю. Сравнивая числа (положительные или отрицательные) с нулем, программисты часто забывают о нем или приписывают неправильной ветви (например, относят его к отрицательным числам). Кроме того, существует более тонкая (хотя и распространенная) ошибка, скрытая в этом фрагменте: действия при условиях (
x>0 && y<0
) и (
x>0 && y>=0
) каким-то образом поменялись местами. Это часто случается, когда программисты пользуются командами “копировать и вставить”.

Чем более сложными являются варианты использования инструкций

if
, тем вероятнее становятся ошибки. Тестировщики анализируют такие коды и стараются не пропустить ни одной ветви. Для функции
do_branch1
набор тестов очевиден.

do_branch1(–1,–1);

do_branch1(–1, 1);

do_branch1(1,–1);

do_branch1(1,1);

do_branch1(–1,0);

do_branch1(0,–1);

do_branch1(1,0);

do_branch1(0,1);

do_branch1(0,0);

По существу, это наивный подход “перебора всех альтернатив”, которой мы применили, заметив, что функция

do_branch1
сравнивает значения с нулем с помощью операторов
<
и
>
. Для того чтобы выявить неправильные действия при положительных значениях переменной
x
, мы должны объединить вызовы функции с желаемыми результатами.

Обработка инструкций

switch
аналогична обработке инструкций
if
.

void do_branch1(int x, int y) // плохая функция

// неправильное использование инструкции switch

{

if (y<0 && y<=3)

switch (x) {

case 1:

cout << "Один\n";

break;

case 2:

cout << "Два\n";

case 3:

cout << "Три\n";

}

}

Здесь сделаны четыре классические ошибки.

• Мы проверяем значения неправильной переменной (

y
, а не
x
).

• Мы забыли об инструкции

break
, что приводит к неправильному действию при
x==2
.

• Мы забыли о разделе

default
(считая, что он предусмотрен инструкцией
if
).

• Мы написали

y<0
, хотя имели в виду
0<y
.

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

  • Читать дальше
  • 1
  • ...
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: