Video Thumbnail

008: Introduction to Test Driven Development (TDD) creating a Stack - Abstract Data Type (Golang)

The Engineering Coach32:57
https://www.youtube.com/watch?v=yFknOWRWpoY

Содержание

Краткое резюме

  • В видео показан процесс разработки стека на языке Go с использованием принципов TDD (Test-Driven Development) по правилам Uncle Bob.
  • Рассматривается работа с базовым фреймворком тестирования Go, без дополнительных библиотек для assert.
  • Пошагово реализуются основные методы стека: проверка пустоты, добавление элементов, определение размера, извлечение элементов (pop) с постоянной проверкой работоспособности через тесты.
  • На каждом шаге применяется цикл TDD: red (пишем падающий тест), green (реализуем минимум, чтобы пройти тест), refactor (улучшаем код без изменения интерфейса).
  • В финале реализован полноценный стек с внутренним срезом для хранения элементов.
  • Обсуждаются потенциальные улучшения, эти вопросы будут рассмотрены в следующих видео.

Введение в тестирование в Go и TDD

Mark Bradley начинает с объяснения, что язык Go содержит встроенный фреймворк для тестирования, который мы будем использовать без сторонних библиотек. Основой для разработки служат три правила TDD от Uncle Bob:

«Пиши только такой продакшен-код, который нужен для прохождения теста.»

Правила вкратце:

  1. Не пиши продакшен-код, пока не написан тест, который не проходит.
  2. Пиши минимальный тест, просто чтобы зафиксировать ошибку (включая ошибки компиляции).
  3. Пиши минимальный код, чтобы пройти тест.

Реализация стека с нуля

Проверка пустоты стека

  • Сначала создаётся тест empty, который проверяет, что при создании новый стек пуст (empty возвращает true).
  • Для компиляции создаётся пустая структура stack и функция newStack().
  • Метод empty() на стеке пока возвращает false, чтобы потом перейти к разным вариантам реализации.
  • Тест падает, как и ожидалось.
  • Чтобы пройти тест, метод empty() меняется на возврат true.
  • Тест теперь успешно проходит.

Добавление элемента и проверка не пустоты

  • Создаётся тест not empty, который проверяет, что после добавления элемента стек уже не пуст.
  • Добавляется метод add(string).
  • Реализация меняется: в структуру добавляется булев флаг isEmpty bool. Новая логика — при добавлении элемент isEmpty меняется на false.
  • Тесты empty и not empty проходят успешно.

Определение размера стека

  • Пишется тест size zero — пустой стек должен иметь размер 0.
  • Добавляется метод size() int.
  • Сначала возвращается заглушка, например -1, чтобы тест падал с понятной ошибкой.
  • Вернув 0 — тест проходит.
  • Пишется тест size one — после добавления одного элемента размер должен быть 1.
  • Логика меняется: к структуре добавляется поле size int, увеличиваемое при добавлении.
  • Тесты проходят.
  • Добавляется тест для трёх элементов (size three) — после добавления трёх конкретных строк размер должен быть 3.
  • Реализация исправляется с учётом инкремента size при добавлении.
  • Тесты зеленеют.

Рефакторинг

  • Понимают, что isEmpty избыточен — можно вычислять пустоту по size == 0.
  • isEmpty удаляется.
  • Все тесты успешно проходят.

Реализация метода pop

Извлечение одного элемента

  • Тест one проверяет, что при одном элементе pop возвращает этот элемент и выкидывает из стека (размер становится 0).
  • Создаётся метод pop() string.
  • Изначально возвращается пустая строка.
  • Для прохождения теста возвращают конкретно Bob.
  • Добавляется проверка после попа, что размер стал 0 (или стек пуст).
  • Для прохождения теста размер уменьшают при попе.

Извлечение нескольких элементов

  • Тест pop two — после добавления двух элементов, вызов pop должен вернуть последний добавленный (Alice), а следующий вызов — первый (Bob).
  • Изначальная реализация сохраняет только последний элемент, поэтому тест падает.
  • Решение: вместо хранения одного элемента, используется срез values []string для хранения всех значений.
  • Добавляются логика добавления в срез и правильный pop с уменьшением размера и возвратом последнего элемента.
  • Все тесты проходят.

Итоги и выводы

  • Видео демонстрирует классический цикл TDD (красный-зелёный-рефакторинг) на примере стека в Go.
  • Используется только стандартная библиотека, без внешних assertion-библиотек, поэтому проверки сделаны через простые if с вызовом t.Error.
  • Важно писать минимальный код для прохождения теста, постепенно усложняя реализацию.
  • В финальной версии стек хранит элементы в срезе и корректно поддерживает размер, добавление и удаление.
  • Обсуждается, что можно ещё улучшить (например, обрабатывать ошибки при pop из пустого стека) в будущих видео.

«Написание долгих тестов из-за отсутствия assert-библиотеки — это нормально, зато код получается чистым и понятным.»


Заключение

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