Автор Анна Евкова
Преподаватель который помогает студентам и школьникам в учёбе.

Отладка и тестирование программ: основные подходы и ограничения

Содержание:

Введение

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

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

Жизненным циклом программной системы является непрерывный процесс, который начинается с момента принятия решения о необходимости создания системы и заканчивающийся моментом её полного изъятия.

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

Процессы тестирования и отладки являются важными при разработке программного обеспечения, поэтому это объясняет, почему я выбрал эту тему.

Объект исследования данной работы – тестирования и отладка программ.

Предмет исследования – виды тестирования, основные подходы и ограничения.

Цель работы – описать этапы процесса разработки, а также подходы к тестированию.

Для достижения данной цели надо будет решить ряд задач:

  1. Проанализировать литературу по заданной теме;
  2. Описать основные термины;
  3. Определить виды тестирования;
  4. Описать основные подходы и ограничения.

Глава 1

Понятия тестирования и отладки программного обеспечения

1.1 Принципы тестирование и отладка программного обеспечения

Тестирование – это процесс анализа программы с целью обнаружения ошибок.

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

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

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

Отладка – это процесс выявления источников ошибок, и внесение в программу соответствующих исправлений.

1.2 Этапы тестирования программного обеспечения

Существует несколько этапов стратегии тестирования:

  1. Объем тестовых работ путем анализа документов, которые содержат требование к программе.
  2. Выбор статических и динамических тестов, связанных со стадиями разработки.
  3. Критерии входа и выхода для каждой стадии тестирования.
  4. Автоматизация в случае того, если планируется использование какого-либо вида тестовой деятельности.

Объем тестовых работ

Если тестирование будет избыточным, то для отладки программы потребуется значительное время. Может быть такое, что риск пропуска того или иного дефекта будет увеличен, устранение этого дефекта будет стоить очень дорого. Но возникает вопрос, как же отыскать нужный баланс между этими крайностями поможет опыт и измерения успешности тестирования.

Есть несколько предложений по разработке стратегии тестирования, которые помогут найти оптимальное тестовое покрытие.

  1. В первую очередь это тестировать требования с наивысшими приоритетами.
  2. Всегда тестировать новый функциональные возможности и программный код, который изменялся с целью исправления и усовершенствования.
  3. Использовать разбиение на классы и анализ граничных значения для снижения трудозатрат на тестирование.
  4. И конечно же тестировать именно те участки где наиболее высоко вероятно присутствие проблем.

Подход к тестированию

Построение подхода к тестированию всегда начинается с исследования стадии разработки с целью отбора тестов статического и динамического тестирования. При этом не имеет значения, какая модель разработки используется: каскадная, спиральная или модель с итеративными версиями – для отбора эффективности тестов можно исследовать все перечисленные модели.

  1. Каскадная модель – это модель процесса разработки программного обеспечения, в котором процесс разработки выглядит как поток, последовательно проходящий фазы анализа требований, проектирования, реализации, тестирования, интеграции и поддержки.
  2. Спиралевидная модель – это модель процесса разработки программного обеспечения, сочетающий в себе как итеративность, так и этапность.
  3. Итеративная модель – это модель процесса разработки программного обеспечения, в котором происходит выполнение работ параллельно с непрерывным анализом полученных результатов и корректировкой предыдущих этапов работы.

Возьмем каскадную модель и выясним, какие виды тестирования могут для нее использоваться:

  1. Стадия формулирования требований
  2. Стадия системного проектирования
  3. Стадии тестирования проектов программ, программных кодов.
  4. Системные испытания
  5. Регрессионное тестирование
  6. Подход к тестированию должен отражаться в документах
  7. Определение критериев тестирования и точек контроля качества
  8. Есть пять критериев, которые могут определяться перед началом системного тестирования:
  9. Критерий входа, который показывает, что нужно сделать перед началом тестирования.
  10. Критерий выхода, который показывает то, что необходимо для завершения испытаний.
  11. Критерий приостановки/возобновления, который показывает нам, что произойдет, если из-за дефектов продолжение тестирования окажется невозможным.
  12. Критерий успешного/неудачного теста. Прогоняет каждый тест, который должен давать заранее известные результаты.

Так де есть и другие критерии, которые определяются процессом и стандартом. Если программный продукт будет соответствовать стандарту или компания предъявит определенные требования к выполнению процесса, то, нужно будет учесть еще ряд дополнительных критериев.

Стратегии автоматизации

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

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

1.3 Цели и задачи тестирования программного обеспечения

