Шрифт:
Интервал:
Закладка:
Это уже гораздо легче поддается обработке: вычисляемая функция — это множество, в котором максимум восемь элементов. Фактически проверка четырех случаев может дать полную уверенность, что функция корректна. Это одна из причин, почему при написании программ лучше использовать типы, тесно связанные с предметной областью, а не встроенные типы языка. Использование предметно-ориентированных типов часто позволяет значительно уменьшить размер функций. Один из способов выяснить, какими должны быть эти типы, — это найти примеры и определить термины предметной области до того, как писать функцию.
Тесты пишутся для людей
Джерард Мезарос
Вы покрываете автоматизированными тестами весь готовый код или его фрагменты. Поздравляем! Пишете сначала тесты, а потом код? Еще лучше! Уже благодаря этому вас можно причислить к программистам, практикующим передовые подходы в разработке программного обеспечения. Но хороши ли ваши тесты? Как это определить? Один из способов — спросить себя: «А для кого я пишу эти тесты?». Если ответом будет «я пишу их для себя, чтобы сократить затраты на исправление ошибок» или «для компилятора, чтобы их можно было выполнить», то вполне возможно, что вы пишете не самые лучшие тесты. Так для кого же нужно писать тесты? Для того, кто будет пытаться понять ваш код.
Хорошие тесты играют роль документации для тестируемого ими кода. Они описывают, как работает код. Для каждого сценария использования тесты делают следующее:
• Описывают контекст, начальную точку или предусловия, которые должны удовлетворяться.
• Иллюстрируют, как вызывается приложение.
• Описывают ожидаемые результаты или постусловия, которые необходимо проверить.
В различных сценариях использования варианты этих действий будут слегка различаться. Тот, кто попытается понять ваш код, должен иметь возможность посмотреть на несколько тестов и, сравнив эти три части рассматриваемых тестов, суметь определить, что заставляет программу в разных случаях работать по-разному. Каждый тест должен ясно иллюстрировать причинно-следственные связи между этими тремя частями.
Отсюда следует, что невидимая часть теста столь же важна, как и видимая. Обилие кода в тесте отвлекает внимание читателя на несущественные мелочи. По возможности скрывайте такие мелочи в понятных вызовах методов, и в этом вам здорово поможет прием рефакторинга Extract Method (Извлечь метод). И постарайтесь дать каждому тесту выразительное название, чтобы оно описывало конкретный сценарий использования, а читающему тесты человеку не пришлось анализировать каждый тест в попытке понять, в чем заключаются различия между сценариями. Во всех случаях имя класса теста и имя метода класса должны содержать хотя бы начальную точку и способ вызова приложения. Это позволит простым прочтением имен методов проверить покрытие кода тестами. В имена методов тестов полезно бывает включить ожидаемые результаты, если только это не сделает имена слишком длинными для чтения или восприятия.
Тестировать сами тесты — тоже хорошая идея. Можно проверить, смогут ли они обнаружить ошибки, которые должны находить, если ввести эти ошибки в производственный (production) код (разумеется, в локальную копию кода, которую вы потом выкинете). Проверьте, что тесты выдают полезные и осмысленные отчеты. Нужно также проверить, что ваши тесты говорят языком, понятным тому, кто разбирается с вашим кодом. Это можно сделать, только если дать прочесть тесты программисту, который не знаком с вашим кодом, и выслушать его впечатления. Если ему что-то непонятно, не связывайте это с нехваткой умственных способностей. Более вероятно, что это вы не сумели написать ясный код. (Попробуйте поменяться ролями и почитать его тесты!)
Нужно заботиться о коде
Пит Гудлиф
Не нужно быть Шерлоком Холмсом, чтобы понять, что хорошие программисты пишут хороший код. Ну, а плохие — нет. Они создают уродливые вещи, которые всем остальным приходится доводить до ума. Но вы-то хотите писать хороший код, правда? Тогда вам нужно стремиться стать хорошим программистом.
Хороший код не возникает сам по себе из ничего. Его появление не вызвано благоприятным расположением планет. Чтобы сделать код хорошим, нужно над ним работать, и немало. Вы создадите хороший код только тогда, когда действительно к этому стремитесь.
Хорошее программирование не является результатом одной лишь технической компетентности. Я встречал очень умных программистов, которые способны создавать сильные и впечатляющие алгоритмы, в совершенстве знают стандарты своего языка и пишут при этом совершенно отвратительный код. Его тяжело читать, с ним тяжело работать и его тяжело модифицировать. Я встречал и программистов с более скромными способностями, которые тяготеют к очень простому коду, но пишут элегантные и выразительные программы, работать с которыми одно удовольствие.
Опыт работы в отрасли разработки программного обеспечения привел меня к заключению, что на практике разница между просто компетентными программистами и выдающимися программистами заключается в одном: это отношение к работе. Хорошее программирование требует профессионального подхода и стремления написать как можно лучший код с учетом ограничений, накладываемых окружающей действительностью и требованиями отрасли.
Код, ведущий в ад, вымощен благими намерениями. Чтобы стать отличным программистом, нужно отказаться от благих намерений и действительно проявить заботу о коде — воспитывать в себе позитивный взгляд на написание кода и вырабатывать здоровое отношение к работе. Выдающийся код есть плод тщательных усилий искусных мастеров, а не поделка, небрежно сляпанная программистом, или таинственное создание самопровозглашенных гуру от кодирования.
Вы хотите писать хороший код. Вы хотите быть хорошим программистом. Тогда вы должны стремиться к следующему:
• Какими бы ни были условия работы, вы отказываетесь наскоро писать код, который предположительно решает задачу. Вы стремитесь писать красивый код, корректность которого очевидна (и доказывается хорошо написанными тестами).
• Вы пишете код, доступный для понимания (другие программисты могут быстро разобраться в нем и продолжить работу), легкий в сопровождении (вы или другие программисты легко сможете модифицировать его в будущем) и верный (вы сделали все возможное, чтобы показать, что вы действительно решили задачу, а не просто создали видимость работающей программы).
• Вы хорошо ладите с другими программистами. Программист не должен быть отшельником. Редкий программист работает в одиночку: большинство трудится в составе команды программистов, будь то в рамках компании или проекта с открытым исходным кодом. Вы учитываете особенности других программистов и пишете код так, чтобы они могли его прочесть. Вы стремитесь помочь команде создать как можно лучший продукт, а не показать, какой вы умный.
• Когда к вам в руки попадает код, вы стараетесь, чтобы после вас он стал немного лучше (лучше организован, лучше протестирован, более понятен…).
• Вы любите код и программирование, поэтому вы постоянно изучаете новые языки, идиомы и новые приемы. Но применяете их только тогда,