Найти в Дзене

Unit тестирование ч.1

Весь код тестируется. Во время разработки первое, что мы делаем, - это запускаем “приемочный тест” нашего собственного программиста. Мы кодим, компилируем и запускаем. И когда программа работает, мы тестируем.
Можно просто нажать кнопку, чтобы увидеть, вызовет ли она ожидаемое меню. Но, тем
не менее, каждый день мы кодим, компилируем, запускаем...и тестируем.
Когда мы тестируем, мы часто обнаруживаем проблемы—особенно при первом запуске. Поэтому мы кодим, компилируем, запускаем и снова тестируем.
Большинство из нас быстро разработают шаблон для наших неофициальных тестов: мы добавляем запись, просматриваем запись, редактируем запись и удаляем запись. Запуск небольшого набора тестов подобное вручную сделать достаточно легко, поэтому мы это делаем. Снова и снова.
Некоторым программистам нравится проводить этот тип повторяющегося тестирования. Это может быть приятный перерыв от глубоких размышлений и жесткого кодирования. И когда наши маленькие тесты по клику, наконец, увенчаются успехом, возникает настоящее чувство выполненного долга: Я нашел его!
Другим программистам не нравится этот тип повторяющейся работы. Вместо того, чтобы запускать тест вручную, они предпочитают создавать небольшую программу, которая запускает тест автоматически. Тестирование кода на воспроизведение — это одно, а запуск автоматических тестов-совсем другое.
Некоторые разработчики считают, что автоматизированные тесты являются неотъемлемой частью процесса разработки: нельзя доказать, что компонент работает, пока он не пройдет комплексную серию тестов. На самом деле, разработчики считали, что этот тип “модульного тестирования” был таким важным, что он заслуживает своей собственной структуры. В 1997 году Эрих Гамма и Кент Бек создал простую, но эффективную платформу модульного тестирования для Java под названием JUnit. (в wiki нашел)
Эта работа последовала за дизайном более ранней структуры, созданной Кентом Беком для Smalltalk, называемый SUnit.
Джунит (junit.org) - программное обеспечение с открытым исходным кодом, выпущенное под общей публичной лицензией IBM версии 1.0 и размещенное на SourceForge. Общая публичная лицензия удобна для бизнеса: люди могут распространять JUnit с коммерческими продуктами без большой волокиты или ограничений.
JUnit быстро стал де-факто стандартной платформой для разработки модульных тестов на Java. Фактически, базовая модель тестирования, известная как xUnit, находится на пути к тому, чтобы стать стандартной платформой для любого языка. Существуют фреймворки xUnit для ASP, C++, C#, Eiffel, Delphi, Perl, PHP, Python, REBOL, Smalltalk и Visual Basic—и это лишь некоторые из них!
Конечно, команда JUnit не изобретала тестирование программного обеспечения или даже модульный тест.
Первоначально термин модульный тест описывал тест, который изучал поведение одной «единицы» работы.
Со временем использование термина модульный тест расширилось. Например, IEEE определил модульное тестирование как “Тестирование отдельных аппаратных или программных блоков или групп
связанных блоков”. (тоже wiki)
Фреймворк обеспечивает многократно используемую общую структуру, которая может быть разделена между приложениями. Разработчики включают фреймворк в их собственное приложение и расширить его для удовлетворения их конкретных потребностей.
Фреймворки отличаются от наборов инструментов тем, что обеспечивают согласованную структуру, а не простой набор классов утилит.
Вот общее описание типичного модульного теста с точки зрения авторов JUnit: “Убедитесь, что метод принимает ожидаемый диапазон входных данных и что метод возвращает ожидаемое значение для каждого ввода теста.”
Это описание просит нас проверить поведение метода через его интерфейс.
Если мы дадим ему значение x, вернет ли он значение y? Если вместо этого мы дадим ему значение z, будет ли он выдавать правильное исключение?
Модульные тесты часто фокусируются на проверке того, соответствует ли метод условиям своего API контракт. Подобно письменному контракту людей, которые соглашаются обмениваться определенными товарами или услугами на определенных условиях, контракт API рассматривается как формальное соглашение, заключенное интерфейсом метода. Метод требует, чтобы его вызывающие предоставляли определенные объекты или значения, и в обмен будет возвращать определенные объекты или значения. Если контракт не может быть выполнен, то метод создает исключение, означающее, что контракт не может быть поддержан. Если метод работает не так, как ожидалось, мы говорим, что метод нарушил свой контракт.
Допустим, вы только что написали класс калькулятора.
В Java-приложении “отдельная единица работы” часто (но не всегда) один метод. Напротив, интеграционные тесты и приемочные тесты изучают, как взаимодействуют различные компоненты. Единица работы — это задача, которая напрямую не зависит от выполнения какой-либо другой задачи.
public class Calculator {
public double add (double number1, double number2) {
return number1 + number2;
}
}
Цель метода add(double, double) калькулятора состоит в том, чтобы взять два числа и вернуть сумму в виде числа.
Принцип модульного тестирования гласит: “Любая функция программы без автоматизированного тестирования просто не существует”.
Метод add представляет собой основную функцию калькулятора. У вас есть какой-то код, который якобы реализует эту функцию. Чего не хватает, так это автоматизированного теста, который доказывает, что ваша реализация работает.
Тем не менее, тестирование чего-либо на данный момент кажется проблематичным. У вас даже нет пользовательского
интерфейса, с помощью которого можно ввести пару чисел. Вы можете написать небольшую программу командной строки, которая подождет, пока вы введете два числа, а затем отобразит
результат. Конечно, тогда вы также будете проверять свою собственную способность вводить число и добавлять результат самостоятельно. Это гораздо больше, чем вы хотите сделать. Вы просто хотите знать, действительно ли эта “единица работы” добавит два числа и вернет правильную сумму.
public class TestCalculator{
public static void main(String[] args) {
Calculator calculator = new Calculator();
double result = calculator.add(10,50);
if (result != 60) {
System.out.println("Bad result: " + result);
}
}
}
Первый тестовый калькулятор действительно прост! Он создает экземпляр калькулятора,
передает ему два числа и проверяет результат. Если результат не соответствует вашим ожиданиям, вы печатаете сообщение на стандартном выводе.
Если вы скомпилируете и запустите эту программу сейчас, тест спокойно пройдет, и все будет
казаться хорошо.
Между тем, вы также можете запустить тесты для других методов калькулятора, которые вы
еще не написали, таких как вычитание или умножение. Переход к более модульной конструкции
это облегчило бы улавливание и обработку исключений, а также облегчило бы расширение
тестовой программы позже.