Статьи

Волшебное испытание

Написание тестов принадлежит повседневной жизни разработчика, но никому это не нравится. Тестирование часто повторяет и раздражает, и оно занимает слишком много вашего драгоценного времени. Таким образом, идеальная среда тестирования должна сделать написание и поддержание тестов максимально эффективными.

Введите MagicTest ( http://www.magicwerk.org/magictest ), новый тестовый фреймворк для Java. Это показывает визуальный подход, который делает тестирование легким. Чтобы продемонстрировать преимущества MagicTest, я приглашаю вас принять участие в тестировании.

Задание

Мы должны протестировать класс Tags со следующими функциями (см. Листинг 1 для реализации):

  • поддерживает список тегов

  • тег состоит из имени тега (не ноль) и количества (положительное целое число)

  • список всегда упорядочен по убыванию количества тегов

Сколько строк кода вам понадобится для проверки всех этих требований? Будет ли он вдвое меньше, чем примерно столько же, или может быть даже больше?

Волшебный тест

Что если я скажу вам, что MagicTest просто нужно 10 заявлений, чтобы получить 100% тестовое покрытие? Они здесь:

      Tags tags = new Tags();
      tags.add("x", 0);
      tags.add("x", -1);
      tags.add("a", 1);
      tags.add("b", 2);
      tags.add("a", 2);
      tags.add("a", 0);
      tags.add("a", -3);
      tags.add("b", -3);
      tags.add(null, 1);

Вы можете сразу заметить существенные различия по сравнению с традиционными модульными тестами, написанными для TestNG или JUnit:

  • Не требуется утверждений для проверки ожидаемых результатов

  • Для отрицательных тестов не нужно ловить исключений

Они не нужны, потому что MagicTest автоматически отслеживает вызовы тестируемого метода со всей соответствующей информацией, включая параметры и результат (в случае успеха) или исключение (при ошибке). MagicTest собирает этот результат теста и сравнивает его с сохраненным эталонным результатом: если они равны, тест считается успешным.

Если мы запустим наш тест с MagicTest, мы получим следующий понятный отчет о тестировании:

Как это работает?

Тест в деталях

Весь тестовый класс выглядит так:

public class TagsTest {
   @Trace(traceMethod="/.+/",
      parameters = Trace.THIS|Trace.ALL_PARAMS, 
      result = Trace.THIS|Trace.RESULT,
      title = "Test all methods of Tags")
   public void testTags() {
      setDescription("Create empty tags list");
      Tags tags = new Tags();
      setDescription("Tag with count 0 is ignored on add");
      tags.add("x", 0);
      setDescription("Adding a tag with negative count is rejected ");
      tags.add("x", -1);
      setDescription("Maintain tags order");
      tags.add("a", 1);
      tags.add("b", 2);
      tags.add("a", 2);
      setDescription("Adding 0 to an existing tag is ignored");
      tags.add("a", 0);
      setDescription("Tag 'a' with new count 0 is removed");
      tags.add("a", -3);
      setDescription("Changing a tag count to a negative value is rejected");
      tags.add("b", -3);
      setDescription("Tag name must not be null");
      tags.add(null, 1);
   }
}

Если мы шаг за шагом пройдемся по коду, то увидим следующее:

  • Соглашение об именовании: так как тестируемый класс называется Tags, мы называем наш тестовый класс TagsTest, чтобы MagicTest обнаруживал связь

  • @Trace аннотация: мы используем traceMethod с регулярным выражением «. *», Чтобы указать, что мы хотим отслеживать вызовы всех методов тестируемого класса

  • Report.setDescription (): можно предоставить текстовое описание шагов теста

Может показаться незнакомым проверить все требования в одном методе. Однако тот факт, что исключение теста продолжается даже в случае исключения, делает это возможным и даже разумным, поскольку требуется гораздо меньше кода, поскольку вы можете извлечь выгоду из уже созданного состояния. Таким образом, вы получаете 100% тестовое покрытие с этими несколькими строками кода.

Я думаю, что пуристический подход к тестированию только одной вещи в тесте общепринят, потому что он подкреплен очень практической причиной: если вы пишете сложные методы тестирования, а одно из ваших утверждений не выполняется в середине выполнения, тестирование просто заканчивается без какой-либо информации о предстоящих этапах испытаний. Таким образом, вы должны исправить проблему и запустить тест снова — возможно, просто чтобы увидеть следующую ошибку … Очевидно, что это не проблема с MagicTest.

Пусть вызов начнется

Чтобы запустить тест самостоятельно, вам нужно скачать плагин MagicTest Eclipse . Скопируйте его в папку dropins Eclipse и перезапустите Eclipse. Затем загрузите прикрепленный проект Eclipse и импортируйте его в рабочее пространство. Запустите тестовый класс TagsTest, выполнив Run As / MagicTest.

После первого запуска появится отчет о тестировании, и все этапы теста будут красного цвета. Это MagicTest способ сообщить вам, что шаг не удалось. В нашем случае шаги просто не выполняются, потому что MagicTest просто ничего не знает об ожидаемом результате. Поэтому мы тщательно проверяем вывод и подтверждаем его правильность, нажимая на кнопку «Сохранить». Теперь все шаги зеленые — и тест пройден успешно.

Теперь вы видели, насколько эффективно этот тест можно реализовать с помощью MagicTest — он даже выглядел забавно. Ваш тестовый инструмент принимает вызов? Сколько минут и строк нужно, чтобы написать тест? Я с нетерпением жду вашего вклада!