Цели тестирования:

  1. Повысить вероятность того, что приложение, предназначенное для тестирования, будет работать правильно при любых обстоятельствах.
  2. Повысить вероятность того, что приложение, предназначенное для тестирования, будет соответствовать всех описанным требованиям.

Задачи тестирования:

  1. Проверить, что система работает в соответствии с определенными временами оклика клиента и сервера.
  2. Проверить, что наиболее критические последовательности действий с системой конечного пользователя выполнятся верно.
  3. Проверить работу пользовательских интерфейсов.
  4. Проверить, что изменения в базах данных не отказывают неблагоприятного влияния на существующие программные модули.
  5. При проектировании тестов свести к минимуму переработку тестов при возможных изменениях приложения.
  6. Использовать инструменты автоматизированного тестирования там, где это целесообразно.
  7. Проводить тестирование таким образом, чтобы не только обнаруживать, но и предупреждать дефекты.
  8. При проектировании автоматизированных тестов использовать стандарты разработки таким образом, чтобы создать многократно используемые и сопровождаемые скрипты.

1.4 Комплексное тестирование программного обеспечения

Целью комплексного тестирования является проверка того, что каждый модуль программного продукта корректно согласуется с остальными модулями продукта. При комплексном тестировании может использоваться технология обработки сверху вниз и снизу вверх, при которой каждый модуль, являющийся листом в дереве системы, интегрируется со следующим модулем более низкого или более высокого уровня, пока не будет создано дерево программного продукта. Эта технология направлена не только на проверку тех параметров, которые передаются между двумя компонентами, но и на проверку глобальных параметров и, в случае объектно-ориентированного приложения, всех классов верхнего уровня.

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

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

1.5 Восходящее и нисходящее тестирование

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

Главным недостатком восходящего тестирования является необходимое написания специального кода-оболочки, вызывающего тестируемый модуль. Если он, в свою очередь, вызывает другой модуль, для него нужно написать заглушку. Заглушка – это имитация вызываемой функции.

У восходящего тестирования есть противоположность, стратегия целостного тестирования. Она предполагает, что до полной интеграции системы её отдельные модули не проходят особо тщательного тестирования.

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

Но на самом деле очень трудно выявить источник ошибки. Поскольку ни один из модулей не проверен, как следует, в большинстве всегда есть ошибки. Хочется сказать, что вопрос состоит не только в том, в каком модуле произошло обнаружение ошибки, сколько в том, какая ошибка привела к полученному результату. И когда на модули накладываются несколько ошибок, ситуацию гораздо труднее локализовать и повторить,

также ошибка может блокировать тестирование другого модуля. Программу всегда пишут несколько программистов, и даже при этом очень сложно найти в каком модуле была ошибка.

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

Существует и еще один принцип организации тестирования, при котором программа так же, как и при восходящем способе, тестируется не целиком, а по частям. Только меняется направления движения – сначала тестируется самый верхний уровень, а потом от него постепенно спускается вниз. Такая технология называется нисходящей.

При нисходящем тестировании отпадает необходимость в написании оболочек, но заглушки остаются. По мере тестирования заглушки по очереди заменяются реальные модули.

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

Глава 2

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

2.1 Метод белого ящика

Стратегия белого ящика:

  1. Покрытие операторов
  2. Покрытие решений
  3. Покрытие условий
  4. Покрытие решений/условий

2.1.1 Покрытие операторов

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

2.1.2 Покрытие решений

Покрытие решений более сильный критерий, или как его еще называют покрытие переходов. Согласно данному критерию должно быть записано достаточное число тестов, такое, что каждое решение на этих тестах примет значение истина и ложь, по крайней мере, один раз. Иными словами хочется сказать, что каждое направление перехода должно быть реализовано, по крайней мере, один раз. Примерами же операторов перехода являются операторы while или if.

Можно показать, что покрытие решений обычно удовлетворяет критерию покрытия операторов. Поскольку каждый оператор лежит на некатором пути, исходящем либо из оператора перехода, либо из точки входа программы, при выполнении каждого направления перехода каждый оператор должен быть выполнен. Однако существует три исключения. Первое – патологическая ситуация, когда программа не имеет решений. Второе встречается в программах или подпрограммах с несколькими точками входа (например, в программах на языке Ассемблера); данный оператор может быть выполнен только в том случае, если выполнение программы начинается с соответствующей точки входа. Третье исключение – операторы внутри switch-конструкций; выполнение каждого направления перехода не обязательно будет вызывать выполнение всех case-единиц. Так как покрытие операторов является необходимым условием, то покрытие решений, которые представляется более сальным критерием, должно включать покрытие операторов. Следовательно, покрытие решений требует, чтобы каждое решение имело, результатом значения истина и ложь и при этом каждый оператор выполнялся бы, по крайней мере, один раз. Но также есть альтернативный и более легкий способ выражения этого требования, который состоит в том, что каждое решение имело результатом значения истина и ложь и что каждой точке входа (включая также каждую case-единицу) Должно быть предано управления при вызове программы, по крайней мере, один раз.

