Существуют различные способы тестирования системы, каждый со своими достоинствами и недостатками. Сейчас мы познакомимся с тремя различными видами тестирования, а более подробно рассмотрим эти три парадигмы в следующих главах.
Возможно, самым легким видом тестирования для понимания является тестирование черного ящика. В этом случае у тестировщика нет знаний о том, как работает система изнутри, и взаимодействовать с ней он может как обычный пользователь. Другими словами, тестировщик не знает, какая используется база данных, какие существуют классы или даже на каком языке написана программа. Вместо этого тестирование проводится так, как будто тестировщик является обычным пользователем программы.
Рассмотрим приложение для работы с электронной почтой. Взявший на тестирование это приложение тестировщик черного ящика будет проверять, может ли оно принимать и отправлять почту, проверять грамотность слов в письме, сохранять файлы и т. п. Этот тестировщик не станет проверять, что был вызван какой-то метод некоего класса, что объекты загружены в память или как осуществляются вызовы определенных функций. Если, например, тестировщик хочет убедиться, что письма могут быть правильно отсортированы по именам отправителей, в соответствующем тесте черного ящика нужно нажать кнопку или выбрать в меню команду Сортировать по именам отправителей. Тестировщик черного ящика может не знать, что программа написана на Java или Haskell, использовалась ли сортировка слиянием, быстрая сортировка или пузырьковая сортировка. Хотя тестировщика будут беспокоить результаты, полученные благодаря выбранным методам. Тестировщик черного ящика фокусируется на том, работает ли тестируемая система, как должна, с точки зрения пользователя, и нет ли в ней дефектов, с которыми может столкнуться пользователь.
Особенности системы, такие как вид примененного алгоритма или тип выбранной схемы использования памяти, могут предполагаться тестировщиком черного ящика, но он в первую очередь должен сфокусироваться на результатах работающей системы. Например, тестировщик черного ящика может обратить внимание, что система замедляется, когда начинает сортировать тысячи писем в почтовом ящике пользователя. Тестировщик черного ящика может предположить, что для сортировки использовался алгоритм типа O(n2 ), и отметить это как дефект. Тем не менее он не будет знать, какой алгоритм применялся или какие особенности программного кода вызвали замедление.
По знанию работы тестируемой системы тестирование белого ящика является противоположностью тестированию черного ящика. В тестировании белого ящика у тестировщика есть глубокое представление об исходном коде, и он напрямую тестирует этот код. Тестировщик белого ящика может протестировать отдельные функции кода, очень часто изучая особенности работы системы гораздо более детально, чем в тестах черного ящика.
Продолжая рассматривать пример с почтовой программой, обратим внимание, что тесты белого ящика могут проверять функцию сортировки (EmailEntry[] emails), подавая на вход различные значения и изучая то, что эта функция возвращает или делает. Тестировщиков белого ящика будет беспокоить, что именно произойдет, если были переданы массив нулевой длины или ссылка на нулевой элемент, в то время как тестировщики черного ящика будут озабочены только тем, что случится, если они попытаются отсортировать пустой список сообщений в самом приложении. Тестировщики белого ящика обращаются с кодом как с кодом — проверяют, что возвращаемое значение функции корректное, объекты инициализированы правильно и т. д. — вместо того чтобы смотреть на систему с точки зрения пользователя.
Тестирование серого ящика, как подразумевает его название, является гибридом тестирования белого ящика и тестирования черного ящика. Тестирование серого ящика включает обращение тестировщика к системе в роли обычного пользователя (как в тестировании черного ящика), но со знаниями программного кода и устройства системы (как в тестировании белого ящика). Обладая этими знаниями, тестировщик серого ящика может создавать более глубокие тесты черного ящика.
Давайте предположим, что наш тестировщик серого ящика собирается протестировать функцию сортировки в почтовом приложении. Изучая код, тестировщик понимает, что система использует метод сортировки вставками. Известно, что у сортировки вставками наихудшая производительность, когда необходимо отсортировать данные, уже отсортированные в обратном порядке. Таким образом, тестировщик серого ящика может добавить тест, который проверяет, что система способна отсортировать список электронных писем, которые расположены в обратном порядке. Другой пример — тестировщик может обратить внимание, что в функции поиска нет обработки пустых данных, и проверить, приведет ли простое нажатие клавиши без ввода данных к разыменованию нулевого указателя в программном коде, к поиску "" и отображению всех писем в результатах поиска, или к другому непредсказуемому поведению.