Способ тестирования белого ящика

Тестирование белого ящика и черного ящика

В зависимости от доступа разработчика тестов к исходному коду тестируемой программы различают «тестирование (по стратегии) белого ящика» и «тестирование (по стратегии) чёрного ящика».
При тестировании белого ящика (также говорят — прозрачного ящика), разработчик теста имеет доступ к исходному коду программ и может писать код, который связан с библиотеками тестируемого программного обеспечения. Это типично для модульного тестирования, при котором тестируются только отдельные части системы. Оно обеспечивает то, что компоненты конструкции — работоспособны и устойчивы, до определённой степени. При тестировании белого ящика используются метрики покрытия
кода или мутационное тестирование.При тестировании чёрного ящика, тестировщик имеет доступ к программе только через те же интерфейсы, что и заказчик или пользователь, либо через внешние интерфейсы, позволяющие другому компьютеру либо другому процессу подключиться к системе для тестирования. Например, тестирующий модуль может виртуально нажимать клавиши или кнопки мыши в тестируемой программе с помощью механизма взаимодействия процессов, с уверенностью в том, все ли идёт правильно, что эти события вызывают тот же отклик, что и реальные нажатия клавиш и кнопок мыши.

Как правило, тестирование чёрного ящика ведётся с использованием спецификаций или иных документов, описывающих требования к системе. Обычно в данном виде тестирования критерий покрытия складывается из покрытия структуры входных данных, покрытия требований и покрытия модели (в тестировании на основе моделей).
При тестировании серого ящика разработчик теста имеет доступ к исходному коду, но при непосредственном выполнении тестов доступ к коду, как правило, не требуется.

Если «альфа-» и «бета-тестирование» относятся к стадиям до выпуска продукта (а также, неявно, к объёму тестирующего сообщества и ограничениям на методы тестирования), тестирование «белого ящика» и «чёрного ящика» имеет отношение к способам, которыми тестировщик достигает цели.
Бета-тестирование в целом ограничено техникой чёрного ящика (хотя постоянная часть тестировщиков обычно продолжает тестирование белого ящика параллельно бета-тестированию). Таким образом, термин «бета-тестирование» может указывать на состояние программы (ближе к выпуску чем «альфа»), или может указывать на некоторую группу тестировщиков и процесс, выполняемый этой группой. То есть, тестировщик может продолжать работу по тестированию белого ящика, хотя программа уже «бета-стадии», но в этом случае он не является частью «бета-тестирования».

Тестирование чёрного ящика или поведенческое тестирование

Тестирование чёрного ящика или поведенческое тестирование — стратегия (метод) тестирования функционального поведения объекта (программы, системы) с точки зрения внешнего мира, при котором не используется знание о внутреннем устройстве тестируемого объекта. Под стратегией понимаются систематические методы отбора и создания тестов для тестового набора. Стратегия поведенческого теста исходит из технических требований и их спецификаций.

Тестирование по стратегии белого ящика

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

Техника Белого ящика включает в себя следующие методы тестирования:
1. покрытие решений
2. покрытие условий
3. покрытие решений и условий
4. комбинаторное покрытие условий

Источник

Тестирование глазами разработчика: инструменты, мифы, ситуации

Евгений Сафронов, Senior Developer, DataArt

«Тестирование можно использовать для того, чтобы доказать наличие ошибок в программе, и никогда — для того чтобы доказать их отсутствие!»
Эдсгер Дейкстра

Тестирование — это прикладная, стандартизированная, инженерная практика, которая применима в большинстве отраслей человеческой жизни. Тестирование, как философия, метрика или практика, существует намного дольше, чем программирование. К примеру, мы выковали меч. Чтобы проверить достаточно ли острым он получился, его испытывают. В некоторые эпохи даже на живом человеке, скажем, рабе.

Читайте также:  Жженые квасцы от пота способ применения