Хочется сказать, что сказанное выше предполагает только двузначные решения или переходы и должно быть модифицировано для программ, содержащих многозначные решения (как для case-единиц). Критерием же для них является выполнение каждого возможного результата всех решений и передача управления при вызове программы или подпрограммы каждой точке входа.

2.1.3 Покрытие условий

Покрытие решений – более сильный критерий, чем покрытие операторов, но и он имеет свои недостатки. Например, путь, где X не изменятся (если выбрано первое альтернативное покрытие), будет проверен с вероятностью 50 %. Если во втором решении существует ошибка (например, X < 1 вместо X > 1), то ошибка не будет обнаружена двумя тестами предыдущего примера.

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

2.1.4. Покрытие решений/условий

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

Недостатком критерия покрытия решений/условий является невозможность его применения для выполнения всех результатов всех условий; часто подобное выполнение имеет место вследствие того, что определенные условия скрыты другими условиями.


C:\Users\Лузин\Desktop\gIwrVEp.png

В качестве примера хотелось бы рассмотреть данный рисунок. Схему передач управления в коде, генерируемым компилятором языка.

Много условные решения исходной программы здесь разбиты на отдельные решения и переходы, поскольку большинство компьютеров не имеет команд, реализующих решений со многими исходами. Наиболее полное покрытие тестами в этом случае осуществляется таким образом, чтобы выполнялись все возможные результаты каждого простого решения. Два предыдущих теста критерия покрытия решений не выполняют этого; они недостаточны для выполнения результата ложь решения H и результата истина решения K. Набор тестов для критерия покрытия условий такой программы также является неполным; два теста (которые случайно удовлетворяют также и критерию покрытия решений/условий) не вызывают выполнения результата ложь решения I и результат истина решения K.

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

2.2 Стратегии черного ящика

Стратегии черного ящика:

  1. Эквивалентное разбиение
  2. Анализ граничных значений
  3. Применение функциональных диаграмм
  4. Предположение об ошибке

2.2.1 Эквивалентное разбиение

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

Правильно выбранный тест должен обладать двумя свойствами:

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

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

если один тест класса эквивалентности обнаруживает ошибку, то следует понимать, что и все другие тесты этого же класса, также могут обнаружить эту же ошибку. Наоборот, если тест не обнаруживает ошибки, то ни один тест этого класса, также не обнаружить ошибку.

Эти два положения составляют основу методологии тестирования по принципу черного ящика, известной как эквивалентное разбиение. Второе положение используется для разработки набора “интересных” условий, которые должны быть протестированы, а первое – для разработки минимального набора тестов, покрывающих эти условия.

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

Разработка тестов методом эквивалентного разбиения осуществляется в два этапа:

  1. Выделение классов эквивалентности
  2. Построение тестов

2.2.1.1 Выделение классов эквивалентности

Классы эквивалентности выделяются путем выбора каждого входного условия и разбиением его на две или более групп. Для проведения этой операции используют таблицу изображенную.

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

Если задаться входным или внешними условиями, то выделение классов эквивалентности представляет собой в значительной степени эвристический процесс. При этом существует ряд правил:

  1. Если входное условие описывает область значений, то определяются один правильный класс эквивалентности и два неправильных.
  2. Если входное условие описывает число значений, то определяются один правильный класс эквивалентности и два неправильных.
  3. Если входное условие описывает множество входных значений и есть основание полагать, что каждое значение программа трактует особо, то определяется правильный класс эквивалентности для каждого значения и один неправильный класс эквивалентности.
  4. Если входное условие описывает ситуацию “должно быть”, то определяется один правильный класс эквивалентности и один неправильный.
  5. Если есть любое основание считать, что различные элементы класса эквивалентности трактуются программой неодинаково, то данный класс эквивалентности разбивается на меньшей классы эквивалентности.

Построение тестов

Второй шаг заключается в использовании классов эквивалентности для построения тестов. Этот процесс включает в себя:

  1. Назначение каждому классу эквивалентности уникального номер.
  2. Проектирование новых тестов, каждый из которых покрывает как можно большее число непокрытых правильных классов эквивалентности, до тех пор все правильные классы эквивалентности не будут покрыты тестами.
  3. Запись тестов, каждый из которых покрывает один и только дин из непокрытых неправильных классов эквивалентности, до тез пор, пока все неправильные классы эквивалентности, до тех пор, пока все неправильные классы эквивалентности не будут покрыты тестами.

