Аннотация: Лекция является второй из трех рассматривающих уровни процесса верификации. Тема данной лекции - процесс интеграционного тестирования, его задачи и цели. Рассматриваются организационные аспекты интеграционного тестирования - структурная и временная классификации методов интеграционного тестирования, планирование интеграционного тестирования. Цель данной лекции: дать представление о процессе интеграционного тестирования, его технической и организационной составляющих
Результатом тестирования и верификации отдельных модулей, составляющих программную систему, должно быть заключение о том, что эти модули являются внутренне непротиворечивыми и соответствуют требованиям. Однако отдельные модули редко функционируют сами по себе, поэтому следующая задача после тестирования отдельных модулей - тестирование корректности взаимодействия нескольких модулей, объединенных в единое целое. Такое тестирование называют интеграционным . Его цель - удостовериться в корректности совместной работы компонент системы.
Интеграционное тестирование называют еще тестированием архитектуры системы . С одной стороны, это название обусловлено тем, что интеграционные тесты включают в себя проверки всех возможных видов взаимодействий между программными модулями и элементами, которые определяются в архитектуре системы - таким образом, интеграционные тесты проверяют полноту взаимодействий в тестируемой реализации системы. С другой стороны, результаты выполнения интеграционных тестов - один из основных источников информации для процесса улучшения и уточнения архитектуры системы, межмодульных и межкомпонентных интерфейсов. Т.е., с этой точки зрения, интеграционные тесты проверяют корректность взаимодействия компонент системы.
Примером проверки корректности взаимодействия могут служить два модуля, один из которых накапливает сообщения протокола о принятых файлах, а второй выводит этот протокол на экран. В функциональных требованиях к системе записано, что сообщения должны выводиться в обратном хронологическом порядке. Однако, модуль хранения сообщений сохраняет их в прямом порядке, а модуль вывода использует стек для вывода в обратном порядке. Модульные тесты, затрагивающие каждый модуль по отдельности, не дадут здесь никакого эффекта - вполне реальна обратная ситуация, при которой сообщения хранятся в обратном порядке, а выводятся с использованием очереди. Обнаружить потенциальную проблему можно только проверив взаимодействие модулей при помощи интеграционных тестов. Ключевым моментом здесь является то, что в обратном хронологическом порядке сообщения выводит система в целом, т.е., проверив модуль вывода и обнаружив, что он выводит сообщения в прямом порядке, мы не сможем гарантировать, что мы обнаружили дефект.
В результате проведения интеграционного тестирования и устранения всех выявленных дефектов получается согласованная и целостная архитектура программной системы, т.е. можно считать, что интеграционное тестирование - это тестирование архитектуры и низкоуровневых функциональных требований.
Интеграционное тестирование , как правило, представляет собой итеративный процесс, при котором проверяется функциональной все более и более увеличивающейся в размерах совокупности модулей.
Как правило, интеграционное тестирование проводится уже по завершении модульного тестирования для всех интегрируемых модулей. Однако это далеко не всегда так. Существует несколько методов проведения интеграционного тестирования:
Все эти методики основываются на знаниях об архитектуре системы, которая часто изображается в виде структурных диаграмм или диаграмм вызовов функций . Каждый узел на такой диаграмме представляет собой программный модуль, а стрелки между ними представляют собой зависимость по вызовам между модулями. Основное различие методик интеграционного тестирования заключается в направлении движения по этим диаграммам и в широте охвата за одну итерацию.
Восходящее тестирование . При использовании этого метода подразумевается, что сначала тестируются все программные модули, входящие в состав системы и только затем они объединяются для интеграционного тестирования. При таком подходе значительно упрощается локализация ошибок: если модули протестированы по отдельности, то ошибка при их совместной работе есть проблема их интерфейса. При таком подходе область поиска проблем у тестировщика достаточно узка, и поэтому гораздо выше вероятность правильно идентифицировать дефект.
Рис.
20.1.
Однако, у восходящего метода тестирования есть существенный недостаток - необходимость в разработке драйвера и заглушек для модульного тестирования перед проведением интеграционного тестирования и необходимость в разработке драйвера и заглушек при интеграционном тестировании части модулей системы (Рис 20.1)
С одной стороны драйверы и заглушки - мощный инструмент тестирования, с другой - их разработка требует значительных ресурсов, особенно при изменении состава интегрируемых модулей, иначе говоря, может потребоваться один набор драйверов для модульного тестирования каждого модуля, отдельный драйвер и заглушки для тестирования интеграции двух модулей из набора, отдельный - для тестирования интеграции трех модулей и т.п. В первую очередь это связано с тем, что при интеграции модулей отпадает необходимость в некоторых заглушках, а также требуется изменение драйвера, которое поддерживает новые тесты, затрагивающие несколько модулей.
Монолитное тестирование предполагает, что отдельные компоненты системы серьезного тестирования не проходили. Основное преимущество данного метода - отсутствие необходимости в разработке тестового окружения, драйверов и заглушек. После разработки всех модулей выполняется их интеграция, затем система проверяется вся в целом. Этот подход не следует путать с системным тестированием, которому посвящена следующая лекция. Несмотря на то, что при монолитном тестировании проверятся работа всей системы в целом, основная задача этого тестирования - определить проблемы взаимодействия отдельных модулей системы. Задачей же системного тестирования является оценка качественных и количественных характеристик системы с точки зрения их приемлемости для конечного пользователя.
Монолитное тестирование имеет ряд серьезных недостатков.
Нисходящее тестирование предполагает, что процесс интеграционного тестирования движется следом за разработкой. Сначала тестируют только самый верхний управляющий уровень системы, без модулей более низкого уровня. Затем постепенно с более высокоуровневыми модулями интегрируются более низкоуровневые. В результате применения такого метода отпадает необходимость в драйверах (роль драйвера выполняет более высокоуровневый модуль системы), однако сохраняется нужда в заглушках (]. По своей сути такой подход не является новым типом интеграционного тестирования, просто меняется минимальный элемент, получаемый в результате интеграции. При интеграции модулей на процедурных языках программирования можно интегрировать любое количество модулей при условии разработки заглушек. При интеграции классов в кластеры существует достаточно нестрогое ограничение на законченность функциональности кластера. Однако, даже в случае объектно-ориентированных систем возможно интегрировать любое количество классов при помощи классов-заглушек.
Вне зависимости от применяемого метода интеграционного тестирования, необходимо учитывать степень покрытия интеграционными тестами функциональности системы. В работе был предложен способ оценки степени покрытия, основанный на управляющих вызовах между функциями и потоках данных. При такой оценке код всех модулей на структурной диаграмме системы должен быть выполнен (должны быть покрыты все узлы), все вызовы должны быть выполнены хотя бы единожды (должны быть покрыты все связи между узлами на структурной диаграмме), все последовательности вызовов должны быть выполнены хотя бы один раз (все пути на структурной диаграмме должны быть покрыты) .
Перевод:
Анна Радионова
Существует много видов ПО тестов. Практики BDD можно применять в любых аспектах тестирования, но BDD фреймворки используются далеко не во всех типах тестов. Поведенческие сценарии, по сути, являются функциональными тестами - они проверяют, что тестируемый продукт работает корректно. Для тестирования производительности могут использоваться инструменты, в то время как BDD фреймворки не предназначены для этих целей. Задача данной статьи, в основном, состоит в описании роли BDD автоматизации в Пирамиде Тестирования. Прочитайте статью BDD 101: Manual Testing для того, чтобы понимать как BDD применяется при ручном тестировании. (Всю информацию по BDD можно найти на странице Automation Panda BDD page)
Тем не менее, BDD практики могут применяться для юнит-тестов. Каждый юнит-тест должен быть направлен на основную составляющую: один вызов, единичная вариация, определенная комбинация ввода; на поведение .В дальнейшем при разработке спецификация поведения фичи четко отделяет юнит тесты от тестов более высокого уровня. Разработчик функционала также ответственен за написание юнит-тестов, в то время как за интеграционные и end-to-end тесты несет ответственность другой инженер. Спецификация поведения является, своего рода, джентльменским соглашением о том, что юнит-тесты будут являться отдельной сущностью.
Интеграционное и End-to-End тестирование
Тестовые BDD фреймворки наиболее ярко проявляют себя на интеграционных и end-to-end уровнях тестирования .
Поведенческие спецификации однозначно и лаконично описывают, на что именно ориентирован тест-кейс. Шаги могут быть написаны на интеграционном или end-to-end уровне. Тесты сервиса могут быть написаны с помощью поведенческих спецификаций, как, например в Karate . End-to-end тесты фактически представляют собой многошаговые интеграционные тесты. Обратите внимание на следующий пример, который, на первый взгляд, кажется базовой моделью взаимодействия с пользователем, но, по сути, является объемным end-to-end тестом:
Given
a user is logged into the social media site
When
the user writes a new post
Then
the user"s home feed displays the new post
And
the all friends" home feeds display the new post
Простая публикация в социальной сети включает процессы взаимодействия с интерфейсом, вызовы сервисов бекенда и внесение изменений в базу данных в режиме реального времени. Описан полный путь прохождения в системе. Автоматизированные шаги могут покрывать эти уровни явно или неявно, но они совершенно точно покрыты тестом.
Длительные End-to-End тесты
Термины часто понимаются разными людьми по-разному. Когда люди говорят “end-to-end тесты,” они подразумевают продолжительные последовательные тесты: тесты, которые покрывают различное поведение продукта одно за другим . Это утверждение заставляет содрогнуться приверженцев BDD, т.к это противоречит основному правилу BDD: один сценарий, одно поведение. Конечно, с помощью BDD фреймворков можно составлять длительные end-to-end тесты, но нужно хорошо подумать, стоит ли это делать и как именно.
Существует пять основных принципов написания длительных end-to-end сценариев в BDD:
Выберите подход, наиболее подходящий вашей команде.
Ни одна разработка программного обеспечения не обходится без тестирования исполняемого кода. Фактически, на это уходит половина всего времени, затраченного на разработку, и более половины стоимости проекта. Однако это неотъемлемая часть процесса создания новых приложений, программ, систем.
Один из способов контроля качества программного обеспечения - интеграционное тестирование, на вход которого подаются отдельно взятые модули, протестированные на предыдущем этапе.
В отличие от модульного варианта, в ходе которого выявляются ошибки, локализованные в каждой отдельно взятой функции или классе, интеграционное тестирование - это поиск дефектов, связанных с реализацией взаимодействия между отдельными частями создаваемого продукта. Интеграционное функциональное тестирование использует метод «белого ящика», то есть инженеру по качеству доступны и известны тексты каждого отдельного модуля, а также принципы взаимодействия между ними.
Монолитный метод означает, что все модули, которые в будущем будут подвергнуты интеграционному тестированию, собираются воедино одновременно. Почти наверняка возникают ситуации, когда часть тестируемого комплекса еще не готова.
В таком случае ее заменяют дополнительно разработанными "заглушками", или драйверами.
Наряду с монолитным методом выделяют инкрементальный (его еще называют пошаговым), так как объем тестируемого кода наращивается постепенно, давая локализовать участки с дефектами во взаимосвязях между отдельными частями.
Инкрементальный метод включает в себя два способа добавления модулей:
Главный недостаток монолитного вида сборки - большое количество времени и трудозатрат уходит на имитацию недостающих частей тестируемого комплекса. Казалось бы, заглушки - достаточно удобный инструмент тестирования, однако возникают ситуации, когда в процессе приходится создавать заново имитационные части программы. Например, в случае изменения состава тестируемых модулей. Кроме того, эффективность поиска дефектов не так высока, когда работа ведется не с реальным продуктом, а лишь с фиктивным компонентом. Этот же недостаток сопровождает и инкрементальное тестирование с восходящим способом сборки.
В то же время одним из недостатков пошагового метода является необходимость организации и создания среды для исполнения модулей в заданной последовательности. А также практически невозможна параллельная разработка верхних и нижних уровней.
Конечно же, оба способа сборки, монолитный и инкрементальный, имеют не только недостатки, но и достоинства. В первом случае появляются отличные возможности для параллельной разработки всех классов и функций, участвующих в тестировании, как на начальном этапе, так и после доработки. Пошаговый же метод менее трудозатратен: модули присоединяются постепенно, и так же постепенно обнаруживаются ошибки и дефекты. Это, как известно, позволяет сократить время на поиск таковых.
На этом этапе проводится колоссальная работа проверки взаимосвязей всех уровней, без чего, конечно же, невозможно дальнейшее тестирование.
Интеграционное тестирование программного обеспечения имеет ряд преимуществ:
Интеграционное тестирование завершено, однако это еще не все. Найденные ошибки фиксируются и отправляются разработчику для исправления, после чего процесс начинается заново.
Во-первых, необходимо проверить, были ли устранены выявленные дефекты. Во-вторых, во время изменения исходного кода могли возникнуть новые ошибки в работе программы и взаимодействии со сторонним ПО.
Хотя в настоящее время и существует большое количество методов контроля качества, по-прежнему немаловажную роль играет интеграционное тестирование. Пример такого вида проверки может наглядно продемонстрировать «узкие» места при разработке программного обеспечения и документации.
В зависимости от объема исходного комплекса данных и предметной области разработки может вставать проблема времени тестирования и трудоемкости мероприятия в целом.
Для наиболее эффективной проверки разработки необходимо использовать огромное количество входных данных и условий, с чем "вручную" справиться невозможно. Для решения этой проблемы используется автоматизация тестирования. Как и другие виды, интеграционное тестирование также может быть автоматизировано. Это позволит сократить время разработки в целом, а также повысит эффективность процесса обнаружения ошибок.
Однако автоматизация тестирования не может полностью заменить труд инженера по качеству, а лишь дополнить его.
Итак, интеграционное тестирование - это неотъемлемая часть разработки любого программного обеспечения и один из этапов всего процесса проверки качества продукта. Как и любой метод, он имеет ряд достоинств и недостатков, но без его применения становится невозможной качественная разработка ПО.
Аннотация: Лекция является второй из трех рассматривающих уровни процесса верификации. Тема данной лекции - процесс интеграционного тестирования, его задачи и цели. Рассматриваются организационные аспекты интеграционного тестирования - структурная и временная классификации методов интеграционного тестирования, планирование интеграционного тестирования. Цель данной лекции: дать представление о процессе интеграционного тестирования, его технической и организационной составляющих
Результатом тестирования и верификации отдельных модулей, составляющих программную систему, должно быть заключение о том, что эти модули являются внутренне непротиворечивыми и соответствуют требованиям. Однако отдельные модули редко функционируют сами по себе, поэтому следующая задача после тестирования отдельных модулей - тестирование корректности взаимодействия нескольких модулей, объединенных в единое целое. Такое тестирование называют интеграционным . Его цель - удостовериться в корректности совместной работы компонент системы.
Интеграционное тестирование называют еще тестированием архитектуры системы . С одной стороны, это название обусловлено тем, что интеграционные тесты включают в себя проверки всех возможных видов взаимодействий между программными модулями и элементами, которые определяются в архитектуре системы - таким образом, интеграционные тесты проверяют полноту взаимодействий в тестируемой реализации системы. С другой стороны, результаты выполнения интеграционных тестов - один из основных источников информации для процесса улучшения и уточнения архитектуры системы, межмодульных и межкомпонентных интерфейсов. Т.е., с этой точки зрения, интеграционные тесты проверяют корректность взаимодействия компонент системы.
Примером проверки корректности взаимодействия могут служить два модуля, один из которых накапливает сообщения протокола о принятых файлах, а второй выводит этот протокол на экран. В функциональных требованиях к системе записано, что сообщения должны выводиться в обратном хронологическом порядке. Однако, модуль хранения сообщений сохраняет их в прямом порядке, а модуль вывода использует стек для вывода в обратном порядке. Модульные тесты, затрагивающие каждый модуль по отдельности, не дадут здесь никакого эффекта - вполне реальна обратная ситуация, при которой сообщения хранятся в обратном порядке, а выводятся с использованием очереди. Обнаружить потенциальную проблему можно только проверив взаимодействие модулей при помощи интеграционных тестов. Ключевым моментом здесь является то, что в обратном хронологическом порядке сообщения выводит система в целом, т.е., проверив модуль вывода и обнаружив, что он выводит сообщения в прямом порядке, мы не сможем гарантировать, что мы обнаружили дефект.
В результате проведения интеграционного тестирования и устранения всех выявленных дефектов получается согласованная и целостная архитектура программной системы, т.е. можно считать, что интеграционное тестирование - это тестирование архитектуры и низкоуровневых функциональных требований.
Интеграционное тестирование , как правило, представляет собой итеративный процесс, при котором проверяется функциональной все более и более увеличивающейся в размерах совокупности модулей.
Как правило, интеграционное тестирование проводится уже по завершении модульного тестирования для всех интегрируемых модулей. Однако это далеко не всегда так. Существует несколько методов проведения интеграционного тестирования:
Все эти методики основываются на знаниях об архитектуре системы, которая часто изображается в виде структурных диаграмм или диаграмм вызовов функций . Каждый узел на такой диаграмме представляет собой программный модуль, а стрелки между ними представляют собой зависимость по вызовам между модулями. Основное различие методик интеграционного тестирования заключается в направлении движения по этим диаграммам и в широте охвата за одну итерацию.
Восходящее тестирование . При использовании этого метода подразумевается, что сначала тестируются все программные модули, входящие в состав системы и только затем они объединяются для интеграционного тестирования. При таком подходе значительно упрощается локализация ошибок: если модули протестированы по отдельности, то ошибка при их совместной работе есть проблема их интерфейса. При таком подходе область поиска проблем у тестировщика достаточно узка, и поэтому гораздо выше вероятность правильно идентифицировать дефект.
Рис.
20.1.
Однако, у восходящего метода тестирования есть существенный недостаток - необходимость в разработке драйвера и заглушек для модульного тестирования перед проведением интеграционного тестирования и необходимость в разработке драйвера и заглушек при интеграционном тестировании части модулей системы (Рис 20.1)
С одной стороны драйверы и заглушки - мощный инструмент тестирования, с другой - их разработка требует значительных ресурсов, особенно при изменении состава интегрируемых модулей, иначе говоря, может потребоваться один набор драйверов для модульного тестирования каждого модуля, отдельный драйвер и заглушки для тестирования интеграции двух модулей из набора, отдельный - для тестирования интеграции трех модулей и т.п. В первую очередь это связано с тем, что при интеграции модулей отпадает необходимость в некоторых заглушках, а также требуется изменение драйвера, которое поддерживает новые тесты, затрагивающие несколько модулей.
Монолитное тестирование предполагает, что отдельные компоненты системы серьезного тестирования не проходили. Основное преимущество данного метода - отсутствие необходимости в разработке тестового окружения, драйверов и заглушек. После разработки всех модулей выполняется их интеграция, затем система проверяется вся в целом. Этот подход не следует путать с системным тестированием, которому посвящена следующая лекция. Несмотря на то, что при монолитном тестировании проверятся работа всей системы в целом, основная задача этого тестирования - определить проблемы взаимодействия отдельных модулей системы. Задачей же системного тестирования является оценка качественных и количественных характеристик системы с точки зрения их приемлемости для конечного пользователя.
Монолитное тестирование имеет ряд серьезных недостатков.
Нисходящее тестирование предполагает, что процесс интеграционного тестирования движется следом за разработкой. Сначала тестируют только самый верхний управляющий уровень системы, без модулей более низкого уровня. Затем постепенно с более высокоуровневыми модулями интегрируются более низкоуровневые. В результате применения такого метода отпадает необходимость в драйверах (роль драйвера выполняет более высокоуровневый модуль системы), однако сохраняется нужда в заглушках (Рис 20.2).
У разных специалистов в области тестирования разные мнения по поводу того, какой из методов более удобен при реальном тестировании программных систем. Йордан доказывает, что нисходящее тестирование наиболее приемлемо в реальных ситуациях , а Майерс полагает, что каждый из подходов имеет свои достоинства и недостатки, но в целом восходящий метод лучше .
В литературе часто упоминается метод интеграционного тестирования объектно-ориентированных программных систем, который основан на выделении кластеров классов, имеющих вместе некоторую замкнутую и законченную функциональность . По своей сути такой подход не является новым типом интеграционного тестирования, просто меняется минимальный элемент, получаемый в результате интеграции. При интеграции модулей на процедурных языках программирования можно интегрировать любое количество модулей при условии разработки заглушек. При интеграции классов в кластеры существует достаточно нестрогое ограничение на законченность функциональности кластера. Однако, даже в случае объектно-ориентированных систем возможно интегрировать любое количество классов при помощи классов-заглушек.
Вне зависимости от применяемого метода интеграционного тестирования, необходимо учитывать степень покрытия интеграционными тестами функциональности системы. В работе был предложен способ оценки степени покрытия, основанный на управляющих вызовах между функциями и потоках данных. При такой оценке код всех модулей на структурной диаграмме системы должен быть выполнен (должны быть покрыты все узлы), все вызовы должны быть выполнены хотя бы единожды (должны быть покрыты все связи между узлами на структурной диаграмме), все последовательности вызовов должны быть выполнены хотя бы один раз (все пути на структурной диаграмме должны быть покрыты) .
Лекция является второй из трех рассматривающих уровни процесса верификации. Тема данной лекции - процесс интеграционного тестирования, его задачи и цели. Рассматриваются организационные аспекты интеграционного тестирования - структурная и временная классификации методов интеграционного тестирования, планирование интеграционного тестирования. Цель данной лекции: дать представление о процессе интеграционного тестирования, его технической и организационной составляющих
Результатом тестирования и верификации отдельных модулей, составляющих программную систему, должно быть заключение о том, что эти модули являются внутренне непротиворечивыми и соответствуют требованиям. Однако отдельные модули редко функционируют сами по себе, поэтому следующая задача после тестирования отдельных модулей - тестирование корректности взаимодействия нескольких модулей, объединенных в единое целое. Такое тестирование называют интеграционным. Его цель удостовериться в корректности совместной работы компонент системы.
Интеграционное тестирование называют еще тестированием архитектуры системы. С одной стороны, это название обусловлено тем, что интеграционные тесты включают в себя проверки всех возможных видов взаимодействий между программными модулями и элементами, которые определяются в архитектуре системы - таким образом, интеграционные тесты проверяют полноту взаимодействий в тестируемой реализации системы. С другой стороны, результаты выполнения интеграционных тестов - один из основных источников информации для процесса улучшения и уточнения архитектуры системы, межмодульных и межкомпонентных интерфейсов. Т.е., с этой точки зрения, интеграционные тесты проверяют корректность взаимодействия компонент системы.
Примером проверки корректности взаимодействия могут служить два модуля, один из которых накапливает сообщения протокола о принятых
Синицын С.В., Налютин Н.Ю. Верификация программного обеспечения
файлах, а второй выводит этот протокол на экран. В функциональных требованиях к системе записано, что сообщения должны выводиться в обратном хронологическом порядке. Однако, модуль хранения сообщений сохраняет их в прямом порядке, а модуль вывода использует стек для вывода в обратном порядке. Модульные тесты, затрагивающие каждый модуль по отдельности, не дадут здесь никакого эффекта - вполне реальна обратная ситуация, при которой сообщения хранятся в обратном порядке, а выводятся с использованием очереди. Обнаружить потенциальную проблему можно только проверив взаимодействие модулей при помощи интеграционных тестов. Ключевым моментом здесь является то, что в обратном хронологическом порядке сообщения выводит система в целом, т.е., проверив модуль вывода и обнаружив, что он выводит сообщения в прямом порядке, мы не сможем гарантировать, что мы обнаружили дефект.
В результате проведения интеграционного тестирования и устранения всех выявленных дефектов получается согласованная и целостная архитектура программной системы, т.е. можно считать, что интеграционное тестирование - это тестирование архитектуры и низкоуровневых функциональных требований.
Интеграционное тестирование, как правило, представляет собой итеративный процесс, при котором проверяется функциональной все более и более увеличивающейся в размерах совокупности модулей.