АНАЛИЗ ЭФФЕКТИВНОСТИ РАЗЛИЧНЫХ МЕТОДОВ ПОДГОТОВКИ ТЕСТОВЫХ ДАННЫХ В ТЕСТИРОВАНИИ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
Постановка проблемы заключается в сложности выбора эффективного метода подготовки тестовых данных в тестировании программного обеспечения.
Анализ последних исследований показывает, что метаэвристические методы (такие, как симулированный отжиг и т.д.) всё ещё остаются актуальными. Они помогают обходить различные проблемы с помощью традиционных методов, например, генетические алгоритмы (алгоритмы, позаимствованные из природы). В работе McMinn подтверждается, что эти алгоритмы полезны особенно для преодоления плато в поисковом пространстве (это те места, где обычные алгоритмы застревают и не могут справиться дальше), хотя и требуют доработки оценочных функций (функций фитнеса) и интеграции со статистическим анализом [1].
В обзоре Anand и соавторов говорится, что среди автоматизированных тестов для программ существуют: символическое, модельное, комбинаторное, адаптивно случайное и поисковое тестирование. Каждый из этих методов хорош по-своему, но в сложных программах ни один метод не универсален. Поэтому было решено использовать гибриды, которые дают наиболее лучший результат в рамках тестирования [2].
Обзор Ali и его коллег показывает, что генетические алгоритмы доминируют и превосходят случайный поиск по покрытию. Но исследование часто страдают от недостатка строгих сравнений – поэтому нужно уделить больше внимания стандартизации и масштабируемости. Это доказывает, что доказательства SBST пока ограничены, но имеют большой потенциал при правильной методологии [3].
В работе Joffe и Clark описывается Фреймворк GNAST который использует генеративные нейросети. Эти нейросети обучаются в процессе и готовы генерировать разнообразные тесты, но им сложно выполнять конкретные, точечные задачи, а также чувствительны к гиперпараметрам. Это показывает, что генеративные нейросети – это отличный инструмент, но нуждается в доработках [4].
Wang и соавторы в своём обзоре о больших языковых моделях в тестировании отметили успех в юнит тестах и починке кода, хотя то что покрытие (глубина и полнота сценария) остаются низкими и присутствует проблема с оракулами требует более качественных промптов и гибридных подходов. Интерес к LLM растёт, но всё ещё есть что развивать в этом направлении [5].
Shah и коллеги в своей статье показали что ML и data-mining инструменты, которые превосходят старые модели, однако есть этические риски и проблемы в работе новых моделей. То есть ML открывает возможности для scalable анализа безопасности [6].
Несмотря на развитие технологий тестирования, разработчики часто сталкиваются с проблемой качественного тестирования ПО, исходя из этого получаем вопрос: как эффективно тестировать сложное ПО в условиях нехватки времени и ресурсов? Какие методы и инструменты помогут находить критические ошибки до того, как они повлияют на пользователей? [12].
В данный момент уже есть проверенные инструменты, которые работают по принципу «Эволюции» [9]. Чтобы эти инструменты было удобнее сравнивать и улучшать учёные придумали библиотеку Defects4J в которой собрали все известные баги из известных программ [8]. Вместе с созданием тестов также развивалось и способы проверки. Один из лучших это мутационное тестирование, когда в код помещают небольшие изменения и смотрят, заметит ли это тест. Этот метод помогает точнее определить место ошибки в коде [7]. В данный момент набирает популярность объединения старых и надёжных методов с современными технологиями [10,11].
Цель исследования заключается в сравнении эффективности различных методов подготовки тестовых данных в тестировании программного обеспечения.
Основная часть
Тестирование программного обеспечения (ПО) представляет из себя проверку и оценку работоспособности программы или системы с целью выявления ошибок, дефектов и несоответствий. Основная задача тестировщиков – убедится в корректной работе ПО и соответствию требованиям пользователей. В основные этапы тестирования программного обеспечения входят:
1) планирование тестирования (определение цели и задачи, выбор методик и составление плана тестирования);
2) анализ требований (проверка соответствий требований программы, составления списка функций и компонентов для тестирования);
3) написание тест-кейсов (создание инструкции по проведению тестов с ожидаемыми результатами);
4) проведение тестирования (проводятся тесты с использованием тест-кейсов и других методик);
5) анализ результатов тестирования (оценка результатов тестов и составление отчёта).
Одним из важных этапов является составление тестовых данных (тест-кейсов), потому что качественные входные данные позволяют моделировать реальные сценарии использования программы, выявлять скрытые ошибки и проверять поведение системы в тех или иных случаях. Без хороших входных данных тестирование может быть не полным, пропускать дефекты и ошибки.
Последнее время программы становятся всё сложнее, и их тестирование также становится всё более затруднительной и трудоёмкой задачей. Поскольку составление тестовых данных является одним из важных этапов в тестировании, стоит разобрать различные методы подготовки тест-кейсов, для дальнейшего проведения сравнительного анализа эффективности рассмотрим традиционные методы такие как случайная и адаптивная генерация.
– Случайная генерация тестовых данных (random testing) – самый простой и ранний подход. Он лёгок в реализации и не требует глубокого анализа кода. Однако эти методы часто пропускают ошибки в кластеризованных пространствах дефектов (fault clusters) [2,3].
– Адаптивная случайная генерация (adaptive random testing). В этом методе улучшается распределение входов путём избегания близких значений, благодаря чему повышает вероятность выявления дефектов на 20 – 30% в отличии от чисто случайных. В контексте таких генераторов случайных чисел как MT19937 (Marsenne Twister), обеспечивают равномерное распределение по сравнению с простыми функциями вроде rand(). Эксперименты показали, что переход от простых функций rand() к более сложным MT19937 улучшает равномерность, но проблема семантической релевантности остаётся нерешённой – данные не учитывают структуру программы, не учитывают логику и зависимости в коде! [2].
Но имеются и недостатки этих методов:
− низкое покрытие сложных сценариев;
− пропуски граничных случаев;
− неэффективности для программ с нелинейными зависимостями.
− поисковые и эволюционные методы [1,3].
Search-based software testing (SBST) – это подход, который используют в метаэвристики, то есть алгоритмы оптимизации для генерации тестовых данных, вдохновлённые природными процессами. Генетические алгоритмы и эволюционные алгоритмы дают возможность имитировать естественный отбор (начальные данные прогрессируют через мутации, ориентированные на покрытие путей и ветвей решений). Particle swarm optimization (PSO) – другой пример метаэвристики, где происходит перемещение в пространстве поиска для оптимизации [1, 3].
Пример сравнения на Defect4J [8]
|
Метод |
Branch coverage (%) |
Mutation Score (%) |
Fault Detection (%) |
Время генерации (отн.) |
Источники |
|
Random (mt19937) |
65 – 75 |
55 – 65 |
40 – 50 |
1 |
[2] |
|
Search-based (EvoSuite) |
85 – 95 |
80 – 90 |
70 – 80 |
10 – 20 |
[1], [3], [9] |
|
Model-based (symbolic) |
80 – 90 |
75 – 85 |
65 – 75 |
15 – 30 |
[2] |
|
AI-based (GAN/LLM) |
90 – 98 |
90 – 97 |
85 – 95 |
5 – 15 |
[4], [5], [10] |
Эти методы куда эффективнее чем random testing: mutation score в SBST достигает 80–90%, тем временем как у random 55–65%. Данные методы сложны в вычислениях и зависят от качества функций пригодности [1,3,7].
Теперь рассмотрим такие методы как модельные: Model-based testing (MBT) – подход при котором тесты генерируются на основе формальных моделей программы (например – таких как графы). Symbolic execution (символьное выполнение) записывает переменные как символы и решает ограничение с помощью солверов (оптимизаторов). Это позволяет генерировать тесты для конкретных путей. Constraint solving (решение ограничений) интегрируется для обработки условий в коде [2].
Плюсы модельного метода: высокая точность в покрытии путей, превосходит random в fault detection на 40 – 50%. Такие инструменты как DART и KLEE демонстрируют это на практике. Стоит отметить, что методы малоэффективны для не линейных ограничений или внешних зависимостей, где эффективность падает [2].
Методы на основе ИИ и нейронных сетей. Для генеративных моделей, тестовые данные начали развиваться ещё с 2020-х годов. Generative Adversarial Networks (GAN) состоят из генератора и дискриминатора, создающие реалистичные данные через состязания. Рекуррентные нейронные сети (RNN/LSTM) обрабатывают последовательности и генерируют данные, имитирующие реальные распределения. Это помогает в тестировании, повышая разнообразие входов [4,10].
Large Language Models (LLM) – большие языковые модели, такие как ChatGPT. Создают тесты на основе отчётов об ошибках и требований. AI-based методы превосходят традиционные в mutation score до 95%, а diversity до 80% [5].
Теперь, когда мы разобрали методы подбора тест-кейсов, перейдём к сравнительному анализу эффективности. Для начала разберём эффективность оценивания по метрикам:
− Code coverage (branch/path coverage – доля исполненных ветвей, путей) [1-3];
− Mutation score (процент устранённых дефектов. Важно не только исполнение, но и проверки assertions) [7, 11];
− Fault detection rate (Дефекты на реальных бенчмарках, вроде Defects4J) [8].
В таблице собраны данные из разных источников, тем самым обобщая метрики на бенчмарке Defects4J. Значения являются приблизительными, усреднёнными диапазонами. Random методы дают низкие показатели, search-based и model-based – выше, AI-based – чаще всего показывают наивысшие показатели в новых работах.
Благодаря данной таблице мы можем убедится, что AI-based методы лидируют по всем метрикам благодаря способности генерировать реалистичные данные. В реальных экспериментах Search-based (EvoSuite) достигает 95% в Branch coverage и 90% в Mutation Score на Defects4J, в то время как AI-based (GAN, LLM) достигают 98% в Branch coverage и 97% в Mutation Score [8, 9]. Это показывает эффективность перехода от простых методов подбора тест-кейсов к продвинутым.
Так же стоит отметить, что гибридные подходы (SBST + GAN) повышают время генерации на 20 – 30%, но требует human-in-the-loop, участие человека в цикле, для валидации [5].
Выводы
В работе проанализированы подходы к созданию тестовых примеров при проверке программного обеспечения, начиная от классических и заканчивая методами, основанными на искусственном интеллекте. Повышение сложности современных программных продуктов и необходимость получения качественных, защищенных данных обуславливают значимость данного исследования. Сравнительный анализ различных техник показал превосходство решений с применением ИИ над остальными (показатель мутационного покрытия может достигать 97% против 65% у случайных тестов), однако это сопряжено с трудностями в понимании логики работы алгоритмов. В будущем предполагается комбинирование различных методик и внедрение этических аспектов для дальнейшего совершенствования процесса тестирования.
Библиографическая ссылка
URL: https://publish2020.scienceforum.ru/article/view?id=1036 (дата обращения: 01.11.2026).