Причина покрытия неправильных классов эквивалентности индивидуальными тестами состоит в том, что определённо проверки с ошибочными входами скрывают или заменяют другие проверки с ошибочными входами.

2.2.2 Анализ граничных значений

Как показывает опыт, тесты, исследующие граничные условия, приносят большую пользу, чем тесты, которые их не исследуют. Граничные условия – это ситуации, возникающие непосредственно на, выше или ниже границ входных и выходных классов эквивалентности. Анализ граничных значений отличается от эквивалентного разбиение в двух отношениях:

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

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

  1. Можно построить тесты для границ области и тесты с неправильными входными данными для ситуаций незначительного выхода за границы области.
  2. Построить тесты для минимального и максимального значений условий и тесты, большие и меньшие этих значений.
  3. Использовать первое правило для каждого входного условия.
  4. Также можно использовать второе правило для каждого выходного условия.
  5. Если же вход или выход программы есть упорядоченное множество, то сосредоточить внимание на первом и последнем элементах этого множества.
  6. Можно также попробовать свои силы в поиске других граничных условий.

Можно проиллюстрировать необходимость анализа граничных значений, для этого используют программу анализа треугольника. Для задания треугольника входные значения должны быть целыми положительными числами, и сумма любых двух из них должно быть больше третьего. Также есть определенные эквивалентные разбиения, которые целесообразно определяет одно разбиение, в котором это условие выполняется, и другое, в котором сумма двух целых не больше третьего. Можно сказать, что двумя возможными тестами являются 3-4-5 и 1-2-4. Тем не менее, даже здесь есть вероятность пропуска ошибки. Существенное различие между анализом граничных значений и эквивалентным разбиением заключается в том, что анализ граничных значений исследует ситуации, возникающие на и вблизи границ эквивалентных разбиений.

2.2.3 Применение функциональных диаграмм

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

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

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

  1. Спецификация разбивается на участки. Конечно, это связано с тем, что функциональные диаграммы становятся слишком громоздкими при применении данного метода к большим спецификациям.
  2. В спецификации определяются причины и следствия. Причина есть отдельное входное условие или класс эквивалентности входных условий. Следствие есть выходное условие или преобразование системы (остаточное действие, где входное условие оказывает на состояние программы или системы).
  3. Анализируется семантическое содержание спецификации, которая преобразуется в булевский граф, связывающий причины и следствия.
  4. Диаграмма снабжается примечаниями, задающими ограничения и описывающими комбинации причин и следствий, которые являются невозможными из-за синтаксических или внешних ограничений.
  5. Путем методического прослеживания состояний условий диаграммы она преобразуется в таблицу решений с ограниченными входами
  6. Столбцы таблица решений преобразуются в тесты.

Базовые символы для записи функциональных диаграмм показаны на рисунке. Где каждый узел диаграммы может находиться в двух состояниях – 0 или 1 ; где 0 обозначает состояние “отсутствует”, а 1 – “присутствует”. Функция тождество устанавливает, что если значение a есть 1, то и значение b есть 1; в противном случае значение b есть 0. Функция не устанавливает, что если a есть 1, то b есть 0; в противном случае b есть 1. Функция или устанавливает, что если a, или b, или c есть 1, то d есть 1; в противном случае d есть 0. Функция и устанавливает, что если и a, и b, есть 1, то и c есть 1; в противном случае c есть 0. Последнее две функции разрешают иметь любое число входов.

C:\Users\Лузин\AppData\Local\Microsoft\Windows\INetCache\Content.Word\IsJqCzj.png

Хочется добавить, что применение функциональных диаграмм – это систематический метод генерации тестов, представляющий из себя комбинации условий. Альтернативой же является специальный выбор комбинаций, но при этом существует вероятность пропуска многих “интересных” тестов, определенных с помощью функциональной диаграммы.

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

Метод функциональных диаграмм позволяет построить набор полезных тестов, но его применение обычно не обеспечивает построение всех полезных тестов, которые могут быть определены. Кроме этого, функциональная диаграмма неадекватно исследует граничные условия.

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

Но самое трудное это реализация этого метода в таблицу решений. Это преобразование представляет собой алгоритмический процесс. Из этого можно сделать вывод, что его можно автоматизировать посредством написания программы.

Предположение об ошибке

