Тестирование программы — 5.5, Информатика 7 класс, Кадыркулов: разбор и ответы
Ookul.kz · разбор уроков
Қазақша

Разберём любой номер вместе!

5.5. Тестирование программы

Информатика, 7 класс. Учебник: Кадыркулов Р. А., Рыскулбекова А. Д., Нурмуханбетова Г. К. (Алматыкітап баспасы, 2023). Раздел 5: Практическое программирование. Страницы 157–161.

Чему научишься

  • Объяснять, что такое тест и чем тестирование отличается от исправления ошибок.
  • Знать три этапа тестирования: нормальные, граничные и исключительные условия.
  • Заранее готовить тестовые данные и ожидаемые ответы.
  • Проверять программу на нескольких наборах данных и находить слабые места.

Разминка

  • Что понимается под тестированием программы? Это проверка: мы запускаем программу на заранее подобранных данных и смотрим, совпал ли её ответ с тем, который мы ждали.
  • Какие бывают типы тестов? По условиям, в которых проверяем: обычные (нормальные) данные, крайние (граничные) значения и «неправильные» данные, которых программа не ждёт (исключительные).

Разбираемся

Чем тест отличается от «починки»

Допустим, ты написал программу, и она запустилась без красных сообщений об ошибке. Это ещё не значит, что она считает правильно. Здесь два разных дела.

  • Исправление ошибок (отладка): программа не запускается или падает, потому что где-то опечатка или нарушены правила записи (синтаксические ошибки). Ты ищешь причину и чинишь.
  • Тестирование: программа запускается, а мы проверяем, правильный ли ответ она даёт.

📌 Тест — это набор входных данных вместе с ответом, который программа должна выдать. Ответ мы определяем заранее, головой или на бумаге, а не списываем с экрана после запуска.

⚠️ Частая ошибка. Запустить программу, посмотреть на ответ и написать «ожидалось именно это». Так любой неверный ответ покажется правильным. Сначала посчитай в уме, потом запускай.

Три этапа проверки

Возьмём простую программу. В магазине игр при покупке от 5000 тенге даётся скидка 10 %. Программа получает сумму покупки и выводит, сколько платить.

price = int(input())          # сумма покупки, тг
if price >= 5000:
    price = price - price // 10   # скидка 10 %
print(price)

1. Нормальные условия. Обычные данные, как в жизни.

2. Граничные условия. Значения на самой границе: там, где условие меняет решение, и на краях допустимых чисел. Здесь граница — число 5000. Проверяем и 4999 (скидки ещё нет), и 5000 (скидка уже есть).

3. Исключительные условия. Данные, которые программа не должна принимать: отрицательная сумма, буквы вместо числа. Хорошая программа такие данные отклоняет, а не печатает странный ответ.

Ввод Что ждём Этап Что выдала программа
3000 3000 нормальный 3000
8000 7200 нормальный 7200
4999 4999 граничный 4999
5000 4500 граничный 4500
−100 сообщение об ошибке исключительный −100 (плохо)

Последний тест нашёл слабое место: программа «приняла» отрицательную сумму. Исправляем.

price = int(input())          # сумма покупки, тг
if price < 0:
    print("Ошибка: сумма не может быть отрицательной")