Тестирование — это проверка работоспособности программы, предмета или любой промышленной разработки. Как и в любом деле, здесь есть свои тонкости и своя философия. Она, наверное, ближе тестировщикам, которые на произведенные нами вещи смотрят деструктивно — они с самого начала думают о том, как сломать предложенный разработчиками продукт. Это не очень типично для пользователей, которые более предсказуемы и обычно находят ошибки, случайно пытаясь сделать с нашей программой что-то нетипичное. У разработчиков подход к программам в принципе другой, но мы должны помнить: тестировщики должны ломать то, что мы создали — это их хлеб.

Почему тестировать программы так важно?

Разработчики не мыслят через тестирование, мы мыслим созидательно — и это может быть источником проблем. Когда нас просят написать программу, мы прежде всего думаем над концептами, структурами данных, их описанием и взаимодействием. В результате мы представляем решение — готовое, пусть и переполненное багами. Обычно мы слабо представляем, что будет, если изменятся входные данные, если пользователь будет в большом количестве совершать нетипичные операции.

При этом практика показывает, самые дорогостоящие ошибки случаются в результате небольших изменений. Потому что, если вы плохо написали кусок кода, более опытный коллега попросит вас его переделать. Обладая опытом, вы сами будете замечать неудачные фрагменты практически сразу. Но когда ошибки минимальны — отдельный символ, точка, знак финансовой операции, ошибка округления — найти их очень сложно, причем на любом этапе.


Рис. 1. Форма авторизации и количество вариантов ее заполнения.

Давайте посмотрим, почему возникает такая сложность в тестировании. На рисунке мы видим простую форму из трех полей. В первых двух полях можно ввести от 1 до 255 букв, в третьем от 1 до 20 символов. Можно также оставить строки пустыми. Внизу мы видим число возможных комбинаций, заметно превышающее количество элементарных частиц во вселенной. Я думаю, это убедительное доказательство того, что проверить все возможные кейсы нереально. Да и пытаться это сделать, наверное, нецелесообразно.

Типы ошибок в проектах


Рис. 2. Схема распределения ошибок по типам, согласно данным книги Стива Макконнелла «Совершенный код».

Примерно 25% общего объема приходится на структурные ошибки. Они возникают еще на этапе проектирования, когда вы создаете структуры данных и пишете реализации манипуляций с ними, то есть создаете некий «клей», скрепляющий эти структуры. Это огромный пласт фундаментальных ошибок.

Далее идут ошибки данных, связанные с реализацией функциональности и т. д. Интересно, что архитектура находится на последнем месте. Это можно объяснить тем, что, создав неправильную архитектуру, очень сложно в принципе выпустить конечный продукт.


Рис. 3. Распределение ошибок по стадиям разработки. Схема Стива Макконнелла.

На этап конструирования и проектирования приходится основной пласт ошибок и дефектов. Здесь работает известное правило Парето: 80 % дефектов локализованы лишь в 20 % вашего кода. Как правило, это какие-то корнер-кейсы. Если вы пишете операции с математической, например, с финансовой логикой, очень много ошибок может заключаться в пределах пограничных значений, при округлении чисел и т. п. Большинство ваших кейсов будут работать, но основная часть дефектов будет локализована в небольшом участке кода.

Вне зависимости от того, применяете ли вы ручное или юнит-тестирование, нельзя утверждать, что покрыв тестами 50 % кода, вам удалось предотвратить 50 % возможных дефектов. Если вы написали 100 юнит-тестов нельзя сказать, что итоговое качество вашего продукта повысилось, например, вдвое. Потому что разработчик, который не мыслит через призму тестирования, проверяет самые легкие кейсы. Нужные формы заполняются стандартными именем, фамилией и логином — разработчик идет дальше. Он с большой долей вероятности не станет проверять случаи, когда одно из полей остается пустым, или когда в него действительно вбили имя длиной в 255 знаков. Не будет он экспериментировать с нестандартными символами, комбинациями строчных и заглавных букв.

Тестирование — самая популярная методика управления качеством. Если вспомнить наш пример с мечом, то прежде чем использовать его в реальном бою, вы точно попросите испытывать его подольше. Еще лучше если на этапе производства вы договоритесь с кузнецом, чтобы тот испытал еще и металл, из которого он будет ковать оружие. Чтобы повысить качество программы, нам, соответственно, желательно увеличить объем тестирования и при этом использовать best practices. Пропорционально усилиям будет возрастать и качество нашего продукта.

