Разделы портала

Онлайн-тренинги

.
Тестирование не для начинающих
24.06.2019 00:00

Автор оригинала: Jon Calhoun
Перевод: Иван Феофанов

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

Но несмотря на всю мою любовь к тестированию, я не рекомендую его новичкам.

Звучит дико, правда? В этой статье я собираюсь пояснить свою точку зрения более детально, но весь смысл, в итоге, сводится к двум пунктам:

  1. Начинающим не хватает знаний, чтобы писать что-либо кроме самых простых тестов. Это неизбежно приводит к следующему пункту…
  2. Пытаться тренировать навыки, необходимые для написания реалистичных тестов, одновременно с обучением программированию крайне тяжело

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

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


Начинающим не хватает знаний чтобы писать что-либо кроме самых простых тестов

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

Подтверждение этого вряд ли потребует каких-либо усилий, просто посмотрите на код, написанный новичком.

Веб-приложение на Go? Наверняка они пишут SQL-запросы везде и всюду в коде, и почти гарантированно соединение с базой хранится в глобальной переменной.

Rails-приложение? Наверняка вы увидите бизнес-логику в представлениях и тонны логических пробок в контроллерах.

Веб-приложение на PHP? Не удивлюсь, если ВСЯ логика будет в одном единственном php-файле — парсинг форм, взаимодействие с БД и т. д.

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

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

В результате, для новичка имеют смысл только простейшие тесты вроде таких:

func Add(a, b int) int {
  return a+b
}

// And a test...
func TestAdd(t *testing.T) {
  got := Add(2, 4)
  want := 6
  if got != want {
    t.Errorf("Add() = %d; want %d", got, want)
  }
}

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

В конце концов это приводит к тому, что мы начинаем учить их большему. Мы пытаемся объяснить, что такое dependency injection, почему глобальные переменные усложняют тестирование, как time.Now() может затруднить проверку пограничных случаев. И в этом месте я начинаю беспокоиться, ведь мы больше не учим начинающего как писать код. В этот момент мы учим его и как писать код И КАК ТЕСТИРОВАТЬ одновременно. И это приводит меня ко второму пункту…

Пытаться тренировать навыки, необходимые для написания реалистичных тестов одновременно с обучением программированию крайне тяжело

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

Если вы были похожи на меня, ваше первое веб-приложение могло бы выглядеть примерно так:

<p>
  <?php
  // This may not work. I don't know PHP anymore.
  $name = $_GET['name'];
  echo "Hello, " . $name;
  ?>
</p>


Произведение искусства, не так ли?

А теперь представьте, что вы только что написали этот код в первый раз и кто-то говорит вам, что вы должны его тестировать. И вы должны использовать React. И фреймворк. О, и вам не помешало бы настроить базу данных и, возможно, GraphQL чтобы работать с ней.

Не знаю, почему, но у нас, разработчиков, есть привычка использовать навыки, полученные в течении многих лет опыта и практики и ожидать, что другие, особенно новички, будут поступать так же. Это же просто смешно! Это как ожидать от кого-нибудь, что он будет разбираться в математике лишь потому, что ты сам уже изучил тригонометрию, алгебру и многое другое и можешь использовать математику для решения конкретных задач.

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

Как будто мы забыли, как мы шаг за шагом изучали, как работают HTTP запросы. Как работают заголовки. Куки. Формы. Как работает POST-запрос на сервер — или даже что ВООБЩЕ СУЩЕСТВУЮТ разные HTTP-методы. И всему этому мы учились старым добрым методом проб и ошибок.

На самом деле я не думаю, что во всем виноваты тесты, реальная проблема в том, что мы свято верим — вы должны учиться программированию, тестированию, сайтостроению и миллиону других вещей одновременно. Я не знаю на самом деле, как это произошло, но, подозреваю, отчасти проблема заключается в том, что мы не даём себе труда задуматься, чего будет стоить изучение всего этого. Новичок спрашивает “что мне изучать?” и мы начинаем “учи тестирование, react, graphql и go, но используй только стандартную библиотеку…”

Нет, нет, и ещё раз нет. Просто остановитесь.



Это смешно, поскольку в других условиях нелепость такого подхода очевидна. Если вы захотите научить кого-либо играть в футбол, вы же начнёте с основ вроде распасовки и ведения мяча. Вы же не начнёте с того, что скажете “Вот, как это делают профессионалы”, включите видео с Рональдо и уйдёте. Так какого чёрта мы поступаем так с новичками в программировании?

Мы пытаемся оправдаться, говоря “ну они конечно же понимают, что невозможно выучить всё это одновременно”, но они не понимают! Ситуацию усугубляет то, что начинающие разработчики, попадая в эту ловушку, чувствуют себя дерьмом из-за того, что застряли. Им кажется, что у них просто нет чего-то, что нужно чтобы стать разработчиком и это позор для нас с вами, потому что многие из них полюбили бы программирование, не врежься они в эту кирпичную стену.

И это подводит меня к тому, что я, собственно, хотел сказать — многие из нас учатся лучше, если фокусируются на изучении нескольких вещей сразу. Мы хотим новых вызовов, хотим пробовать новые штуки, но не хотим при этом запутаться и впасть в ступор. Изучать тестирование и что-нибудь ещё — например, как создать веб-приложение, как работает http, cookie, и т. д. — простой способ попасть в эту ловушку. И в результате я обычно рекомендую сначала изучить остальное, а тестирование — в последнюю очередь. Вы всегда можете вернуться к своим старым проектам и посмотреть, как бы вы перестроили их сейчас, когда вы изучили тестирование, но это возможно только если вы не перегружены, не расстроены и, в конце-концов, не бросили это дело.

Но что, если я хочу научиться тестировать ?! (и миллион других «что если»)

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

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

Это также не означает, что вы не можете учиться во время парного программирования или чего-либо вроде того. С ментором вы можете изучать много вещей одновременно и успешно выдерживать эту нагрузку, поскольку у вас есть тот, кто проведёт вас через всё это. В этой ситуации если вы потеряетесь, то не попадёте в тупик и не будете чувствовать себя неудачником, поскольку рядом будет тот, кто скажет “Ты отлично справляешься, просто это слишком сложно пока. В следующий раз попробуй вместо этого X и Y!”. Проще говоря, в этом сценарии растеряться, разочароваться и бросить всё вам не грозит.

Обсудить в форуме