Эффективное тестирование программного обеспечения
Руководство разработчика
Покупка
Издательство:
ДМК Пресс
Автор:
Аниче Маурисио
Перевод:
Киселев Артём Николаевич
Год издания: 2023
Кол-во страниц: 370
Дополнительно
Вид издания:
Практическое пособие
Уровень образования:
Профессиональное образование
ISBN: 978-5-97060-997-2
Артикул: 817288.01.99
В этой книге представлены основы систематического эффективного тестирования программного обеспечения. Показаны способы автоматизировать часть этого процесса, приводятся шаблоны проектирования, которые помогут писать легко контролируемый и простой для наблюдения код. Обсуждаются модульные, интеграционные и системные тесты; рассматривается передовой опыт работы с тестовым кодом.
Издание адресовано разработчикам с разным уровнем знаний: начинающие детально изучат процесс тестирования на конкретных примерах, опытные познакомятся с новыми практическими приемами и отточат имеющиеся навыки.
- Полная коллекция по информатике и вычислительной технике
- DevOps
- ДМК Пресс. Информационные системы и технологии
- ДМК Пресс. ИТ-технологии для профессионалов
- Интермедиатор. Информационные системы и технологии (сводная)
- Интермедиатор. ИТ-технологии для профессионалов (сводная)
- Локальные компьютерные сети. Программное обеспечение локальных сетей. ОС
- Системное и сетевое администрирование
Тематика:
ББК:
УДК:
ОКСО:
- ВО - Бакалавриат
- 02.03.02: Фундаментальная информатика и информационные технологии
- 09.03.01: Информатика и вычислительная техника
- 09.03.02: Информационные системы и технологии
- 09.03.04: Программная инженерия
ГРНТИ:
Скопировать запись
Фрагмент текстового слоя документа размещен для индексирующих роботов.
Для полноценной работы с документом, пожалуйста, перейдите в
ридер.
Маурисио Аниче Эффективное тестирование программного обеспечения
Effective Software Testing A DEVELOPER’S GUIDE MAURÍCIO ANICHE Forewords by ARIE VAN DEURSEN and STEVE FREEMAN
Эффективное тестирование программного обеспечения РУКОВОДСТВО РАЗРАБОТЧИКА МАУРИСИО АНИЧЕ Предисловие Ари ван Дерсена и Стива Фримана Москва, 2023
УДК 004.415.53 ББК 32.372 А67 Аниче М. А67 Эффективное тестирование программного обеспечения / пер. с англ. А. Н. Киселева. – М.: ДМК Пресс, 2023. – 370 с.: ил. ISBN 978-5-97060-997-2 В этой книге представлены основы систематического эффективного тестирования программного обеспечения. Показаны способы автоматизировать часть этого процесса, приводятся шаблоны проектирования, которые помогут писать легко контролируемый и простой для наблюдения код. Обсуждаются модульные, интеграционные и системные тесты; рассматривается передовой опыт работы с тестовым кодом. Издание адресовано разработчикам с разным уровнем знаний: начинающие детально изучат процесс тестирования на конкретных примерах, опытные познакомятся с новыми практическими приемами и отточат имеющиеся навыки. УДК 004.415.53 ББК 32.372 © LICENSEE 2023. Authorized translation of the English edition © 2021 Manning Publications. This translation is published and sold by permission of Manning Publications, the owner of all rights to publish and sell the same. Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. ISBN 978-1-6334-3993-1 (англ.) © Manning Publications, 2022 ISBN 978-5-97060-997-2 (рус.) © Перевод, оформление, издание, ДМК Пресс, 2022
Оглавление 1 Эффективное и систематическое тестирование программного обеспечения .....................................................................................................28 2 Тестирование на основе спецификаций ........................................................64 3 Структурное тестирование и охват кода ......................................................101 4 Проектирование по контрактам ...................................................................138 5 Тестирование на основе свойств ...................................................................161 6 Дублеры и имитации для тестирования .......................................................187 7 Проектирование с учетом простоты тестирования .....................................222 8 Разработка через тестирование ....................................................................251 9 Большие тесты ................................................................................................270 10 Качество тестового кода ................................................................................319 11 Заключение .....................................................................................................340
Содержание Оглавление ............................................................................................................ 5 Предисловие ........................................................................................................ 12 Вступление ......................................................................................................... 15 Благодарности .................................................................................................... 17 О книге ................................................................................................................ 20 Об авторе ........................................................................................................... 26 Об иллюстрации на обложке .............................................................................. 27 1 Эффективное и систематическое тестирование программного обеспечения ................... 28 1.1 Разница между разработчиками, тестирующими и не тестирующими свой код ................................................................ 29 1.2 Эффективное тестирование программного обеспечения для разработчиков .................................................................................. 40 1.2.1 Эффективное тестирование в процессе разработки .................... 41 1.2.2 Эффективное тестирование как итеративный процесс ............... 43 1.2.3 Сосредоточение внимания на разработке, а затем на тестировании .......................................................................... 43 1.2.4 Миф о «правильности по замыслу» ................................................ 44 1.2.5 Стоимость тестирования ........................................................... 44 1.2.6 Что подразумевается под словами «эффективный» и «систематический» ................................................................... 45 1.2.7 Роль автоматизации тестирования ............................................ 45 1.3 Принципы тестирования программного обеспечения (или Почему тестирование такое сложное) .......................................... 46 1.3.1 Всеобъемлющее тестирование невозможно .................................. 46 1.3.2 Своевременное прекращение тестирования .................................. 47 1.3.3 Изменчивость важна (парадокс пестицидов) ................................ 47 1.3.4 В одних частях ошибок больше, чем в других .................................. 47 1.3.5 Никакой объем тестирования не будет идеальным или достаточным ......................................................................... 48 1.3.6 Контекст имеет решающее значение ........................................... 48 1.3.7 Верификация не валидация ............................................................ 49 1.4 Пирамида тестирования и на чем следует сосредоточиться............... 49 1.4.1 Модульное тестирование ............................................................. 50 1.4.2 Интеграционное тестирование .................................................... 52 1.4.3 Системное тестирование ............................................................ 53
Содержание 1.4.4 Когда использовать каждый уровень тестирования ...................... 54 1.4.5 Почему я предпочитаю модульные тесты? ................................... 55 1.4.6 Что я тестирую на разных уровнях?............................................. 56 1.4.7 Что делать, если вы не согласны с пирамидой тестирования ........ 57 1.4.8 Поможет ли эта книга найти все ошибки? ................................... 60 Упражнения ........................................................................................................ 60 Итоги ................................................................................................................. 62 2 Тестирование на основе спецификаций ........................... 64 2.1 Требования говорят сами за себя .......................................................... 65 2.1.1 Шаг 1: изучение требований, входных и выходных данных .............. 68 2.1.2 Шаг 2: исследование, что делает программа для различных входных данных ............................................................................. 68 2.1.3 Шаг 3: изучение возможных входных и выходных данных и определение разделов ................................................................. 69 2.1.4 Шаг 4: анализ границ .................................................................... 72 2.1.5 Шаг 5: определение списка тестов ................................................ 74 2.1.6 Шаг 6: автоматизация тестирования ......................................... 76 2.1.7 Шаг 7: расширение набора тестов с применением творческой смекалки и опыта ......................................................................... 79 2.2 Коротко о тестировании на основе спецификаций ............................. 80 2.3 Поиск ошибок с помощью тестирования на основе спецификаций .... 82 2.4 Тестирование на основе спецификаций в реальных условиях ........... 91 2.4.1 Процесс тестирования должен быть итеративным, а не последовательным ................................................................. 91 2.4.2 Как далеко следует заходить при тестировании на основе спецификаций? ............................................................................. 91 2.4.3 Раздел или граница? Не имеет значения! ...................................... 91 2.4.4 Точек включения и исключения достаточно, но не стесняйтесь добавлять точки входа и выхода ................................................... 92 2.4.5 Используйте варианты одних и тех же входных данных для более полного понимания ........................................................ 92 2.4.6 Когда количество комбинаций резко возрастает, оставайтесь прагматичными ...................................................... 92 2.4.7 Если сомневаетесь, используйте самые простые входные данные .... 93 2.4.8 Выбирайте разумные значения входных данных, которые вас не беспокоят................................................................................. 93 2.4.9 Проверяйте на null и исключительные случаи, только когда это имеет смысл .......................................................................... 93 2.4.10 Используйте параметризованные тесты, когда тесты имеют одну и ту же структуру ................................................................ 94 2.4.11 Требования могут иметь любую степень детализации ................. 94 2.4.12 Применима ли предложенная методика для тестирования классов и состояний? .................................................................... 95 2.4.13 Роль опыта и творчества ............................................................. 96 Упражнения ........................................................................................................ 97 Итоги ................................................................................................................. 99 3 Структурное тестирование и охват кода .................101 3.1 Охват кода, правильный способ ...........................................................102 3.2 Кратко о структурном тестировании ...................................................105
Содержание 3.3 Критерии охвата кода ...........................................................................107 3.3.1 Охват строк ...............................................................................107 3.3.2 Охват ветвей ..............................................................................107 3.3.3 Охват условий + ветвей ...............................................................108 3.3.4 Охват путей ...............................................................................109 3.4 Сложные условия и критерий охвата MC/DC ....................................... 110 3.4.1 Абстрактный пример ..................................................................110 3.4.2 Создание набора тестов по критерию MC/DC .............................111 3.5 Тестирование циклов и других подобных конструкций ....................113 3.6 Классификация и выбор критериев .....................................................114 3.7 Тестирование на основе спецификаций и структурное тестирование: практический пример ..................................................115 3.8 Граничное и структурное тестирование ..............................................120 3.9 Одного структурного тестирования часто недостаточно ...................121 3.10 Структурное тестирование в реальном мире ......................................123 3.10.1 Почему некоторые испытывают неприязнь к оценке охвата кода? ...........................................................................................123 3.10.2 Что означает достижение 100 % охвата? ...................................125 3.10.3 Какой критерий охвата использовать .........................................127 3.10.4 MC/DC для слишком сложных выражений, которые нельзя упростить ...................................................................................127 3.10.5 Другие критерии охвата ..............................................................129 3.10.6 Когда полный охват нежелателен? ..............................................129 3.11 Мутационное тестирование .................................................................130 Упражнения .......................................................................................................133 Итоги ................................................................................................................137 4 Проектирование по контрактам .......................................138 4.1 Пред- и постусловия ..............................................................................139 4.1.1 Ключевое слово assert ...................................................................140 4.1.2 Строгие и слабые пред- и постусловия .........................................141 4.2 Инварианты ...........................................................................................143 4.3 Изменение контрактов и принцип подстановки Лисков ...................147 4.3.1 Наследование и контракты .........................................................149 4.4 Как проектирование по контрактам связано с тестированием? .......151 4.5 Проектирование по контрактам в реальном мире .............................152 4.5.1 Слабые или строгие предусловия? ................................................153 4.5.2 Проверка допустимости входных данных, контракты или и то и другое? ........................................................................153 4.5.3 Утверждения и исключения: когда использовать то или другое ....155 4.5.4 Исключение или возврат специального значения? ........................157 4.5.5 Когда не следует использовать проектирование по контрактам ...........................................................................157 4.5.6 Следует ли писать тесты для предусловий, постусловий и инвариантов? ...........................................................................158 4.5.7 Инструментальная поддержка ....................................................158 Упражнения .......................................................................................................159 Итоги ................................................................................................................160 5 Тестирование на основе свойств ..........................................161 5.1 Пример 1: программа проверки оценок за экзамены ........................162
Содержание 5.2 Пример 2: тестирование метода unique ..............................................166 5.3 Пример 3: тестирование метода indexOf .............................................168 5.4 Пример 4: тестирование класса Basket ................................................174 5.5 Пример 5: создание сложных объектов предметной области ............182 5.6 Тестирование на основе свойств в реальном мире ............................183 5.6.1 Тестирование на основе примеров и на основе свойств ................183 5.6.2 Общие проблемы в тестах на основе свойств ..............................184 5.6.3 Творческая смекалка имеет решающее значение ..........................185 Упражнения .......................................................................................................186 Итоги ................................................................................................................186 6 Дублеры и имитации для тестирования ......................187 6.1 Пустышки, фиктивные объекты, заглушки, шпионы и имитации ....190 6.1.1 Объекты-пустышки ....................................................................190 6.1.2 Фиктивные объекты ....................................................................190 6.1.3 Заглушки .....................................................................................190 6.1.4 Имитации ...................................................................................191 6.1.5 Шпионы .......................................................................................191 6.2 Введение в фреймворки имитаций .....................................................191 6.2.1 Заглушки .....................................................................................192 6.2.2 Имитации и ожидания .................................................................197 6.2.3 Захват аргументов .....................................................................200 6.2.4 Моделирование исключений .........................................................204 6.3 Имитации в реальном мире .................................................................206 6.3.1 Недостатки имитаций ...............................................................207 6.3.2 Что следует и не следует имитировать ......................................208 6.3.3 Обертки для даты и времени .......................................................213 6.3.4 Имитация типов, которыми вы не владеете ...............................215 6.3.5 Что другие говорят об имитациях? .............................................217 Упражнения .......................................................................................................219 Итоги 220 7 Проектирование с учетом простоты тестирования .......................................................................................222 7.1 Отделение инфраструктурного кода от предметного ........................223 7.2 Внедрение зависимостей и управляемость .........................................232 7.3 Улучшение наблюдаемости классов и методов ...................................235 7.3.1 Пример 1: добавление методов для упрощения проверок ..............236 7.3.2 Пример 2: наблюдение за поведением методов void ......................237 7.4 Передача зависимостей через конструктор класса и значений через параметры методов ....................................................................240 7.5 Проектирование с учетом простоты тестирования на практике .......244 7.5.1 Связность тестируемого класса ..................................................244 7.5.2 Тесная связь с тестируемым классом ...........................................245 7.5.3 Сложные условия и тестируемость .............................................246 7.5.4 Приватные методы и тестируемость ........................................246 7.5.5 Статические методы, синглтоны и тестируемость ...................247 7.5.6 Гексагональная архитектура и имитации как метод проектирования ..........................................................................247 7.5.7 Дополнительная информация о проектировании с учетом
Содержание тестируемости .......................................................................................248 Упражнения .......................................................................................................248 Итоги ................................................................................................................250 8 Разработка через тестирование .........................................251 8.1 Наш первый сеанс TDD .........................................................................252 8.2 Размышления о первом опыте применения TDD ...............................260 8.3 TDD в реальном мире ............................................................................262 8.3.1 Использовать или не использовать TDD? .....................................262 8.3.2 TDD следует использовать постоянно? .......................................263 8.3.3 Подходит ли TDD для всех типов приложений? ............................263 8.3.4 Что говорят исследования о TDD? ...............................................264 8.3.5 Другие школы TDD .......................................................................265 8.3.6 TDD и правильное тестирование .................................................267 Упражнения .......................................................................................................267 Итоги ................................................................................................................269 9 Большие тесты ....................................................................................270 9.1 Когда использовать большие тесты .....................................................271 9.1.1 Тестирование больших компонентов ...........................................271 9.1.2 Тестирование больших компонентов, взаимодействующих с внешним кодом ..........................................................................280 9.2 База данных и тестирование SQL .........................................................285 9.2.1 Что тестировать в SQL-запросе.................................................285 9.2.2 Автоматизированные тесты для SQL-запросов ..........................287 9.2.3 Настройка инфраструктуры для тестирования SQL ..................293 9.2.4 Рекомендации ..............................................................................295 9.3 Системные тесты ...................................................................................296 9.3.1 Введение в Selenium ......................................................................297 9.3.2 Проектирование объектов страниц ............................................300 9.3.3 Шаблоны и лучшие практики .......................................................310 9.4 Заключительные замечания по большим тестам ...............................314 9.4.1 Как сочетаются методы тестирования в больших тестах?........314 9.4.2 Анализ затрат/выгод ..................................................................315 9.4.3 Будьте осторожны с методами, охваченными, но не проверенными тестами ......................................................315 9.4.4 Инфраструктурный код имеет большое значение ........................316 9.4.5 DSL и инструменты для разработки тестов клиентами ............316 9.4.6 Тестирование веб-систем других типов ......................................316 Упражнения .......................................................................................................317 Итоги ................................................................................................................318 10 Качество тестового кода ...........................................................319 10.1 Отличительные черты поддерживаемого тестового кода ..................320 10.1.1 Тесты должны быть быстрыми ...................................................320 10.1.2 Тесты должны быть связными, независимыми и изолированными .......................................................................320 10.1.3 Тесты должны иметь причину для существования .......................321 10.1.4 Тесты должны быть воспроизводимыми и надежными .................321 10.1.5 Тесты должны иметь строгие утверждения ................................323
Содержание 10.1.6 Тесты должны терпеть неудачу при изменении поведения ...........323 10.1.7 Тесты должны иметь единственную и четкую причину неудачи ...324 10.1.8 Тесты должны быть простыми в разработке ..............................324 10.1.9 Тесты должны легко читаться ....................................................325 10.1.10 Тесты должны позволять легко изменять и развивать их ............329 10.2 Дурно пахнущие тесты ..........................................................................329 10.2.1 Чрезмерное дублирование.............................................................330 10.2.2 Нечеткие утверждения ................................................................331 10.2.3 Неправильное обращение со сложными или внешними ресурсами ....................................................................................331 10.2.4 Слишком обобщенные наборы тестовых данных ..........................332 10.2.5 Чувствительные утверждения ....................................................333 Упражнения .......................................................................................................336 Итоги ................................................................................................................339 11 Заключение ..............................................................................................340 11.1 Хотя модель выглядит линейной, итерации имеют фундаментальное значение .................................................................340 11.2 Разработка программного обеспечения без ошибок: миф или реальность? ............................................................................341 11.3 Вовлекайте в процесс тестирования конечных пользователей .........342 11.4 Модульное тестирование – сложная задача ........................................343 11.5 Уделяйте внимание мониторингу ........................................................344 11.6 Что дальше? ...........................................................................................344 Приложение A. Решения упражнений ................................................................346 Ссылки ................................................................................................................354 Предметный указатель .....................................................................................361
Предисловие В современной разработке программного обеспечения тестирование управляет проектированием, реализацией, развитием, обеспечением качества и развертыванием программных систем. Чтобы быть эффективным разработчиком, вы должны стать успешным тестировщиком программного обеспечения, и эта книга поможет вам в этом. Тестирование – это не что иное, как выполнение части программного обеспечения с целью увидеть, соответствует ли его поведение ожидаемому. Но тестирование – непростая задача. Его сложность становится очевидной, стоит только подумать о полном наборе тестов, которые необходимо спроектировать и выполнить. Какие из бесконечного множества возможных тестов следует написать? Достаточно ли полно протестирована система, чтобы ее можно было передать в промышленную эксплуатацию? Какие дополнительные тесты нужны и зачем? И если нужно изменить систему, то как настроить набор тестов, чтобы он способствовал, а не препятствовал будущим изменениям? Книга не увиливает от таких сложных вопросов. Она охватывает такие ключевые методы тестирования, как проектирование по контрактам, тестирование на основе свойств, граничное тестирование, критерии достаточности тестирования, мутационное тестирование и правильное использование фиктивных объектов. А там, где это уместно, дает ссылки на исследовательские работы по теме. В то же время эта книга наглядно показывает, что сами тесты и процесс тестирования остаются настолько простыми, насколько это возможно. Эта простота достигается за счет того, что всегда принимается точка зрения разработчика, который фактически разрабатывает и запускает тесты. Книга полна примеров, которые помогут читателю сразу приступить к применению приемов в своих проектах. Эта книга появилась на основе курса, преподававшегося в Делфтском техническом университете в течение многих лет. Этот курс по тестированию программного обеспечения я ввел в учебную программу
Предисловие бакалавриата в 2003 году. В 2016-м ко мне присоединился Маурисио Аниче, а в 2019 году он полностью взял этот курс на себя. Маурисио – превосходный лектор, и в 2021 году студенты избрали его учителем года факультета электротехники, математики и компьютерных наук. В Делфтском техническом университете мы обучаем тестированию на самом первом курсе нашей программы бакалавриата по информатике и вычислительной технике. Было трудно найти книгу, соответствующую нашему представлению о том, что эффективный инженер-программист должен быть эффективным тестировщиком программного обеспечения. Многие академические учебники сосредоточены на результатах исследований. Многие книги, ориентированные на разработчиков, посвящены конкретным инструментам или процессам. Книга «Эффективное тестирование программного обеспечения» Маурисио Аниче (Maurício Aniche) заполняет этот пробел между теорией и практикой. Она написана для действующих разработчиков и освещает самые современные методы тестирования программного обеспечения. В то же время она идеально подходит для университетских курсов бакалавриата и учит следующее поколение информати- ков, как стать эффективными тестировщиками программного обеспечения. – Доктор Ари ван Дерсен (Dr. Arie van Deursen), профессор факультета программной инженерии, Делфтский технический университет, Нидерланды Книга «Эффективное тестирование программного обеспечения» Ма- урисио Аниче (Maurício Aniche) – это практическое введение, которое поможет разработчикам тестировать свой код. Это компактный обзор основ тестирования программного обеспечения, охватывающий основные темы, о которых должен знать каждый разработчик. Сочетание теории и практики в книге показывает глубину опыта Маурисио как ученого и действующего программиста. Мой собственный путь в информатике был довольно случайным: несколько курсов программирования в университете, обучение на рабочем месте и, наконец, курс переквалификации, ведущий к получению докторской степени. Это заставило меня завидовать программистам, которые прошли нужные курсы в нужное время и обладали теоретической базой, которой мне не хватало. Я периодически обнаруживал, что та или иная моя идея, обычно с недоработанной реализацией, оказывалась устоявшейся концепцией, о которой я не слышал. Вот почему я считаю важным читать вводные материалы, такие как эта книга. На протяжении большей части моей профессиональной карьеры я рассматривал тестирование как необходимое зло, которое в основном связано с утомительным выполнением текстовых инструкций вручную. В настоящее время стало совершенно очевидно, что автоматизация тестирования лучше всего выполняется с помощью компью-
Предисловие теров, но потребовались десятилетия, чтобы это понимание нашло широкое распространение. Вот почему разработка через тестирование, когда я впервые столкнулся с ней, сначала показалась мне безумием, а затем необходимостью. В своей практике мне приходилось видеть много малопонятного тестового кода. Это особенно заметно задним числом, когда отсутствует давление сроков или когда модель предметной области устоялась. Я считаю, что этот тестовый код можно было бы улучшить, если бы методы структурирования и анализа задач, описанные в этой книге, имели большее распространение среди программистов. Это не означает, что все мы должны стать учеными, однако простота применения концепций может иметь большое значение. Например, я считаю проектирование по контрактам полезным при работе с компонентами, сохраняющими состояние. Возможно, я не всегда добавляю явные предварительные и заключительные проверки в свой код, но знание концепций помогает мне думать или обсуждать, что должен делать код. Очевидно, что тестирование программного обеспечения – важная тема для разработчиков, и эта книга поможет им начать ее осваивать. Для тех из нас, кто занимается этой темой немного дольше, книга послужит хорошим напоминанием о методах, которыми мы пренебрегли или, возможно, упустили в первый раз. В книге также имеются замечательные разделы, посвященные тестированию программного обеспечения как практике, в частности краткое введение в крупномасштабное тестирование и, что мне особенно нравится, обсуждение вопросов поддержания высокого качества тестового кода. В реальном мире многие наборы тестов превращаются в источник разочарования, потому что они не поддерживаются. Опыт Маурисио проявляется в практических рекомендациях и эвристиках, которые он включает в объяснение каждой методики. Он тщательно описывает инструменты, но позволяет читателю найти свой собственный путь (хотя обычно лучший выбор – последовать его совету). И конечно же, содержание самой книги было тщательно протестировано, так как изначально она разрабатывалась на основе его курса в Делфтском техническом университете. Я сам часто встречался с Маурисио, когда читал лекции для его курса, после которых мы заходили в палатку в историческом центре города, чтобы отведать маринованной сельди (имеющей уникальный вкус для гурманов Северной Европы). Мы обсуждали методы программирования и тестирования, а также жизнь в Нидерландах. Я был впечатлен его стремлением дать все самое лучшее своим студентам и его идеями для исследований. Я с нетерпением жду, когда снова смогу сесть на поезд до Делфта. – Доктор Стив Фриман (Dr. Steve Freeman), автор книги «Growing Object-Oriented Software, Guided by Tests» (Addison-Wesley Professional)
Вступление Каждый разработчик программного обеспечения помнит конкретную ошибку, повлиявшую на его карьеру. Позвольте мне рассказать вам о моей ошибке. В 2006 году я занимал должность технического руководителя небольшой группы разработчиков, работавшей над созданием приложения для контроля платежей на заправочных станциях. В то время я заканчивал бакалавриат по информатике и начинал свою карьеру как разработчик программного обеспечения. До этого мне приходилось работать только над двумя серьезными веб- приложениями. И, как ведущий разработчик, я очень серьезно относился к своим обязанностям. Система должна была напрямую связываться с подающими насосами. Как только клиент заканчивал заправку, бензоколонка уведомляла нашу систему и приложение запускало свой процесс: сбор информации о покупке (тип топлива, количество в литрах), расчет конечной стоимости, проведение пользователя через процесс оплаты и сохранение информации для будущей отчетности. Программная система должна была работать на выделенном устройстве с процессором 200 МГц, 2 Мбайт ОЗУ и несколькими мегабайтами постоянной памяти. Это была первая попытка внедрения устройства в бизнес. То есть не было никакого предшествующего проекта, опыт разработки которого мы могли бы изучить или позаимствовать из него код. Мы также не могли повторно использовать какие-либо внешние библиотеки, и нам даже пришлось реализовать свою упрощенную базу данных. Система обслуживала заправочные станции, поэтому моделирование их оборудования стало жизненно важной частью нашего процесса разработки. Мы писали новую функцию, запускали систему, запускали симулятор, моделировали несколько покупок топлива и вручную проверяли, правильно ли реагирует система. Через несколько месяцев мы реализовали несколько важных функций. Наши тесты (выполнявшиеся вручную), включая тесты, проведенные компанией, прошли успешно. У нас появилась версия, которую можно было протестировать в реальных условиях! Но испытания в реальных условиях оказались непростыми: команде инженеров при-
Вступление шлось внести физические изменения на заправочной станции, чтобы насосы могли взаимодействовать с нашим программным обеспечением. К моему удивлению, компания решила запланировать первый пуск в Доминиканской Республике. Я был рад не только увидеть, как реализуется мой проект, но и посетить такую прекрасную страну. Я был единственным разработчиком, который ездил в Доминиканскую Республику, поэтому я отвечал за исправление всех ошибок, обнаруженных на месте. Следил за установкой и за первым запуском программного обеспечения. Весь день наблюдал за системой, и все выглядело нормально. А вечером мы пошли праздновать. Пиво было холодным, и гордость переполняла меня. Я лег спать рано, чтобы утром успеть подготовиться к встрече с заинтересованными сторонами и обсуждению следующих шагов проекта. Но в 6 утра в моем номере зазвонил телефон. Это был владелец опытной АЗС: «По всей видимости, ночью произошел сбой программного обеспечения. Ночная смена не знала, что делать, а бензоколонки не выдавали ни капли топлива, поэтому за всю ночь станция ничего не смогла продать!» Я был потрясен. Как такое могло случиться? Я отправился прямо на станцию и начал отладку системы. Ошибка была вызвана непроверенной ситуацией, когда количество заправок превышало возможности системы. Мы знали, что используем встроенное устройство с ограниченным объемом памяти, поэтому приняли меры предосторожности. Но мы ни разу не проверили, что произойдет, если предел будет достигнут, – и это была наша ошибка! Все наши тесты проводились вручную: для имитации заправки мы подходили к симулятору, нажимали кнопку, имитирующую включение насоса, качающего топливо, ждали несколько секунд (считалось, что чем дольше мы ждали, тем больше литров топлива «купили»), а затем останавливали процесс заправки. Чтобы сымитировать 100 заправок, нужно было 100 раз нажать кнопку на симуляторе. Это довольно медленная и утомительная процедура. Поэтому во время разработки мы пробовали выполнить по две-три заправки кряду. Однажды мы протестировали механизм обработки исключений, но этого было недостаточно. Первая программная система, над которой я работал в роли ведущего разработчика, не проработала даже суток! Что я мог сделать, чтобы предотвратить ошибку? Пришло время изменить способ создания программного обеспечения, и это привело меня к тому, что я больше узнал о тестировании программного обеспечения. Конечно, в колледже нас познакомили с разными методами тестирования и рассказывали о важности тестирования программного обеспечения, но мы часто начинаем понимать ценность некоторых вещей, только когда они становятся нужны. Сегодня я не могу представить создание системы без набора автоматизированных тестов. Такой набор может сказать мне за считанные секунды, правильный или неправильный код я написал, поэтому я работаю намного продуктивнее. Эта книга – моя попытка помочь разработчикам избежать моих ошибок.