Читайте также:  Фронтальный способ организации детей что это

Тестировать продукт могут все: разработчик, тестировщик, менеджер, заказчик. Иногда в небольших проектах роль тестировщика может выполнять менеджер или разработчик. Но все же все четыре роли здесь очень важны — каждый участник процессе смотрит на объект со своей точки зрения. Разработчик — через призму того, как работает код. У него с самого начала есть большая часть информации о том, как сломать интерфейс. Для тестировщика найти ошибки и сломать продукт — прямая задача. Заказчик смотрит на тесты совершенно иначе: ему интересно, как написать меньше тестов и заплатить меньше денег, все равно получив в итоге качественный продукт. Но самая интересная роль у менеджера, который обычно может опираться на случаи из собственной практики. Впрочем, как правило, он служит мостом между разработчиками, тестировщиками и заказчиком, а его основная задача сводится к презентации продукта. Но именно менеджер отвечает за качество продукта на выходе.

Тестирование черного и белого ящиков

Классификация тестирования в виде анализа белого, серого и черного ящиков, интересна нам тем, что разработчик смотрит на собственный код как на белый ящик. А тестировщик и заказчик рассматривают программу как черный ящик — они до конца не понимают, как именно работает программа, знают только, какие фичи важны и должны работать обязательно.

Баг на сайте интернет-магазина, из-за которого какой-то товар не попадает в корзину, для разработчика — минорная проблема. Достаточно что-то закоммитить и раскоммитить, поменять переменные в одном месте — и все отлично заработает. Для тестировщика и тем более заказчика такой баг оказывается критическим, поскольку не позволяет клиенту купить нужный товар.

Но самый интересный ящик — серый. С ним работают те, кого я называю умными тестировщиамки, которые глубоко вникают в код и то, как работает продукт. Их интересует, как происходит деплой и коммуникация с базами данных.

Какие тесты пишут разработчики?

  • Модульные тесты. Большая часть разработчиков использует ручное тестирование. Если вы что-то сделали, прежде всего, нужно убедиться, что это действительно работает, проверить входные данные и переменные и получить какой-то фидбек. Модульные тесты — вид юнит-тестирования, то есть нам нужно проверять, правильно ли работает каждый кусочек кода.
  • Функциональные тесты. С их помощью мы проверяем отдельные фичи, связки наших модулей и так далее
  • Интеграционные тесты. Они позволяют проверить, могут ли два наших модуля работать вместе.
  • End-to-end тестирование. Проверка какой-либо фичи с точки зрения клиента и от начала до конца. Допустим, мы не можем отвечать за работу курьерской службы. Но можете убедиться в том, что клиент может выбрать и оплатить продукт в написанном вами интернет-магазине. И в том, что товар будет готов к отправке.


Рис. 4. Пирамида модульного тестирования.

Основа пирамиды — юнит-тестирование — желательно, чтобы юнит-тестов в проекте было много. Далее следуют интеграционное тестирование наших модулей, Acceptance Tests и непосредственное UI-тестирование конкретных фич.

F.I.R.S.T

F.I.R.S.T. — методология описания требованиий, которым должны отвечать тесты. Прежде всего, модульные, но в принципе эти характеристики можно экстраполировать и на автоматические тесты. Ее создатель — известный дядюшка Боб — автор многих практик программирования.

  • Быстрота (Fast). Тесты должны быть быстрыми, медленные тесты никто не станет запускать. На их проведение не хватит времени даже у команды из 30 тестировщиков.
  • Независимость (Independent). Тесты должны быть независимы: ни один элемент не может зависеть от исполнения предыдущего.
  • Повторяемость (Repeatable). Вы должны иметь возможность запустить любой тест в любой момент, и его поведение должно быть предсказуемо.
  • Очевидность (Self-Validating). Поведение теста должно быть очевидно, прежде всего для тех, кто создает программу.
  • Своевременность (Timely). Тесты должны быть написаны тогда, когда они действительно нужны.
Читайте также:  Фрезерный станок по дереву для домашней мастерской ручной способ работы


Рис. 5. Схема TDD-процесса.

