Суть автоматизированного тестирования в том, чтобы все тесты которые вы прописали в таблице тестов, не пришлось проверять вручную. Для этого создается специальная программа для вашей программы, которая подставляет необходимые значения и проверяет выданный уже вашей программой результат.
Однако тут есть небольшая проблема: те программы, которые мы писали до этого, строго говоря, никуда ничего не возвращали, а просто выводили информацию на экран.
Поэтому прежде чем начать писать автоматизированные тесты для программы необходимо произвести декомпозицию проекта. То есть выделить ту часть кода, которая ответственна непосредственно за расчет результатов и ту, которая будет непосредственно взаимодействовать с пользователем.
Рассмотрим пару примеров.
Пример 1
Задача: Студенты Иванов и Петров за время практики заработали определенную сумму. Кто из них заработал большую сумму? Определить средний заработок.
Возьмем код из предыдущих разделов и определим какая часть кода отвечает за взаимодействие с пользователем, а какая часть за логику:
То есть сейчас у нас своего рода “лапша” в коде, логика пересекается с взаимодействие с пользователем.
Убираем лапшу
Преобразуем код так чтобы, логика у нас была строга отделена от общения с юзером. Например, так:
Таким образом мы разбили приложение на три этапа,
в первой части мы “взаимодействуем с пользователем”: запрашиваем значения;
вторая часть включает логику, тут мы добавили новую переменную, в которую будем фиксировать сообщение, которое позже покажем юзеру, и также считаем среднее арифметическое сумм полученных студентами;
третья часть – снова общаемся с пользователем: отображаем рассчитанные результаты и ждем нажатия любой клавиши.
Производим декомпозицию
Однако, такого преобразования пока недостаточно, чтобы приступить к автотестированию кода. Следующее что мы сделаем – это произведем декомпозицию кода. У нас имеется:
Добавим класс, в который запихаем логику нашего приложения:
То, что мы сейчас сделали, называется декомпозицией. Тело программы, которое находится в вызове функции Main, у нас “похудело” и теперь отвечает в основном за взаимодействие с пользователем, а всю логику делегирует классу Logic. Собственно, этот класс
и его функции мы будем тестировать.
Добавляем тесты
Скролим вверх к классу Logic, наводим мышкой на название функции Compare, кликаем правой кнопкой мыши и выбираем Создание модульных тестов
увидим такое окошко, ничего не меняем, просто жмем Ok
ждем прока Visual Studio создаст вложенный проект под тесты:
а в панели обозревателя увидим, как появился новый подпроект
также откроется код уже непосредственно тестов, посмотрим, что у нас там присутствует
Давайте запустим наш тест, для этого нажимаем правой кнопкой мыши на название теста и выбираем “Выполнить тесты”:
подождем пока тесты скомпилируются и выполнятся, слева от кода откроется Окно обозревателя тестов, в котором будет виден
результат выполнения тестов, то есть прошли ли они успешно или неудачно:
В нашем случае выполнение завершилось неудачно, потому что в коде тестов явно написано, что должна случится неудача:
Такое нам не интересно, так что давайте добавим какой-нибудь осознанный тест.
Пишем автотесты
И так, правим код:
Уже лучше, но у нас есть еще как минимум два варианта исхода событий, когда Иванов зарабатывает
меньше чем Петров, а также, когда они зарабатывают поровну. Добавим соответствующие тесты:
Пример 2
Задача: посчитать сумму введенных пользователем чисел.
Разберем этот пример с минимум комментариев. И так ищем в исходном коде логику и общение с пользователем:
Как видно, тут все достаточно удачно разделено, поэтому можно пропустить этап “разгребания лапши” и сразу перейти к декомпозиции
Декомпозиция
Пишем тесты
По аналогии с первой примером
кликаем правой кнопкой мыши на getSum
выбираем Создание модульных тестов
появляется окно, в котором ничего не меняем и жмем Ok
удаляем тест getSumTest
добавляем свои тесты:
Об особенностях тестирования массивов (добавленно 15.10)
Если надо проверить на равенство значения двух массивов, необходимо использовать CollectionAssert, например,