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

Автор оригинала: 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!”. Проще говоря, в этом сценарии растеряться, разочароваться и бросить всё вам не грозит.
  • +10
  • 11,6k
  • 6
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 6

    +1

    Я сейчас плавно учу Rust, и там тестирование даётся в главе №11, а основы ввода-вывода — в главе №12. И это офигенный подход. Написал трейт? Напиши тест.


    Главная боль всякого php — в том, что начинающий начинает писать раньше, чем понимает что пишет.

      0

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


      Кейс совершенно обычный — сервис, генерирующий отчёты, счета, акты и т.п.

        +1
        Мне кажется, тут смешали две группы людей: будущие профессионалы-программисты и условные «домохозяйки», которые хотят себе себе сайт-визитку или малинку с чайником связать. Вот для первых тезис «пытаться изучать тестирование плюс что-либо ещё — ошибка» я бы развил в «следовательно они должны начинать с тестирования». Тестирование очень сильно способствует элегантности кода, а правило «тесты — код первого порядка и подчиняются тем же требованиям, что и основной код» способствует элегантности тестов.
        Есть ещё известный эффект, что мотивация сильно падает, если долгое время не видно результата — если стек глубокий, а до hello world'а ещё пилить и пилить. Так вот, если параллельно делать тесты, то эффект сильно слабеет, во всяком случае для меня лично.
          0

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


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


          А вот в откладывании тестов "на потом" — проблема есть. Если не приучать к тестам с пелёнок, то потом они так и будут писать… :)

            0
            А вот в откладывании тестов «на потом» — проблема есть. Если не приучать к тестам с пелёнок, то потом они так и будут писать… :)

            Нахожусь сейчас как раз в такой ловушке — «так и пишу». Но у нас на фирме вообще нет культуры разработки, так что начиная свой путь тут я не слышал от «старших товарищей» про тесты, работу в команде, даже локальный git у нас «добровольно-принудительный».
            Но время идет, проекты растут, и я уже пришел к пониманию того, что без тестов хуже и хуже, дольше и дольше. Теперь только нужно перебороть себя и, отодвинув на время текущие задачи, начать плотно разбираться с тестированием.
            0
            Нужно разделять тесты на те которые для 100% покрытия и надежности всего приложения, и те которые чтобы избежать рутинной самостоятельной проверки работоспособности кода. Второю категорию нужно писать сразу, так как это сама суть программирования не делать руками одно и тоже более 2 раз.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое