Статьи

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

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

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

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

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

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@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) и делает вид, что выполняет некоторую бизнес-обработку перед возвратом объекта адреса вызывающей стороне.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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-х годов, когда вычислительное время было дорогим, и вам приходилось писать программы вручную на перфокартах или бумажной ленте, а затем проверять визуально, используя «таблицу истинности». Как только вы были довольны тем, что ваш код работал, вы отправили его в машинное отделение и запустили свой код — я недостаточно взрослый, чтобы помнить о вычислениях в 60-х годах. Тот факт, что машинное время было дорогим, означало, что об автоматическом тестировании не могло быть и речи. Хотя компьютеры становились все быстрее, эта устаревшая парадигма продолжала развиваться, превращаясь в такую, в которой вы пропустили тщательную умственную проверку и просто запустили код, а если он сломался, вы исправили его. Эта вырожденная парадигма все еще преподавалась (есть?) В школах, колледжах и книгах, и до последних нескольких лет она не вызывала сомнений.

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

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

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

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

Ссылка: Методы тестирования — Часть 1 — Не пишите тесты от нашего партнера по JCG в блоге Captain Debug .

Статьи по Теме :