elif price >= 5000:
    print(price - price // 10)    # скидка 10 %
else:
    print(price)

Теперь ввод −100 даёт сообщение об ошибке, а остальные тесты дают те же ответы.

💡 Правило тестировщика: для каждого условия if придумай тест по обе стороны от границы и ровно на границе. Тогда ошибки вроде > вместо >= не спрячутся.

🌟 Крупные игры и приложения перед выходом проверяют целые команды тестировщиков. Они специально вводят странные данные, нажимают всё подряд и ищут, что сломается.

Вердикт: программа «условно правильная»

Если на всех продуманных тестах ответы совпали с ожидаемыми, программу можно считать условно правильной. «Условно» потому, что мы проверили не все на свете входные данные. Чем лучше подобраны тесты, тем меньше шансов, что ошибка проскочит.

👨‍👩‍👧 Родителю. Попросите ребёнка показать, как он проверял программу. Хороший вопрос: «А что будет, если ввести ноль или самое большое число?» Привычка проверять края пригодится и вне информатики.

Проверь себя

  • Чем исправление ошибок отличается от тестирования? При исправлении мы убираем синтаксические ошибки, из-за которых программа не работает. При тестировании проверяем, правильно ли работающая программа отвечает на подготовленные данные.
  • Почему ожидаемый результат нельзя брать с экрана после запуска? Тогда проверка теряет смысл: любой ответ программы покажется «ожидаемым». Правильный ответ находим заранее.
  • Назови три этапа тестирования. Проверка в нормальных, в граничных (экстремальных) и в исключительных условиях.
  • Какие данные для программы «дано число от 1 до 1000» будут граничными? 0 и 1 на нижней границе, 999 и 1000 на верхней. Число 0 заодно уже за границей допустимого.

Решаем упражнения

Практическая работа

№ 1 · «Практическая работа»

«Пересадка по маршруту». В Алматы вводят два автобусных маршрута. Остановки пронумерованы числами от 1 до 100. Первый автобус едет между остановками a и b, второй между c и d (направление может быть любым). Нужно найти, на скольких остановках можно пересесть с одного автобуса на другой. Образцы: 3 6 4 2 даёт 2, а 3 1 5 10 даёт 0.

Как думать. Каждый маршрут — это отрезок номеров остановок. Пересадка возможна на остановках, которые есть в обоих отрезках, то есть на пересечении. Сначала расставим концы по порядку (меньший, потом больший), потом найдём общий участок: он начинается с большего из левых концов и кончается меньшим из правых.

Решение. Подготовим данные для проверки заранее, до написания кода.

№ Ввод a b c d Что ждём Этап
1 8 5 6 9 3 нормальный (оба маршрута «задом наперёд»)
2 50 10 20 30 11 нормальный (один маршрут внутри другого)
3 5 9 1 4 0 нормальный (не пересекаются)
4 10 20 20 30 1 граничный (общая остановка только одна)
5 7 7 7 7 1 граничный (маршруты из одной остановки)
6 1 100 100 1 100 граничный (самые широкие маршруты)

Вариант 1: с проверкой условий if (расставляем номера по порядку).

a, b, c, d = map(int, input().split())
if a > b:
    a, b = b, a            # первый маршрут: от меньшей остановки к большей
if c > d:
    c, d = d, c            # второй маршрут: то же самое
if a > c:
    a, b, c, d = c, d, a, b   # пусть первым будет тот, кто начинается раньше
if b > d:
    b, d = d, b            # теперь b - конец общего участка
if b < c:
    print(0)               # маршруты не пересекаются
else:
    print(b - c + 1)       # остановки от c до b

Вариант 2: короче, через функции min и max.

a, b, c, d = map(int, input().split())
a, b = min(a, b), max(a, b)     # первый маршрут по возрастанию
c, d = min(c, d), max(c, d)     # второй маршрут по возрастанию
left = max(a, c)                # левый край общего участка
right = min(b, d)               # правый край общего участка
print(max(0, right - left + 1)) # отрицательной длины не бывает

Обе программы запущены на тестах из таблицы и на образцах из задания: ответы 3, 11, 0, 1, 1, 100, а образцы 3 6 4 2 и 3 1 5 10 дали 2 и 0.

Ответ: количество пересадочных остановок равно max(0, min(b, d) - max(a, c) + 1) после упорядочивания концов каждого маршрута. Ожидаемые результаты по таблице тестов: 3, 11, 0, 1, 1, 100.

Анализ

№ 2 · «Анализ», вопрос 1

Сравни два способа записи программы «Пересадка по маршруту» (с цепочкой if и с min и max). Какая структура тебе понравилась больше? Объясни почему.

Как думать. Здесь нет одного «правильного» ответа. Важно назвать причину: длина, понятность, риск ошибиться.

Пример ответа. Мне больше понравился вариант с min и max. Он короче, а идея видна сразу: найти левый и правый край общего участка. В варианте с if много перестановок, и в них легко запутаться. Зато цепочку if проще объяснить новичку, который ещё не знает функций min и max.

Ответ: по выбору ученика с причиной, например: вариант с min и max короче и понятнее по идее, вариант с if нагляднее для начинающего.

№ 3 · «Анализ», вопрос 2

Образцы тестов из таблицы 1 учебника относятся к двум этапам проверки. Разложи их по группам в зависимости от условий.

Как думать. Если числа обычные, средние, и ответ «как в жизни», то это нормальные условия. Если данные на краях диапазона (остановки 1 и 100, маршруты едва касаются или совпадают), то граничные.

Решение. Тесты 1, 2 и 6 (1 2 3 4, 2 4 3 5, 1 99 97 100) проверяют края: маршруты стоят вплотную, пересекаются на пару остановок, доходят до остановки 1 или почти до 100. Тесты 3, 4 и 5 (35 17 10 42, 30 10 45 80, 4 50 4 50) — обычные «середины» диапазона.

Ответ: граничные: тесты 1, 2, 6; обычные (нормальные): тесты 3, 4, 5.

Вопросы для размышления

№ 4 · «Вопросы для размышления», вопрос 1

Что такое тестирование программы? Из каких этапов оно состоит?

Как думать. Сначала определение, потом три этапа по порядку.

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

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

№ 5 · «Вопросы для размышления», вопрос 2

Как тестирование влияет на работоспособность программы?

Как думать. Подумай, что происходит с найденной ошибкой.

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

Ответ: тестирование выявляет ошибки, после исправления программа работает надёжнее и правильно на более широком наборе данных.

№ 6 · «Вопросы для размышления», вопрос 3

В чём значимость тестирования программы?

Как думать. Что может случиться, если программу не проверять?

Пример ответа. Без тестов ошибка обнаружится у пользователя: неверный расчёт, сбой, потеря данных. Тестирование помогает заметить это заранее и убедиться, что программа отвечает условиям задачи. Чем важнее программа (банк, медицина, навигация), тем важнее проверка.

Ответ: тестирование позволяет найти ошибки до начала использования и убедиться, что программа соответствует условиям задачи.

Задание

№ 7 · «Задание», задание 1

⭐⭐ (средняя сложность. Дана шахматная доска, клетки которой определяются координатами (номер столбца и номер строки). Для двух клеток определи, одинакового ли они цвета. Если цвета одинаковые, выведи «Да», иначе «Нет». Подготовь 5 разных тестов с опорой на этапы тестирования. Образец: 2 1 3 2 даёт «Да».

Как думать. Клетки на доске чередуются, как на шахматке. Цвет клетки зависит от чётности суммы её координат: в одной клетке сумма x + y чётная, в соседней нечётная. Значит, клетки одного цвета, если суммы у них обе чётные или обе нечётные, то есть (x1 + y1) % 2 == (x2 + y2) % 2. Проверим на образце: 2 + 1 = 3 и 3 + 2 = 5, обе суммы нечётные, значит, цвет один и тот же.

Решение.

x1, y1, x2, y2 = map(int, input().split())
if (x1 + y1) % 2 == (x2 + y2) % 2:
    print("Да")
else:
    print("Нет")

Пять тестов (доска 8 × 8):

№ Ввод x1 y1 x2 y2 Ожидаем Этап
1 2 1 3 2 Да нормальный (образец)
2 1 1 1 2 Нет нормальный (соседние клетки)
3 1 1 8 8 Да граничный (противоположные углы)
4 1 1 1 8 Нет граничный (углы на одном краю)
5 5 5 5 5 Да граничный (одна и та же клетка)

Все пять тестов запущены, ответы совпали с ожидаемыми. Для исключительных условий (координата 0, 9 или отрицательная) программа выше не готова: чтобы она сообщала об ошибке, перед сравнением нужна проверка if not (1 <= x1 <= 8 ...), как в примере со скидкой.

Ответ: (x1 + y1) % 2 == (x2 + y2) % 2 значит «Да», иначе «Нет».

Шпаргалка

Термины: тест, тестирование, ожидаемый (образцовый) результат, нормальные условия, граничные значения, исключительные условия.

Мини-тест

← 5.4. Программирование задач. Практическая работа · 5.6–5.7. Практические задания →