Обзор книги Modern C++ Programming with Test-Driven Development

Modern C++ Programming with Test-Driven DevelopmentКнига написана в 2013 году Джефом Лангром (Jeff Langr), человеком, о котором я раньше никогда не слышал (позже тоже). Сейчас мне трудно сказать, что побудило меня обратить внимание на эту книгу — вероятнее всего, я просто случайно наткнулся на неё на Amazon, когда покупал что-то другое. Что я могу сказать определенно, так это то, что до этой книги я не видел никаких книг, которые были бы посвящены тестированию с использованием C++. И я не вижу ничего кроме этой книги до сих пор. Исходя из этих предпосылок, я был весьма скептически настроен по отношению к ней: я не ожидал от неё ничего хорошего. Нет, правда, какая-то «одинокая в поле» книга по тестам, с примерами на современном C++, написанная каким-то неизвестным (для меня) автором, да ещё и от издательства, чьих книг я отродясь не видел. Поэтому, повторюсь, я не питал никаких надежд касательно качества материала. Тем удивительнее было увидеть в начале книги вступительное слово от Роберта Мартина (Uncle Bob), всячески восхваляющего сей труд.

Непосредственный обзор книги хочется начать с того, что у неё ужасное название. Если назвать её по содержимому, то получилось бы нечто такое: «Introduction to TDD with examples in [modern] C++» или по-русски: «Введение в TDD с примерами на [современном] C++». Текущее же название, на мой взгляд, создаёт впечатление, что эта книга по современному C++, но это не так. Эта книга по модульным тестам с очень сильным креном в сторону TDD (по-русски это можно перевести как «Разработка через тестирование» или РЧТ, но я буду придерживаться англоязычной аббревиатуры). Да, в коде примеров используются конструкции появившееся только в C++11, но это не является основным акцентом книги. Более того, как автор сам признаётся, он далёко не эксперт по языку C++, поэтому и код его не всегда может выглядеть оптимально с точки зрения этих самых экспертов.

Язык и структура книги вполне достойные и соответствуют «стандартам» книг по программированию. Хочется отметить, что главы книги построены довольно остроумно: в виде Setup/Case/Case…/Teardown,— мне нравятся такие оригинальные построения. Да они ничего не привносят, в плане полезной информации, но всегда приятно смотреть пусть и на робкие, но оригинальные подходы. Начинается книга с представления инструментария, который будет использоваться на протяжении всей книги (по большей части). Главным инструментом в книге является Google Test, что не может не радовать: отличный способ познакомиться с весьма интересным фреймворком, если до этого вы с ним не сталкивались. Затем читателя сразу бросают в TDD-бой, разбирая пример написания более-менее полезного (не абсолютно надуманная сущность!) класса с использованием вышеозначенной техники. Это довольно интересный метод, который позволяет сразу окунуться в пример, без прочтения предварительной теории: я знаю, что многие предпочитают именно такой метод обучения, но далеко не все. Правда, теория тоже не заставит себя долго ждать и будет разобрана уже в следующей главе, где читателя познакомят с основными моментами, что составляют методологию TDD.

Сразу за основами TDD, читателя посвящают в анатомию модульного теста: из чего он состоит, как его писать и т.п. Сразу хочется упомянуть, что в книге очень много кода, много примеров, но не подумайте, не просто кода-набивки (как иногда любят помещать целые простыни, чтобы книга толще получилась), а именно релевантного кода, который позволяет сразу видеть то, о чем говорит автор, вместо пережёвывания сухой теории. Вводно-поучительная часть завершается главой, посвящённой внедрению зависимостей и, соответственно, заглушкам и имитациям (stubs & mocks), с применением всё того же Google Test, что особенно полезно тем, кто ранее никогда не имел дела с этой темой, т.к. помимо определения самих сущностей, сразу видно как это реализовано в фреймворке — бери и используй. По завершении этой главы, автор считает, что у вас уже есть достаточно знаний, чтобы начинать писать свои C++-программы в TDD стиле. Оставшиеся же главы предназначены для полировки полученных знаний, а также посвящены некоторым философско-организационным вопросам.

Так, следующая глава посвящена инкрементальному проектированию — краеугольному камню всей гибкой методологии разработки и неизбежному результату применения TDD. А вслед за ней идёт глава посвящённая качеству тестов: мы уже научились писать тесты и даже TDD освоили, теперь нужно понять как писать тесты лучше, чтобы они не превратились из помощника в проблему.

Может ли книга по тестированию обойти вниманием унаследованный (legacy) код? Не может, и эта книга также содержит довольно хорошо проработанную главу посвящённую оному: рассматриваются различные проблемы, с которыми может столкнуться программист, а также приводится пример внедрения тестов в такой код. Затем идёт глава, в которой автор пытается нас убедить, насколько классно и удобно писать многопоточный код с применением TDD — хорошая попытка, но нас не проведёшь!

Завершается же книга 2 главами, которые посвящены различным аспектам тестов в целом и TDD в частности, что не нашли себе места в других главах.

Итак, разобравшись с содержимым книги, что можно сказать о её полезности? Когда я писал этот обзор, меня не покидала мысль, что книгу мне пора перечитать, хотя читал я её не так давно и, лично для меня, это отличный показатель того, что она весьма полезна. Да, не со всеми мнениями автора я был согласен, когда читал книгу: много спорил с ним и даже ругался (с книгой), но в целом она замечательная. Особенно если до этого про тесты вы либо не читали совсем, либо читали очень мало. Автор настырно продвигает TDD, что для меня является скорее минусом, т.к. я не верю ни в какие методологии в их рафинированном виде. Но, с другой стороны, никто не обязывает вас соглашаться с мнением автора по всем вопросам — он только представляет вам инструмент. Берите его, модифицируйте по желанию и используйте!

В общем, на мой взгляд, книга действительно стоит того, чтобы обратить на неё внимание как начинающим, так и уже несколько опытным программистам, которые считают, что их навыки написания тестов ещё не слишком хороши. Тем более, что для C++-программистов таких книг больше нет. Кстати, она является отличным дополнением к книге, что я обозревал в прошлый раз: The Art of Unit Testing: with examples in C#. Не считаю, что из них нужно выбирать одну,— советую прочитать обе.