Лекции. Тестирование ПО (all in one) (1186159), страница 12
Текст из файла (страница 12)
Регрессионное тестирование используется на этапесопровождения, после внесения изменений и исправлений в систему, при выпуске ееочередной версии.Литература[1][2][3][4]IEEE Guide to Software Engineering Body of Knowledge, SWEBOK, 2004.IEEE 754-1985. IEEE Standard for Binary Floating-Point Arithmetic.
NY: IEEE, 1985.D. Goldberg. What Every Computer Scientist Should Know about Floating-Point Arithmetic.ACM Computing Surveys, 23(1):5-48, 1991.В. В. Кулямин. Технологии программирования. Компонентный подход. М: Интернетуниверситет информационных технологий — БИНОМ. Лаборатория знаний, 2007.http://www.ispras.ru/~kuliamin/lectures-sdt/Lecture01.pdf.Тестирование на основе моделейВ. В. КуляминЛекция 3.
Критерии полноты тестированияНабор тестов, используемый при тестировании, всегда конечен и, более того, ограниченсоображениями экономической эффективности распределения ресурсов между разнымивидами деятельности при разработке ПО. Поэтому крайне важно строить его так, чтобыиспользуемые тесты проверяли как можно больше разных аспектов функциональностисистемы в как можно большем разнообразии ситуаций. Чтобы систематическим образомперебирать существенно отличающиеся друг от друга ситуации, используют критерииполноты тестирования или критерии адекватности тестирования [1,2]. Тестовый набор,удовлетворяющий заданному критерию полноты, называют полным по этому критерию.Чаще всего для определения критерия полноты некоторые из возможных тестовыхситуаций рассматривают как эквивалентные и определяют количество классовнеэквивалентных тестовых ситуаций, встретившихся или «покрытых» во времятестирования.
Такие критерии полноты называются критериями тестового покрытия [1-3].При этом определяется и числовая метрика тестового покрытия — доля покрытых классовситуаций среди всех возможных. Критерий полноты может использовать различныезначения метрики, например, он может требовать, чтобы полный тестовый набор всегдапокрывал 100% выделенных классов ситуаций, или же считать достаточным покрытие 85%классов ситуаций. Поскольку для одной метрики покрытия можно определить многокритериев полноты, далее речь, чаще всего, идет о различных метриках тестового покрытия.Полноту тестирования можно определять по-разному, но в основе любого критерияполноты лежит представление о возможных ошибках в тестируемой системе. Различныеспособы классификации ситуаций, отражающие их разнообразие с точки зрениятестирования, перечислены ниже.
Каждый из них и любое их подмножество совместно могутиспользоваться для определения метрик тестового покрытия. Классифицировать ситуацииможно следующим образом.•На основе структурных элементов тестируемой системы, которые выполняются илизадействуются в ходе тестирования.•На основе структуры входных данных, используемых во время тестирования.•На основе элементов требований, проверяемых при выполнении тестов.•На основе явно сформулированных предположений об ошибках, выявление которыхдолжны обеспечить тесты.•На основе произвольных моделей устройства или функционирования тестируемойсистемы.Последний вид метрик покрытия является самым общим — все критерии полнотыиспользуют, так или иначе, какие-то модели системы. Дополняя такую модель некоторымигипотезами о возможных ошибках в системе — в чем именно она может отличаться от этоймодели, мы всегда получим основу для определения метрики тестового покрытия.
Первыечетыре вида, однако, выделены, поскольку используемые в них модели имеют четкоопределенную природу — это модели структуры самой системы, модели структуры еевходных данных, модели требований и модели ошибок определенного вида. К пятой группеотносятся метрики, основанные на моделях, не принадлежащих к этим разновидностям.Структурные критерииКритерии полноты тестирования и метрики тестового покрытия, основанные наструктуре тестируемой системы, называются структурными, а тестирование, проводимое сих использованием — структурным тестированием.В основе структурных критериев полноты лежит простая идея: если ошибка находится вкакой-то конструкции кода, в каком-то компоненте тестируемой системы, то выполнив этуконструкцию или заставив работать этот компонент, мы, скорее всего, сможем ееобнаружить. Соответственно, если в двух ситуациях выполняются одни и те же элементыкода, такая ошибка будет либо проявляться в обеих ситуациях, либо не проявляться ни водной, поэтому их можно объявить эквивалентными и проверять всегда только одну из такихситуаций.Это предположение редко выполняется на практике, однако как эвристика дляопределения метрик тестового покрытия, оно достаточно полезно.
Далее для некоторыхконкретных структурных метрик будут приведены примеры простых программ, в которыхвыполнение одной и той же конструкции в некоторых случаях вскрывает ошибку, а внекоторых — нет.Структурные метрики покрытия различаются в зависимости от размера элементовсистемы, используемых при их определении. Можно выделить три уровня структурныхметрик — уровень отдельной функции или отдельного метода класса, уровень компонентаили класса, включающего несколько операций, и уровень подсистемы или системы в целом,в составе которых может быть много компонентов.Вне зависимости от уровня структурные метрики могут быть основаны на информациидвух видов — на информации о передаче управления между разными исполняемымиэлементами системы или на информации об использовании и записи данных.
Метрикипервого типа называются основанными на потоке управления, второго типа — основаннымина потоках данных.Важным достоинством структурных метрик покрытия является возможность ихавтоматизированного вычисления при наличии доступа к коду или схемам архитектурытестируемой системы. Существенным недостатком является отсутствие учета требований —мы можем покрыть все элементы структуры, но не обнаружим, что какое-то требованиепросто забыли реализовать.Структурные критерии на уровне отдельной функцииСтруктурные метрики покрытия для одной функции или метода на основе потокауправления базируются на исполняемых в ходе теста элементах кода этой функции или этогометода.Метрики покрытия на основе потока управленияНаиболее простая из таких метрик — метрика покрытия инструкций (statementcoverage), равная доле выполненных во время тестирования инструкций кода функции поотношению ко всем ее инструкциям.
Поскольку в большинстве современных языковпрограммирования принято писать не более одной инструкции в строке, эта метрика чащевсего коррелирует с метрикой покрытия строк исходного кода. Однако всегда при разговорео строках кода стоит уточнять, насколько они соответствуют инструкциям, потому что частьстрок содержит декларативную, неисполняемую информацию, и информация обинструкциях позволяет точнее оценить ситуацию. В том случае, если часть инструкций недостижима, т.е. не может быть выполнена ни при каких условиях, долю покрытыхинструкций определяют только по отношению ко всем достижимым инструкциям.Рассмотрим следующий пример.1234567int gcd(int a, int b){if(a == 0)return b;if(b == 0)return a;if(a > 0 && b < 0 || a < 0 && b > 0)89101112131415161718192021222324b = -b;while(b != 0){if(b > a && a > 0 || b < a && a < 0){a = b-a;b = b-a;a = a+b;}b = a-b;a = a-b;}return a;}Приведенная функция вычисляет наибольший общий делитель своих аргументов.При вызове этой функции с аргументами 0 и 1 выполняются только инструкции в строках3 и 4.
При вызове с аргументами 1 и 0 будут выполнены строки 3, 5, 6. При вызове саргументами 1 и –2 выполняются строки 3, 5, 7, 8, 10, 12, 14, 15, 16, 19, 20, 23. Такимобразом, набор тестовых данных, состоящий из пар <0, 1>, <1, 0>, <1, –2> обеспечиваетполное покрытие инструкций этой функции.Заметим, что вместо <1, –2> можно было бы использовать два набора аргументов,например, <1, –1> и <1, 2>, первый из которых покрывает инструкцию 8, но не покрывает 14,15, 16, а второй — покрывает эти три инструкции.
С точки зрения получаемого покрытия всеравно, какой набор тестовых данных выбрать. Однако могут быть существенны другиеаспекты, например, время работы тестового набора и удобство анализа результатовтестирования. Время выполнения тестов обычно сокращается при уменьшении ихколичества, но сложный тест, эквивалентный по покрытию нескольким простым, в рядеслучаев может выполняться дольше, чем все они вместе взятые.
С точки зрения удобстваанализа результатов, чем проще тесты, тем лучше, поскольку меньше различных факторовприходится рассматривать при локализации ошибки, найденной таким тестом.В примерах, приведенных ниже, обычно используются наиболее компактные полныетестовые наборы для заданной метрики, но на практике всегда стоит рассмотреть вопросыэффективности выполнения тестов и удобства анализа результатов, прежде чем пытатьсяминимизировать их количество.Для обнаружения всех ошибок покрытия 100% инструкций недостаточно. В следующемпримере приведен код функции, которая должна по значению целого числа печатать егопростую характеристику — ноль это, четное или нечетное число, положительное илиотрицательное. В этом коде пропущена вставка слова «нечетное» в описание нечетныхчисел.