Две базовых методологии юнит-тестирования — похожие концепты TDD и BDD. BDD-подход основывается на TDD и призван устранить небольшие недостатки, которые присутствуют в TDD. Синтаксис BDD-тестов в большей степени ориентирован на бизнес и понятен заказчику и вообще технически менее подкованному человеку. TDD — о том, как делать вещи правильно. BDD — о том, как делать правильные вещи.

Как выглядит TDD-процесс?

Первым делом вы пишете тест для кода, который еще не написан. Соответственно, видите, что он не работает. Чтобы он заработал, код ещё нужно написать. Потом вы все-таки пишете код, запускаете тест и убеждаетесь в том, что тест работает. Далее вы модифицируете свой тест (уточняете требования, добавлете проверку граничных условий и т. п.). После этого ваш тест перестает работать, и вы снова приходите к необходимости модифицировать ваш код. Этот процесс зациклен до того момента, пока ваш тест не будет совершенно четко отвечать конечным критериям и соответствовать задачам, которые перед вами стоят. Предположим, если вы решаете квадратное уравнение, ваша задача — написать функцию, которая находит корни квадратного уравнения. Предположим, вы написали тест, и он хорошо работает на базе действительных чисел. Но если пользователь захочет найти комплексное решение, то ничего не получится, тест завалится и потребует модификации. Поэтому эта схема должна быть в крови у разработчиков: нужно действовать по ней, пока ваша фича не будет соответствовать всем требованиям.

Как выглядит TDD?

Пример написан на JavaScript, но думаю, в синтаксическом плане он будет примерно также выглядеть для PHP или Java. Все достаточно очевидно. Открыв тест, можно легко сказать, какие моменты протестированы не были. Можно легко и быстро что-то добавить. И таким образом проверить, корректно ли работает ли ваша функция.

BDD очень похож на TDD, но отличается тем, что формулировки в описании немного лучше адаптированы для людей, менее плотно связанных с разработкой: менеджеров или бизнес-аналитиков.

Особенности модульного тестирования

  • Из-за своей атомарности и простоты, модульное тестирование позволяет разработчику писать много тестов, причем достаточно быстро.
  • Участки вашего кода (mocks, stubs, spies) приходится изолировать. Модульность предполагает тестирование отдельных небольших участков, соответственно, если эти участки связаны с другими, то их нужно тестировать отдельно.
  • Важный момент — вы можете написать тест только тогда, когда понимаете, как должен работать код (тестирование белого ящика). Во многих языках есть инструменты для юнит-тестирования, но в JavaScript их просто колоссальное количество. В основном они заточены на тестирование описания BDD-стиля. Хотя есть например, QUnit и другие сервисы, созданные на раннем этапе развития JS и jQuery, тяготеющие к TDD-подходу. Каждый может выбрать то, что ему больше нравится, в англоязычных комьюнити распространены Karma и Jasmine. Мне больше нравится Mocha, очень производительная штука, эффективная непосредственно на этапе разработки.


Рис. 6. Инструменты юнит-тестирования.

QUnit — библиотека от разработчиков jQuery, позволяющая писать юнит-тесты в TDD-стиле, с механизмом assert. Вы пишете qunit.test, название теста, и что вы хотите протестировать.Затем запускаете его в отдельном файле, который должен видеть ваш код, и можете убедиться в том, что код работает.

Mocha — фреймворк для тестирования, позволяющий писать тесты в TDD и BDD-формате. Как правило, он используется совместно с другими инструментами для того, чтобы полностью реализовать TDD-подход в работе. То есть он позволяет запускать и описывать тесты в нужном формате, а к примеру за обработку проверок утверждений (asserts) отвечает другая библиотека (чаще всего Chai).

Sinon— инструмент для создания Mocks, stubs и spies, который очень часто используется в современных успешных проектах. Он содержит набор функций и модулей, которые здорово помогают и решают большое количество типичных проблем, которые возникают у разработчика во время создания юнит-тестов.

Jasmine — популярный BDD-библиотека, которая фактически стала стандартом в экосистеме самого распространенного Javascript-фреймворка Angular.

Источник

Оцените статью
Разные способы