четверг, 31 октября 2013 г.

Экстремальное программирование. Разработка через тестирование

Наша цель - чистый код, который работает.




Что такое TDD? Это вовсе не методика тестирования. "Это методика анализа, методика проектирования, фактически методика структурирования всей деятельности, связанной с разработкой программного кода".
Это великолепная книга для того, чтобы начать использовать TDD в своей профессиональной деятельности (если, конечно, есть желание). Книга легко читается и получаешь истинное удовольствие наблюдая за ходом мыслей автора (Кент Бек), который на реальном (ну почти) примере описывает, как вы можете использовать эти методики. Помимо этого автор очень подробно описывает паттерны для разработки через тестирование (такие как: паттерны красной полосы, зеленой полосы, тестирования и т.д.)
Мантра TDD:
Красный- напишите небольшой тест, который не работает;
Зеленый- напишите ровно столько кода, чтобы тест заработал;
Рефакторинг - удалите из написанного вами кода дублирование.
Достаточно простые правила, на которых базируется TDD. Однако, для начинающих не так-то просто им следовать. Мне понравился совет автора о том, с чего следует начать написание теста? "С операторов Assert, которые должны быть выполнены в рамках теста".
Не могу не привести пример из книги:
Представьте, что нам надо реализовать обмен данными с другой системой через сокет. После завершения операции сокет должен быть закрыт, а в буфер должна быть прочитана строка 'abc'

void TestCompleteTransaction()
{
    Assert.IsTrue(reader.IsClosed());
    Assert.AreEqual("abc", PingReply.Contents());
}
Откуда должен быть прочитан объект relpy? Конечно же из сокета:
void TestCompleteTransaction()
{
    Buffer reply = reader.Contents();
    Assert.IsTrue(reader.IsClosed());
    Assert.AreEqual("abc", PingReply.Contents());
}
Откуда берется сокет? Мы создаем его, подключаясь к серверу:
void TestCompleteTransaction()
{
    Socket reader = new Socket("localhost", defaultPort());
    Buffer reply = reader.Contents();
    Assert.IsTrue(reader.IsClosed());
    Assert.AreEqual("abc", PingReply.Contents());
}
Однако перед этим мы должны открыть сервер:
void TestCompleteTransaction()
{
    Server writer = new Server(defaultPort(), "abc");
    Socket reader = new Socket("localhost", defaultPort());
    Buffer reply = reader.Contents();
    Assert.IsTrue(reader.IsClosed());
    Assert.AreEqual("abc", PingReply.Contents());
}

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

  • Если вы воспользуетесь первой же идеей, которая пришла вам в голову, у вас не будет шанса реализовать вторую, лучшую идею.
  • Сначала мы пишем код, "который работает", после чего создадим "чистый код". Такой подход противоположен модели разработки на основе архитектуры, в котором вы сначала пишете "чистый код", а потом мучаетесь, пытаясь интегрировать в проект код, "который работает".
  • Вместо того, чтобы увеличить количество тестов и тем самым охватить всевозможные комбинации входных данных, мы оставляем количество тестов неизменным и меняем количество внутренних структурных комбинаций кода.
  • Когда вы начинаете писать тесты, вы обнаруживаете, что действуете в рамкам некоторой общей последовательности (Arrange, Act, Assert). Вначале вы создаете некоторые тестовые объекты (Arrange), затем вы заставляете эти объекты действовать (Act), затем вы проверяете результат их работы (Assert).
  • Зловещая спираль "нет времени для тестирования": Чем больший стресс вы ощущаете, тем меньше вы тестируете разрабатываемый код; Чем меньше вы тестируете разрабатываемый код, тем больше ошибок вы допускаете; Чем больше ошибок вы допускаете, тем выше уровень стресса, который вы ощущаете.
  • Большинство программистов инфицированно духом саморазрушения: "Я угроблю свое здоровье, отрекусь от своей семьи и даже выпрыгну из окна, лишь бы этот код заработал". :)
  • Каждый тест должен оставить рабочую среду в том же состоянии, в котором она была до того, как тест начал работу.
  • Пишите тесты до тех пор, пока страх не превратится в с скуку (к вопросу о том, что не подлежит тестированию).
  • Тесты - это канарейка, которую берут в угольную шахту для того, чтобы по ее поведению определить присутствие запаха плохого дизайна.


Комментариев нет:

Отправить комментарий