Статьи

Методы тестирования — Часть 1 — Не писать тесты

В этом нет особых сомнений, способ тестирования вашего кода является спорным вопросом. Различные методы тестирования пользуются популярностью у разных разработчиков по разным причинам, включая корпоративную культуру, опыт и общие психологические перспективы. Например, вы можете предпочесть написание классических модульных тестов, которые проверяют поведение объекта изолированно, проверяя возвращаемые значения; вы можете отдать предпочтение классическим заглушкам или поддельным предметам; или вы можете использовать фиктивные объекты для имитации ролей или даже использовать фиктивные объекты в качестве заглушек. Этот и мои следующие несколько блогов являются частью очень, очень распространенного шаблона проектирования и исследуют различные подходы, которые вы могли бы использовать при его тестировании.

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

В этом примере приведенный выше шаблон будет использоваться для извлечения и проверки адреса из базы данных. Пример кода, доступный в моем репозитории GitHub 1 , использует простое веб-
приложение Spring MVC в качестве отправной точки и использует небольшую базу данных MySQL для хранения адресов ни по какой другой причине, кроме того, что у меня уже есть локально работающий сервер на моем ноутбуке.

Что касается тестирования, блоги будут сосредоточены на тестировании компонента ServiceService AddressService:

@Component
public class AddressService {

  private static final Logger logger = LoggerFactory.getLogger(AddressService.class);

  private AddressDao addressDao;

  /**
   * Given an id, retrieve an address. Apply phony business rules.
   *
   * @param id
   *            The id of the address object.
   */
  public Address findAddress(int id) {

    logger.info("In Address Service with id: " + id);
    Address address = addressDao.findAddress(id);

    businessMethod(address);

    logger.info("Leaving Address Service with id: " + id);
    return address;
  }

  private void businessMethod(Address address) {

    logger.info("in business method");
    // Do some jiggery-pokery here....
  }

  @Autowired
  void setAddressDao(AddressDao addressDao) {
    this.addressDao = addressDao;
  }

}

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

public class Address {

  private final int id;

  private final String street;

  private final String town;

  private final String country;

  private final String postCode;

  public Address(int id, String street, String town, String postCode, String country) {
    this.id = id;
    this.street = street;
    this.town = town;
    this.postCode = postCode;
    this.country = country;
  }

  public int getId() {
    return id;
  }

  public String getStreet() {

    return street;
  }

  public String getTown() {

    return town;
  }

  public String getCountry() {

    return country;
  }

  public String getPostCode() {

    return postCode;
  }
}

Как я уже говорил выше, я расскажу о различных стратегиях тестирования этого кода, некоторые из которых я гарантирую, вы будете ненавидеть. Первый, до сих пор широко используемый многими разработчиками и организациями …

Не пишите никаких тестов

Невероятно, но некоторые люди и организации все еще делают это. Они пишут свой код, размещают его на веб-сервере и открывают страницу. Если страница открывается, они отправляют код, если нет, то исправляют код, компилируют его, повторно развертывают его, перезагружают веб-браузер и проводят повторную проверку.


Самый крайний пример, который я когда-либо видел в этой технике: изменение кода, развертывание на сервере, запуск кода, обнаружение ошибки и повторение цикла, было пару лет назад на престижном правительственном проекте. Субподрядчик, я полагаю, чтобы сэкономить деньги, импортировал кучу дешевых и очень неопытных программистов из «офшора» и не имел достаточно опытных программистов, чтобы наставлять их. Рассматриваемый модуль представлял собой простой компонент на основе Spring, управляемый сообщениями, который брал сообщения из одной очереди, применял небольшую бизнес-логику и затем помещал ее в другую очередь: simples. Первоначальный автор начал с написания нескольких тестов, но затем передал код другим неопытным членам команды. Когда код изменился и тест не прошел, они просто отключили все тесты.Тестирование состояло из развертывания MDB в контейнере EJB (Weblogic), отправки сообщения в передней части системы и наблюдения за тем, что получилось на другом конце, и отладки журналов по пути. Вы можете сказать, что такое сквозное тестирование не так уж и плохо, НО, чтобы развернуть MDB и запустить тест, потребовалось чуть больше часа: за рабочий день это 8 изменений кода. Не совсем быстрое развитие!

Моя работа? Чтобы исправить процесс и код. Решение? Написание тестов, запуск тестов и рефакторинг кода. Модуль прошел путь от нулевых тестов до примерно 40 модульных тестов и нескольких интеграционных тестов, и он был улучшен и наконец поставлен. Сделано.

У большинства людей будет свое мнение об этой технике, и мое мнение таково: она создает ненадежный код; написание и отправку кода с использованием этой техники занимает больше времени, поскольку вы тратите массу времени на ожидание запуска серверов, развертывания WAR / EJB и т. д., и, как правило, его используют более неопытные программисты или те, кто не пострадал от использования этого. техника — и вы страдаете. Я могу сказать, что я работал над проектами, где я пишу тесты, а другие разработчики нет. Команда тестирования обнаружила очень мало ошибок в моем коде, в то время как другие разработчики исправляют множество ошибок и стараются изо всех сил пытаться уложиться в сроки. Я блестящий программист, или написание тестов приносит дивиденды? Из опыта, если вы используете эту технику,у вас будет множество дополнительных ошибок, которые нужно исправить, потому что вы не сможете легко и многократно протестировать множество сценариев, сопровождающих историю, которую вы разрабатываете. Это потому, что это просто занимает слишком много времени, и вы должны помнить каждый сценарий, а затем запускать их вручную.


Я действительно задаюсь вопросом, является ли метод
написания тестов похмелья с 1960-х годов, когда вычислительное время было дорогим, и вам приходилось писать программы вручную на перфокартах или бумажной ленте, а затем проверять визуально, используя «таблицу истинности». Когда вы были довольны тем, что ваш код работал, вы отправили его в машинное отделение и запустили свой код
2 . Тот факт, что машинное время было дорогим, означало, что об автоматическом тестировании не могло быть и речи. Хотя компьютеры становились все быстрее, эта устаревшая парадигма продолжала развиваться, превращаясь в такую, в которой вы пропустили тщательную умственную проверку и просто запустили код, а если он сломался, вы исправили его. Эта вырожденная парадигма все еще преподавалась (есть?) В школах, колледжах и книгах, и до последних нескольких лет она не вызывала сомнений.

Поэтому может быть довольно сложно убедить людей изменить свои привычки?

Еще одна серьезная проблема с этой техникой заключается в том, что проект может перейти в состояние паралича. Как я уже говорил выше, с этой техникой количество ошибок будет высоким, и это создаст плохое впечатление для руководителей проектов, которые считают, что код воняет и поддерживает идею, что вы не должны менять код, если это абсолютно не необходимо, поскольку вы можете что-то сломать , Менеджеры начинают сомневаться в том, чтобы разрешать изменения кода, часто не доверяя разработчикам и не управляя ими. Действительно, сами разработчики очень неохотно добавляют изменения в код, так как нарушение чего-либо заставит их выглядеть плохо. Изменения, которые они вносят, настолько малы, насколько это возможно, без какого-либо рефакторинга. Со временем это добавляет беспорядок, и код вырождается еще больше, становясь большим шариком грязи.

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

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


1 См.: Git: //github.com/roghughe/captaindebug.git

2 Я недостаточно взрослый
, чтобы помнить о вычислениях в 60-х годах.

 

С http://www.captaindebug.com/2011/11/testing-techniques-part-1-not-writing.html