Можно сказать, что человек, обладающий практическим опытом, на подсознательном уровне применят метод проектирования тестов, который называется предположение об ошибке. При наличии определенной программы он может интуитивно предполагать типы ошибок и затем сразу же разрабатывать тесты для из обнаружения.

Процедуру для метода предположения об ошибке описать трудно, так как он в значительной степени является интуитивным. Основная идея заключается в том, чтобы перечислить в нектаром списке возможные ошибки, в которых они могут появиться, а уже затем на основе этого списка писать тесты. Приведу пример, такая ситуация происходит при значении 0 на входе и выходе программы. Значит, можно сделать тесты, для которых определенные входные данные имеют нулевые значения и для которых определенные выходные данные устанавливаются в 0. Можно добавить, что при переменном числе входов или выходов ошибки возможны в ситуациях типа “никакой” и “один”. Так же есть и другая идея, которая состоит в том, чтобы определить тесты, которые могут быть связаны с предположениями, которые в свою очередь может сделать программист во время чтения спецификаций.

Данная процедура не может быть четко определена, лучшим способом обсуждения смысла предположения об ошибке представляется разбор примеров. Можно в качестве примера рассмотреть тестирование подпрограммы сортировки, то нужно будет исследовать следующие ситуации:

  1. Сортируемый список пуст.
  2. Сортируемый список содержит одно и то же значение.
  3. Все записи в сортируемом списке имеют одно.
  4. Список уже отсортирован.

Другими словами можно сказать, что требуется перечислить те специальные случаи, которые могут быть не учтены при проектировании программы. Если же пример заключается в тестировании подпрограммы двоичного поиска, то можно проверить следующие ситуации:

  1. Существует только один вход в таблицу, в которой ведется поиск.
  2. Размер таблица есть степень двух.
  3. Размер таблица должен быть меньше или больше степени двух.

2.3 Метод Сандвича

Тестирования этим метод представляет собой компромисс между восходящим и нисходящим подходами. Здесь делается упор на то, что нужно воспользоваться достоинствами обоих методов, и избежать их недостатки. При использовании этого метода одновременно начинают восходящее и нисходящее тестирование, собирая программу как снизу, так и сверху и встречаясь, в конце концов, где-то в середине. Точка встречи зависит от конкретной тестируемой программы и всегда должна, быть заранее определена при изучении её структуры. Можно привести в пример разработчика, который может представить свою систему в виде уровня прикладных модулей, а затем уровня модулей обработки запросов, затем уровня примитивных функций, то он может решить применять нисходящий метол на уровне прикладных модулей, а на остальных уровнях он может применить восходящий метод. Применение этого метода – это разумны подход к интеграции больших программ, как операционная система или пакет прикладных программ.

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

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

2.4 Методы отладки программного обеспечения

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

  1. Ручное тестирование.
  2. Прологи.
  3. Снижения
  4. Обратная трассировка.

2.4.1 Метод ручного тестирования.

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

2.4.2 Метод пролога

Этот метод основан на тщательном анализе ошибки. Которую можно показать как неправильные результаты расчетов или как сообщение об ошибке. Если компьютер просто “зависает”, то фрагмент дисплея ошибки вычисляют, происхождение последних полученных результатов и движений потребителя. Информация, полученная таким образом, организует и осторожно учит просматривать адекватный фрагмент программы. В результате этих гипотез усовершенствования движений о погрешностях, каждая из которых проверяют. Если гипотеза – истина, то детализируется информация об ошибке.

2.4.3 Метод снижения

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

2.4.4 Метод обратной трассировки

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

Заключение

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

Список использованных источников

  1. И.В.Степанченко “методы тестирования программного обеспечения” http://window.edu.ru/resource/765/45765/files/kti10.pdf
  2. И.В.Винниченко “Автоматизация процессов тестирования” https://www.studmed.ru/view/vinnichenko-iv-avtomatizaciya-processov-testirovaniya_db0467cb7bd.html
  3. Д.Элфрид “Автоматизированное тестирование программного обеспечения, внедрение, управление и эксплуатация” http://padaread.com/?book=79236&pg=3
  4. М.Плаксин “тестирования и отладка программ для профессионалов будущих и настоящих” https://docplayer.ru/49795651-M-plaksin-testirovanie-i-otladka-programm-dlya-professionalov-budushchih-i-nastoyashchih-3-e-izdanie-elektronnoe.html
  5. Т.В.Коликова “Основы тестирования программного обеспечения. Учебное пособие” http://window.edu.ru/resource/713/41713/files/MSTesting.pdf