1. Напоминание!
Тестирование
= поиск дефектов!
Тестирование-
процесс
исследования ПО с целью
получения информации о качестве
продукта.
2. Что такое дефект (баг)?
Дефект
(он же баг) — это несоответствие
фактического результата выполнения
программы ожидаемому результату.
3. «First actual case of bug being found»
4. Как определить дефект перед нами или нет?
Программа
не делает, то что она должна
делать согласно ТЗ.
Программа
делает что-то, чего она не
должна делать согласно ТЗ.
Программа
делает что-то, о чём в
требованиях не упоминалось.
Программа
не делает чего-то, о чём не
говорится в требованиях , однако
подразумевается, что она должна это делать.
Программа
трудна для понимания и
неудобна в использовании.
5. Оформление отчёта об ошибке
Цель составления :отчета об ошибке является ее
исправление.
Каждое хорошее описание ошибки должно содержать
роено три вещи
1. Какие шаги привели к ошибке;
2. Что Вы ожидали, увидеть;
3. Что Вы на самом деле увидели.
.1 отчет в багтреккере на I баг
.1 отчет в багтреккере на один итот жебаг, который
воспроизводится браузерах/ОС.
6. Основные типы дефектов ПО
функциональные
ошибки
7. Функциональные ошибки. Примеры:
1.
Не сохраняются изменения данных в
профиле
2.
Не работает добавление комментария
3.
Не работает удаление товара из
корзины
4.
Не работает поиск
8. Основные типы дефектов ПО
функциональные ошибки
визуальные ошибки
9. Визуальные ошибки. Примеры:
1.
Текст вылезает за границы поля
2.
Элемент управления сайтом
наслаивается на нижестоящий элемент.
3.
Не отображается картинка
10. Основные типы дефектов ПО
функциональные
ошибки
визуальные ошибки
логические ошибки
11. Логические ошибки. Примеры:
1.
Можно поставить дату рождения в
будущем. 31 февраля, 31 июня и т.д.
2.
Можно сделать заказ не указав адрес
доставки
3.
Неверная работа логики поиска
12. Основные типы дефектов ПО
функциональные
ошибки
визуальные ошибки
логические ошибки
ошибки контента
13. Ошибки контента. Примеры:
1.
Конвертация валют идет по некорректному курсу.
2.
Орфографические или пунктуационные ошибки.
3.
Картинка товара не соответствует
карточке товара
14. Основные типы дефектов ПО
функциональные
ошибки
визуальные ошибки
логические ошибки
ошибки контента
ошибки удобства
использования
15. Ошибки удобства использования. Примеры:
1.
Отсутствие подсветки или текста
ошибки при некорректно заполненных
полях формы
2.
Сброс значений заполненных полей
при некорректной попытке регистрации
3.
Перегруженный интерфейс
(чрезмерное количество однотипных
точек входа)
16. Основные типы дефектов ПО
функциональные
ошибки
визуальные ошибки
логические ошибки
ошибки контента
ошибки удобства
использования
ошибки безопасности
17. Ошибки безопасности. Примеры:
1.
XSS-уязвимости
2. SQL-инъекции
18. Зачем документируют дефекты
Чтобы
Чтобы
не забыть
иметь возможность
исправлять конкретные проблемы
Чтобы собирать метрики
19. Ошибки безопасности. Примеры:
1.
XSS-уязвимости
2. SQL-инъекции
20. Простые правила оформления
Один дефект — один репорт
Говорящее название
Понятное описание
21. Оформление ошибок. Название
Локатор. Действие для проявления.
Проявление. Ожидаемый результат.
Где? Что делал? Что получилось? Что
ожидали?
22. Оформление ошибок. Описание
1. Предусловия воспроизведения
2. Последовательность действий для
воспроизведения
3. Фактический результат
4. Ожидаемый результат
23. Оформление ошибок. Доп. инфо
1. Окружение/условия воспроизведения
2. Скриншоты/видео
3. Логи/артефакты работы ПО
4. Атрибуты ошибки (важность, компонент)
24. Атрибуты бага: (Summary)
Принцип описания
сути(Summary) бага:
Что?
Где?
Когда?, (При каких условиях?)
25. Практика формулирования Summary бага.
Сформулируйте
баг на скриншоте
используя принцип: Что, где, когда?
26. Практика формулирования Summary бага.
Ответ:
Что:
Отсутствует выпадающее меню
Где:
в пункте Actionc
Когда:
при не выбранном документе.
27. Серьёзность и Приоритет багов.
СЕРЬЁЗНОСТЬ
ПРИОРИТЕТ
S1 Блокирующий (Blocker)
S2 Критический (Critical)
S3 Значительный (Major)
P1 Высокий (High)
S4 Незначительный (Minor)
P2 Средний (Medium)
S5 Тривиальный (Trivial)
P3 Низкий (Low)
28. Жизненный цикл дефекта.
29. Жизненный цикл дефекта.
30. Состояние дефектов
31. Жизненный цикл дефекта.
Варианты прохождения багов:
1. (новый)new
(отклоненный)rejected
(закрытый)closed
2. new
(отложенный)deferred
3. new
(принятый)Accepted
(открытый)open
(исправленный)fixed
(закрытый)closed
4. new
pen
accepted
(открыт снова)reopend
fixed
closed
32. Дефекты — основной продукт работы тестировщиков !!!
Дефекты программного обеспечения можно обнаружить на каждом этапе разработки и тестирования продукта. Чтобы гарантировать исправление наиболее серьезных дефектов программного обеспечения, тестировщикам важно иметь хорошее представление о различных типах дефектов, которые могут возникнуть.
В этой статье мы обсудим самые распространенные типы ПО дефекты и способы их выявления.
Что такое дефект?
Дефект программного обеспечения — это ошибка, изъян, сбой или неисправность в компьютерной программе, из-за которой она выдает неправильный или неожиданный результат или ведет себя непреднамеренным образом. Программная ошибка возникает, когда фактические результаты не совпадают с ожидаемыми. Разработчики и программисты иногда допускают ошибки, которые создают ошибки, называемые дефектами. Большинство ошибок возникает из-за ошибок, которые допускают разработчики или программисты.
Обязательно прочтите: Разница между дефектом, ошибкой, ошибкой и сбоем
Типы программных ошибок при тестировании программного обеспечения
Существует множество различных типов дефектов программного обеспечения, и тестировщикам важно знать наиболее распространенные из них, чтобы они могут эффективно тестировать их.
Ошибки программного обеспечения подразделяются на три типа:
- Дефекты программного обеспечения по своей природе
- Дефекты программного обеспечения по их приоритету
- Дефекты программного обеспечения по их серьезности
Обычно мы можем видеть приоритет и серьезность классификаторов в большинстве инструментов отслеживания ошибок. Если мы настроим классификатор в соответствии с характером ошибки, а также приоритетом и серьезностью, это поможет легко управлять распределением обязанностей по исправлению ошибок соответствующим командам.
#1. Дефекты программного обеспечения по своей природе
Ошибки в программном обеспечении имеют широкий спектр природы, каждая из которых имеет свой собственный набор симптомов. Несмотря на то, что таких багов много, сталкиваться с ними можно не часто. Вот наиболее распространенные ошибки программного обеспечения, классифицированные по характеру, с которыми вы, скорее всего, столкнетесь при тестировании программного обеспечения.
#1. Функциональные ошибки
Как следует из названия, функциональные ошибки — это те, которые вызывают сбои в работе программного обеспечения. Хорошим примером этого может служить кнопка, при нажатии на которую должно открываться новое окно, но вместо этого ничего не происходит.
Функциональные ошибки можно исправить, выполнив функциональное тестирование.
#2. Ошибки на уровне модуля
Ошибки на уровне модуля — это дефекты, связанные с функциональностью отдельного программного модуля. Программный модуль — это наименьшая тестируемая часть приложения. Примеры программных модулей включают классы, методы и процедуры. Ошибки на уровне подразделения могут существенно повлиять на общее качество программного обеспечения.
Ошибки на уровне модуля можно исправить, выполнив модульное тестирование.
#3. Ошибки уровня интеграции
Ошибки уровня интеграции — это дефекты, возникающие при объединении двух или более программных модулей. Эти дефекты может быть трудно найти и исправить, потому что они часто требуют координации между несколькими командами. Однако они могут оказать существенное влияние на общее качество программного обеспечения.
Ошибки интеграции можно исправить, выполнив интеграционное тестирование.
#4. Дефекты юзабилити
Ошибки юзабилити — это дефекты, влияющие на работу пользователя с программным обеспечением и затрудняющие его использование. Дефект юзабилити — это дефект пользовательского опыта программного обеспечения, который затрудняет его использование. Ошибки юзабилити — это такие ошибки, как если веб-сайт сложен для доступа или обойти, или процесс регистрации сложен для прохождения.
Во время тестирования удобства использования тестировщики программного обеспечения проверяют приложения на соответствие требованиям пользователей и Руководству по доступности веб-контента (WCAG) для выявления таких проблем. Однако они могут оказать существенное влияние на общее качество программного обеспечения.
Ошибки, связанные с удобством использования, можно исправить, выполнив тестирование удобства использования.
#5. Дефекты производительности
Ошибки производительности — это дефекты, влияющие на производительность программного обеспечения. Это может включать в себя такие вещи, как скорость программного обеспечения, объем используемой памяти или количество потребляемых ресурсов. Ошибки уровня производительности сложно отследить и исправить, поскольку они могут быть вызваны рядом различных факторов.
Ошибки юзабилити можно исправить, выполнив тестирование производительности.
#6. Дефекты безопасности
Ошибки безопасности — это тип дефекта программного обеспечения, который может иметь серьезные последствия, если его не устранить. Эти дефекты могут позволить злоумышленникам получить доступ к конфиденциальным данным или системам или даже позволить им получить контроль над уязвимым программным обеспечением. Таким образом, очень важно, чтобы ошибкам уровня безопасности уделялось первоочередное внимание и устранялись как можно скорее.
Ошибки безопасности можно исправить, выполнив тестирование безопасности.
#7. Дефекты совместимости
Дефекты совместимости — это те ошибки, которые возникают, когда приложение несовместимо с оборудованием, на котором оно работает, или с другим программным обеспечением, с которым оно должно взаимодействовать. Несовместимость программного и аппаратного обеспечения может привести к сбоям, потере данных и другому непредсказуемому поведению. Тестировщики должны знать о проблемах совместимости и проводить соответствующие тесты. Программное приложение, имеющее проблемы с совместимостью, не работает последовательно на различных видах оборудования, операционных системах, веб-браузерах и устройствах при подключении к определенным программам или работе в определенных сетевых условиях.
Ошибки совместимости можно исправить, выполнение тестирования совместимости.
#8. Синтаксические ошибки
Синтаксические ошибки являются самым основным типом дефекта. Они возникают, когда код нарушает правила языка программирования. Например, использование неправильной пунктуации или забывание закрыть скобку может привести к синтаксической ошибке. Синтаксические ошибки обычно мешают запуску кода, поэтому их относительно легко обнаружить и исправить.
#9. Логические ошибки
Логические ошибки — это дефекты, из-за которых программа выдает неправильные результаты. Эти ошибки может быть трудно найти и исправить, потому что они часто не приводят к каким-либо видимым ошибкам. Логические ошибки могут возникать в любом типе программного обеспечения, но они особенно распространены в приложениях, требующих сложных вычислений или принятия решений.
Общие симптомы логических ошибок включают:
- Неверные результаты или выходные данные
- Неожиданное поведение
- Сбой или зависание программного обеспечения
Чтобы найти и исправить логические ошибки, тестировщикам необходимо иметь четкое представление о коде программы и о том, как она должна работать. Часто лучший способ найти такие ошибки — использовать инструменты отладки или пошаговое выполнение, чтобы отслеживать выполнение программы и видеть, где что-то идет не так.
#2. Дефекты программного обеспечения по степени серьезности
Уровень серьезности присваивается дефекту по его влиянию. В результате серьезность проблемы отражает степень ее влияния на функциональность или работу программного продукта. Дефекты серьезности классифицируются как критические, серьезные, средние и незначительные в зависимости от степени серьезности.
#1. Критические дефекты
Критический дефект — это программная ошибка, имеющая серьезные или катастрофические последствия для работы приложения. Критические дефекты могут привести к сбою, зависанию или некорректной работе приложения. Они также могут привести к потере данных или уязвимостям в системе безопасности. Разработчики и тестировщики часто придают первостепенное значение критическим дефектам, поскольку их необходимо исправить как можно скорее.
#2. Серьезные дефекты
Серьезный дефект — это программная ошибка, существенно влияющая на работу приложения. Серьезные дефекты могут привести к замедлению работы приложения или другому неожиданному поведению. Они также могут привести к потере данных или уязвимостям в системе безопасности. Разработчики и тестировщики часто придают первостепенное значение серьезным дефектам, поскольку их необходимо исправить как можно скорее.
#3. Незначительные дефекты
Незначительный дефект — это программная ошибка, которая оказывает небольшое или незначительное влияние на работу приложения. Незначительные дефекты могут привести к тому, что приложение будет работать немного медленнее или демонстрировать другое неожиданное поведение. Разработчики и тестировщики часто не придают незначительным дефектам приоритет, потому что их можно исправить позже.
#4. Тривиальные дефекты
Тривиальный дефект – это программная ошибка, не влияющая на работу приложения. Тривиальные дефекты могут привести к тому, что приложение отобразит сообщение об ошибке или проявит другое неожиданное поведение. Разработчики и тестировщики часто присваивают тривиальным дефектам самый низкий приоритет, потому что они могут быть исправлены позже.
#3. Дефекты программного обеспечения по приоритету
#1. Дефекты с низким приоритетом
Дефекты с низким приоритетом, как правило, не оказывают серьезного влияния на работу программного обеспечения и могут быть отложены для исправления в следующей версии или выпуске. В эту категорию попадают косметические ошибки, такие как орфографические ошибки, неправильное выравнивание и т. д.
#2. Дефекты со средним приоритетом
Дефекты со средним приоритетом — это ошибки, которые могут быть исправлены после предстоящего выпуска или в следующем выпуске. Приложение, возвращающее ожидаемый результат, которое, однако, неправильно форматируется в конкретном браузере, является примером дефекта со средним приоритетом.
#3. Дефекты с высоким приоритетом
Как следует из названия, дефекты с высоким приоритетом — это те, которые сильно влияют на функционирование программного обеспечения. В большинстве случаев эти дефекты необходимо исправлять немедленно, так как они могут привести к серьезным нарушениям нормального рабочего процесса. Дефекты с высоким приоритетом обычно классифицируются как непреодолимые, так как они могут помешать пользователю продолжить выполнение поставленной задачи.
Некоторые распространенные примеры дефектов с высоким приоритетом включают:
- Дефекты, из-за которых приложение не работает. сбой
- Дефекты, препятствующие выполнению задачи пользователем
- Дефекты, приводящие к потере или повреждению данных
- Дефекты, раскрывающие конфиденциальную информацию неавторизованным пользователям
- Дефекты, делающие возможным несанкционированный доступ к системе
- Дефекты, приводящие к потере функциональности
- Дефекты, приводящие к неправильным результатам или неточным данным
- Дефекты, вызывающие проблемы с производительностью, такие как чрезмерное использование памяти или медленное время отклика
#4. Срочные дефекты
Срочные дефекты — это дефекты, которые необходимо устранить в течение 24 часов после сообщения о них. В эту категорию попадают дефекты со статусом критической серьезности. Однако дефекты с низким уровнем серьезности также могут быть классифицированы как высокоприоритетные. Например, опечатка в названии компании на домашней странице приложения не оказывает технического влияния на программное обеспечение, но оказывает существенное влияние на бизнес, поэтому считается срочной.
#4. Дополнительные дефекты
#1. Отсутствующие дефекты
Отсутствующие дефекты возникают из-за требований, которые не были включены в продукт. Они также считаются несоответствиями спецификации проекта и обычно негативно сказываются на пользовательском опыте или качестве программного обеспечения.
#2. Неправильные дефекты
Неправильные дефекты — это те дефекты, которые удовлетворяют требованиям, но не должным образом. Это означает, что хотя функциональность достигается в соответствии с требованиями, но не соответствует ожиданиям пользователя.
#3. Дефекты регрессии
Дефект регрессии возникает, когда изменение кода вызывает непреднамеренное воздействие на независимую часть программного обеспечения.
Часто задаваемые вопросы — Типы программных ошибок< /h2>
Почему так важна правильная классификация дефектов?
Правильная классификация дефектов важна, поскольку она помогает эффективно использовать ресурсы и управлять ими, правильно приоритизировать дефекты и поддерживать качество программного продукта.
Команды тестирования программного обеспечения в различных организациях используют различные инструменты отслеживания дефектов, такие как Jira, для отслеживания дефектов и управления ими. Несмотря на то, что в этих инструментах есть несколько вариантов классификации дефектов по умолчанию, они не всегда могут наилучшим образом соответствовать конкретным потребностям организации.
Следовательно, важно сначала определить и понять типы дефектов программного обеспечения, которые наиболее важны для организации, а затем соответствующим образом настроить инструмент управления дефектами.
Правильная классификация дефектов также гарантирует, что команда разработчиков сможет сосредоточиться на критических дефектах и исправить их до того, как они повлияют на конечных пользователей.
Кроме того, это также помогает определить потенциальные области улучшения в процессе разработки программного обеспечения, что может помочь предотвратить появление подобных дефектов в будущих выпусках.
Таким образом, отслеживание и устранение дефектов программного обеспечения может показаться утомительной и трудоемкой задачей. , правильное выполнение может существенно повлиять на качество конечного продукта.
Как найти лежащие в основе ошибки программного обеспечения?
Определение основной причины программной ошибки может быть сложной задачей даже для опытных разработчиков. Чтобы найти лежащие в основе программные ошибки, тестировщики должны применять систематический подход. В этот процесс входят различные этапы:
1) Репликация. Первым этапом является воспроизведение ошибки. Это включает в себя попытку воспроизвести тот же набор шагов, в котором возникла ошибка. Это поможет проверить, является ли ошибка реальной или нет.
2) Изоляция. После того, как ошибка воспроизведена, следующим шагом будет попытка ее изоляции. Это включает в себя выяснение того, что именно вызывает ошибку. Для этого тестировщики должны задать себе несколько вопросов, например:
– Какие входные данные вызывают ошибку?
– При каких различных условиях возникает ошибка?
– Каковы различные способы проявления ошибки?
3) Анализ: после Изолируя ошибку, следующим шагом будет ее анализ. Это включает в себя понимание того, почему возникает ошибка. Тестировщики должны задать себе несколько вопросов, таких как:
– Какова основная причина ошибки?
– Какими способами можно исправить ошибку?
– Какое исправление было бы наиболее эффективным? эффективно?
4) Отчет. После анализа ошибки следующим шагом является сообщение о ней. Это включает в себя создание отчета об ошибке, который включает всю соответствующую информацию об ошибке. Отчет должен быть четким и кратким, чтобы разработчики могли его легко понять.
5) Проверка. После сообщения об ошибке следующим шагом является проверка того, была ли она исправлена. Это включает в себя повторное тестирование программного обеспечения, чтобы убедиться, что ошибка все еще существует. Если ошибка исправлена, то тестер может подтвердить это и закрыть отчет об ошибке. Если ошибка все еще существует, тестировщик может повторно открыть отчет об ошибке.
Заключение
В индустрии программного обеспечения дефекты — неизбежная реальность. Однако благодаря тщательному анализу и пониманию их характера, серьезности и приоритета дефектами можно управлять, чтобы свести к минимуму их влияние на конечный продукт.
Задавая правильные вопросы и применяя правильные методы, тестировщики могут помочь обеспечить чтобы дефекты обнаруживались и исправлялись как можно раньше в процессе разработки.
TAG: qa
Автор: Екатерина Курач
Классификация ODC (Orthogonal Defect Classification — ортогональная классификация дефектов) — это метод, разработанный корпорацией IBM с целью сбора информации о типах неисправностей, которые имеют место в разрабатываемых программных системах. Этот метод полезен при сборе и анализе тестовой информации с тем, чтобы направить усилия совершенствования процесса разработки в нужном направлении. Можно воспользоваться стандартной классификацией, разработанной авторами ODC, в качестве основы для отбора тестовых случаев.
В последние несколько лет наметилась тенденция, когда усилия фирм-разработчиков программного обеспечения направлены на повышение качества своих программных продуктов. Постепенно производители отказываются от «интуитивного» тестирования программ и переходят к формальному тестированию, с написанием тест кейсов.
Но, как известно, полностью протестировать программу невозможно по следующим причинам:
- Количество всех возможных комбинаций входных данных слишком велико, чтоб его можно было проверить полностью.
- Количество всех возможных последовательностей выполнения кода программы также слишком велико, чтобы его можно было протестировать полностью.
- Пользовательский интерфейс программы (включающий все возможные комбинации действий пользователя и его перемещений по программе) обычно слишком сложен для полного тестирования.
Т.е. написать тест кейсы для «полного» тестирования продукта — просто невозможно. Мы можем разработать миллионы тестов, но будет ли время у нас их выполнить? Вероятнее всего — нет. Поэтому приходится тщательно выбирать тест кейсы, которые мы будем проводить.
Характеристики хорошего теста:
- Существует обоснованная вероятность выявления тестом ошибки
- Набор тестов не должен быть избыточным
- Тест должен быть наилучшим в своей категории
- Он не должен быть слишком простым или слишком сложным
В настоящее время наблюдается несколько методологий разработки тест кейсов. Они отличаются и теоретическим подходом, и практической реализацией.
Наиболее часто употребляемая методология разработки тестовых случаев — методология, при которой источниками тестовых случаев выступают случаи использования.
Методология построения тестовых случаев на основе Ортогональной классификации дефектов
Второй широко используемый подход к разработке тест кейсов [первый рассматривался в статье «Методология разработки тестовых случаев на основе сценариев использования»] предлагает задуматься над тем, какие типы дефектов может содержать в себе программный продукт, и написать тестовые случаи, способные их обнаружить. То есть он требует определиться с тем, как система будет использована, и построить тестовые случаи, которые проведут испытание системы на всех этапах использования. Этот подход называется метод целенаправленной проверки и построен на основе классификации ODC.
| Классификация ODC (Orthogonal Defect Classification — ортогональная классификация дефектов) — это метод, разработанный корпорацией IBM с целью сбора информации о типах неисправностей, которые имеют место в разрабатываемых программных системах. Этот метод полезен при сборе и анализе тестовой информации с тем, чтобы направить усилия совершенствования процесса разработки в нужном направлении. Можно воспользоваться стандартной классификацией, разработанной авторами ODC, в качестве основы для отбора тестовых случаев. |
Идея ODC заключается в разделении всех дефектов на типы. Когда программист исправляет дефект, то обычно он исправляет какой-то определенный тип дефекта. Тип определяется видом конечного исправления. Назначение типов является очевидным для программистов. В каждом случае различие проявляется в том, является ли источником ошибки пропущенная часть кода или неправильная часть кода. По методу ODC выделяются следующие типы дефектов:
Функциональной ошибкой является ошибка, которая значительно влияет на возможности продукта, интерфейс для конечного пользователя, интерфейс внутри продукта, интерфейс с конфигурацией аппаратной части или ошибка, которая вызывает глобальный крах системы и требует обязательного изменения дизайна.
Ошибка ассигнования указывает на несколько неверных строчек кода, например на инициализацию контрольных блоков или структуру данных.
Ошибка интерфейса относится к тем видам ошибок, которые связаны с обменом данных с другими компонентами, модулями или драйверами устройств, вызовами процедур, контрольными блоками или списками параметров.
Ошибки проверки связаны ошибками программной логики в тех случаях, когда программа неправильно подтвердила данные и значения перед тем, как их использовать.
Ошибки синхронизации/сериализации — это те ошибки, которые устраняются путем улучшенного управления распределенными ресурсами и ресурсами в реальном времени.
Ошибки билда/пакета/соединения описывают ошибки, которые случаются из-за ошибок в библиотеках, управлении изменениями или контроле версий.
Ошибки документации могут быть связаны как с ошибками публикаций, так и записями управления.
Алгоритмические ошибки включают ошибки, связанные с недостаточной эффективностью или правильностью проблематики, которая влияет на задачу, и может быть исправлена путем внедрения улучшенного алгоритма локальной структуры данных без изменения дизайна.
Выбранные типы дефектов достаточно обобщены для того, чтобы быть применимыми к разработке любого программного продукта, не учитывая его специфику. Степень детализации их такова, что их можно соотнести с любой фазой разработки. На рисунке представлен список дефектов и соотношение этих дефектов с любой стадией разработки.
Список дефектов и соотношение этих дефектов с любой стадией разработки
Тест кейсы разрабатываются в соответствии с тем, какие типы дефектов могут быть найдены в данной программном продукте и соотносятся с видом деятельности разработки. Для того, чтоб определить необходимые группы тест кейсов строится матрица: по осям пишутся виды дефектов и стадии процесса верификации.
Матрица: виды дефектов/стадии процесса верификации
Например, тип дефекта — функциональный — связан с дизайном и можно ожидать, что ошибки такого типа могут быть найдены при изучении high-level дизайна и при проведении функционального тестирования. Аналогично заполняется данная таблица для дефектов других типов. На основе данной таблицы разрабатываются группы тест кейсов. Необходимо заметить, что сейчас разработаны математические алгоритмы для автоматической генерации данных таблиц связей.
Другим основным понятием классификации ODC является понятие «триггеров отказов». Грубо говоря, триггер отказа — это условие, при котором ошибка проявляется. Например, когда продукт собран, предполагается, что все его функции протестированы. Однако, оказывается, что новые ошибки возникают при использовании продукта на другом тестовом окружении, при использовании других аппаратных средств. Таким образом, хоть тип дефекта и тот же самый, необходимо задействовать различные типа триггеров отказов для того, чтоб он проявился. При проявлении ошибки, триггер может быть определен инженером или кем-то, кто разбирается в проблемном диагнозе.
Вот список шести категорий причин отказов, распознаваемых методом ODC:
- Рабочий объем/Повышенная нагрузка
- Нормальный режим
- Восстановление/Исключение
- Пуск/Повторный пуск
- Конфигурация аппаратных средств
- Конфигурация программных средств.
Метод целенаправленной проверки использует несколько таких триггеров в качестве ориентиров для выбора тестовых случаев. Нам необходимо быть уверенными в том, что нам удалось построить тестовые случаи, которые позволяют задействовать каждый из этих триггеров дефектов. Некоторые из категорий, такие как Пуск или Нормальный режим, вряд ли удастся избежать. В то же время категория Исключение напоминает нам, что каждая исключительная ситуация на системном уровне должна быть покрыта тестовыми случаями. Слово Восстановление в названии этой категории также напоминает, что ожидаемые ситуации захвата исключительной ситуации должны быть четко описаны. Однако не всегда возможно продолжать выполнение операций в результате возникновения некоторых исключительных ситуаций, например таких как «File not found». Каждая хорошо спроектированная программа должна быть способной справиться с такой ситуацией.
Категории Аппаратные средства и Конфигурация программного обеспечения менее очевидные, однако не менее важные области, подлежащие тестированию. Например, в случае персональных компьютеров выделение памяти для размещения программного обеспечения может стать источником трудно решаемых проблем, если механизм виртуальной памяти отсутствует или недостаточен.
План тестирования системы должен предусматривать применение некоторого диапазона машин, оснащенных различными аппаратными средствами. Подобным образом конфигурации программного обеспечения также могут служить причиной возникновения проблем. Многие программы могут оказаться сбитыми с толку порядком, в котором библиотеки расположились в пути поиска. Поскольку это не есть дефект самой программы, следовательно, это дефект установочного процесса или документации, сопровождающей программу.
Метод целенаправленной проверки очень эффективен в компаниях, где процесс тестирования и разработки — очень связаны между собой. Как возможно было заметить, типы дефектов классифицированы таким образом, что дефекты одного вида имеют схожие пути исправления. Типы дефектов могут быть связаны с деятельностью на соответствующих стадиях разработки. Т.е. при прохождении одного набора тестов, который соответствует определенному типу дефектов на какой-либо стадии разработки — гораздо легче исправить эти дефекты, путем внесения изменений в строки кода, соответствующие данному набору тест кейсов. Количественная оценка найденных дефектов по классификации ODC дает большое поле для анализа. Например, если на уровне исследования дизайна было найдено много функциональных ошибок, то это значит, что возможно, дизайн не был хорошо продуман и его необходимо переписать или переписать какие-то определенные части кода, в которых было найдено наибольшее число ошибок.
Сложность внедрения ODC заключается в том, что довольно трудоемко применить данный подход к разработке больших неоднородных систем. Увеличивается количество групп тест кейсов и увеличивается вероятность возникновения ошибки в непредсказуемых местах. Также, для введения классификации ODC критичными является наличие следующих факторов: хорошо спроектированные утилиты для отслеживания дефектов и образование людей, занимающихся тестирование (проводится значительное количество различных тестов).
При использовании обеих этих методологий довольно важным вопросом является вопрос измерения тестового покрытия.
|
Покрытие — это мера, показывающая степень доверия, которое мы испытываем по отношению к проводимому тестированию. |
Имеется большое количество атрибутов системы, которые можно использовать для измерения покрытия. По существу, имеются две категории таких атрибутов: вводы и выводы. То есть, можно измерить, сколько возможных вводов было использовано в тестовых случаях, и можно измерить, сколько выводов из числа тех, которые может выдавать эта система, были выданы во время тестирования.
Традиционно покрытие рассматривалось с позиций перспективы тестирования. Типичными следует считать такие метрики, как процентное содержание покрытых строк программного кода или число альтернатив некоторого решения, которые были осуществлены. Часто, пытаются перекрыть все случаи использования системы, взяв в качестве основы соответствующую модель случаев использования. Такой подход хорошо работает, когда надо убедится, что программный продукт делает все то, что он по замыслу должен делать. Если мы сможем получить все требуемые выводы, то этот факт свидетельствует о том, что продукт делает именно то, для чего он предназначен.
Литература:
- Сэм Канер, Джек Фолк, Енг Кек Нгуен. Тестирование программного обеспечения. — Киев: Издательство «Диа Софт», 2001.—544 с.
- Макгрейгор Джон, Сайкс Девид. Тестирование объектно-ориентированного программного обеспечения. Практическое пособие. — Киев: ООО «ТИД «ДС»», 2002.—432 с.
- Официальный сайт Chillarege Inc: http://www.chillarege.com/index.html
Слайд 1Напоминание!
Тестирование = поиск дефектов!
Тестирование- процесс исследования ПО с целью получения информации
о качестве продукта.

Слайд 2Что такое дефект (баг)?
Дефект (он же баг) — это несоответствие фактического результата выполнения
программы ожидаемому результату.

Слайд 3«First actual case of bug being found»

Слайд 4Как определить дефект перед нами или нет?
Программа не делает, то что
она должна делать согласно ТЗ.
Программа делает что-то, чего она не должна делать согласно ТЗ.
Программа делает что-то, о чём в требованиях не упоминалось.
Программа не делает чего-то, о чём не говорится в требованиях , однако подразумевается, что она должна это делать.
Программа трудна для понимания и неудобна в использовании.

Слайд 5Оформление отчёта об ошибке
Цель составления :отчета об ошибке является ее исправление.
Каждое
хорошее описание ошибки должно содержать роено три вещи
Какие шаги привели к ошибке;
Что Вы ожидали, увидеть;
Что Вы на самом деле увидели.
1 отчет в багтреккере на I баг
1 отчет в багтреккере на один итот жебаг, который воспроизводится браузерах/ОС.

Слайд 6Основные типы дефектов ПО
функциональные ошибки

Слайд 7Функциональные ошибки. Примеры:
1. Не сохраняются изменения данных в профиле
2. Не работает
добавление комментария
3. Не работает удаление товара из корзины
4. Не работает поиск

Слайд 8Основные типы дефектов ПО
функциональные ошибки
визуальные ошибки

Слайд 9Визуальные ошибки. Примеры:
1. Текст вылезает за границы поля
2. Элемент управления сайтом
наслаивается на нижестоящий элемент.
3. Не отображается картинка

Слайд 10Основные типы дефектов ПО
функциональные ошибки
визуальные ошибки
логические ошибки

Слайд 11Логические ошибки. Примеры:
1. Можно поставить дату рождения в будущем. 31 февраля,
31 июня и т.д.
2. Можно сделать заказ не указав адрес доставки
3. Неверная работа логики поиска

Слайд 12Основные типы дефектов ПО
функциональные ошибки
визуальные ошибки
логические ошибки
ошибки контента

Слайд 13Ошибки контента. Примеры:
1. Конвертация валют идет по некор-ректному курсу.
2. Орфографические или
пунктуацион-ные ошибки.
3. Картинка товара не соответствует карточке товара

Слайд 14Основные типы дефектов ПО
функциональные ошибки
визуальные ошибки
логические ошибки
ошибки контента
ошибки удобства
использования

Слайд 15Ошибки удобства использования. Примеры:
1. Отсутствие подсветки или текста ошибки при некорректно
заполненных полях формы
2. Сброс значений заполненных полей при некорректной попытке регистрации
3. Перегруженный интерфейс (чрезмерное количество однотипных точек входа)

Слайд 16Основные типы дефектов ПО
функциональные ошибки
визуальные ошибки
логические ошибки
ошибки контента
ошибки удобства
использования
ошибки безопасности

Слайд 17Ошибки безопасности. Примеры:
1. XSS-уязвимости
2. SQL-инъекции

Слайд 18Зачем документируют дефекты
Чтобы не забыть
Чтобы иметь возможность исправлять конкретные проблемы
Чтобы собирать
метрики

Слайд 19Ошибки безопасности. Примеры:
1. XSS-уязвимости
2. SQL-инъекции

Слайд 20Простые правила оформления
Один дефект — один репорт
Говорящее название
Понятное описание

Слайд 21Оформление ошибок. Название
Локатор. Действие для проявления. Проявление. Ожидаемый результат.
Где? Что делал?
Что получилось? Что ожидали?

Слайд 22Оформление ошибок. Описание
1. Предусловия воспроизведения
2. Последовательность действий для воспроизведения
3. Фактический результат
4.
Ожидаемый результат

Слайд 23Оформление ошибок. Доп. инфо
1. Окружение/условия воспроизведения
2. Скриншоты/видео
3. Логи/артефакты работы ПО
4. Атрибуты
ошибки (важность, компонент)

Слайд 24Атрибуты бага: (Summary)
Принцип описания сути(Summary) бага:
Что?
Где?
Когда?, (При каких условиях?)

Слайд 25Практика формулирования Summary бага.
Сформулируйте баг на скриншоте используя принцип: Что, где,

Слайд 26Практика формулирования Summary бага.
Ответ:
Что: Отсутствует выпадающее меню
Где: в пункте Actionc
Когда:
при не выбранном документе.

Слайд 27Серьёзность и Приоритет багов.
СЕРЬЁЗНОСТЬ
S1 Блокирующий (Blocker)
S2 Критический (Critical)
S3 Значительный (Major)
S4 Незначительный
(Minor)
S5 Тривиальный (Trivial)
ПРИОРИТЕТ
P1 Высокий (High)
P2 Средний (Medium)
P3 Низкий (Low)

Слайд 31Жизненный цикл дефекта.
Варианты прохождения багов:
1. (новый)new
(отклоненный)rejected (закрытый)closed
2. new (отложенный)deferred
3. new (принятый)Accepted (открытый)open (исправленный)fixed (закрытый)closed
4. new accepted pen fixed closed (открыт снова)reopend

Слайд 32Дефекты — основной продукт работы тестировщиков !!!

В таком случае, как менеджер тестов, что вы будете делать?
А) Согласиться с командой тестирования, что это дефект
Б) Менеджер теста берет на себя роль судьи, чтобы решить, является ли проблема дефектом или нет
В) договориться с командой разработчиков, что не является дефектом
Для разрешения конфликта, вы (менеджер проекта) берете на себя роль судьи, который решает, является ли проблема продукта дефектом или нет.
Категории ошибок
Классификация дефектов помогает разработчикам программного обеспечения определять приоритеты своих задач и в первую очередь устранить те дефекты, которые больше прочих угрожают работоспособности продукта.
Критический – дефект должен быть устранены немедленно, иначе это может привести к большим потерям для продукта
Например: функция входа на сайт не работает должным образом.
Вход в систему является одной из основных функций банковского сайта, если эта функция не работает, это серьезные ошибки.
Высокий – дефект негативно влияет на основные функции продукта
Например: производительность сайта слишком низкая.
Средний – дефект вносит минимальные отклонения от требований к к продукту
Например: не корректно отображается интерфейс на мобильных устройствах.
Низкий – минимальное не функциональное влияние на продукт
Например: некоторые ссылки не работают.
Решение
После того, как дефекты приняты и классифицированы, вы можете выполнить следующие шаги, чтобы исправить их.
- Назначение: проблемы отправлены разработчику или другому техническому специалисту для исправления и изменило статус на отвечающий.
- График устранения: сторона разработчика берет на себя ответственность на этом этапе, они создадут график для устранения этих дефектов в зависимости от их приоритета.
- Исправление: пока группа разработчиков устраняет дефекты, диспетчер тестов отслеживает процесс устранения проблем, исходя из графика.
- Сообщить о решении: получите отчет об устранении бага от разработчиков, когда дефекты устранены.
Верификация
После того, как команда разработчиков исправила дефект и сообщила об этом, команда тестирования проверяет, действительно ли устранены все заявленные дефекты.
Закрытие
После устранения и проверки дефекта его статус меняется на закрытый. Если он не устранен, вы отправляете уведомление в отдел разработки, чтобы они проверили дефект еще раз.
Составление отчетов
Далее вы должны сообщить правлению текущую ситуацию с дефектами, чтобы получить от них обратную связь. Они должно видеть и понимать процесс управления дефектами, чтобы поддержать вас в случае необходимости.
Как измерить и оценить качество выполнения теста?
Это вопрос, который хочет знать каждый менеджер в тестировании. Есть 2 параметра, которые вы можете рассмотреть следующим образом…
В приведенном выше сценарии можно рассчитать коэффициент отклонения брака (DRR), равный 20/84 = 0,238 (23,8%).
Другой пример: предположительно, в продукте всего 64 дефекта, но ваша группа по тестированию обнаружила только 44 дефекта, т.е. они пропустили 20 дефектов. Следовательно, можно рассчитать коэффициент утечки дефектов (DLR), равный 20/64 = 0,312 (31,2%).
Вывод, качество выполнения теста оценивается по следующим двум параметрам.
Defect reject ratio (DRR) – 23,8%
Defect leakage ratio (DLR) – 31,2%
Чем меньше значение DRR и DLR, тем, соответственно, лучше качество тестирования. Какой диапазон коэффициентов является приемлемым? Этот диапазон может быть определен и принят за основу в проекте исходя из целей, или вы можете ссылаться на показатели аналогичных проектов.
В рассматриваемом нами проекте рекомендуемое значение показателей качества тестирования должно составлять 5 ~ 10%. Это означает, что качество выполнения теста низкое.
Чтобы уменьшить эти коэффициенты:
- Улучшите навыки тестирования участников проекта.
- Тратьте больше времени на выполнение тестов и на просмотр результатов.
Министерство
науки и высшего образования РФ
Федеральное
государственное бюджетное образовательное
учреждение
высшего образования
«Уфимский
государственный авиационный технический
университет»
Факультет
информатики и робототехники
Кафедра
вычислительной математики и кибернетики
Отчет
по лабораторной работе №5
Поиск
и документирование дефектов
по
дисциплине
«Технология
разработки программного обеспечения»
Выполнили:
студент
группы МО-317
Шакиров
А. Р.
Проверил:
старший
преподаватель
Тугузбаев
Гаяз Ахтямович
Уфа
2020
Оглавление
Теоретические
сведения 3
1.
Описание дефектов 4
2.
Ответы на контрольные вопросы 6
Вывод 7
Приложение
А 8
Цель:
Протестировать мобильное приложение
и описать найденные дефекты.
Задачи:
-
Изучить
теоретические сведения. -
Выполнить
практическое задание по лабораторной
работе. -
Оформить
отчёт и ответить на контрольные вопросы.
Теоретические сведения
Дефекты, обнаруженные тестировщиком,
должны быть корректно и понятно описаны,
чтобы разработчик смог воспроизвести
данный дефект и устранить его.
Описание каждого дефекта сохраняется
в специализированной – багтрэкинговой
– системе (например, JIRA, Bugzilla, Mantis, Redmine
и др.) или в предварительно созданном в
программной среде Microsoft Excel файле.
Описание дефекта включает следующие
обязательные поля:
-
Headline –
название дефекта. -
Severity –
степень критичности (важность дефекта). -
Description
– алгоритм воспроизведения. -
Result –
фактический результат. -
Expected
result – ожидаемый результат. -
Attachment –
прикреплённые файлы (приложение).
В багтрэкинговых системах для каждого
дефекта автоматически генерируется
его уникальный номер, в случае использования
Microsoft Excel номер дефекту необходимо
присваивать вручную.
Требование спецификации, которое
нарушает обнаруженный дефект, можно
дополнительно вынести в примечание.
Дополнительно в описании дефекта может
быть указана Priority – степень срочности
исправления дефекта разработчиком.
-
Описание дефектов
Acceptance Sheet – документ, который содержит
подробный перечень всех модулей и
функций приложения, а также результаты
всех тестов данных функций. Как правило,
содержит статистику по наиболее важным
показателям каждой сборки, определяющим
ее качество.
В рамках модуля в качестве функциональных
проверок выступают действия над активными
элементами пользовательского интерфейса
(полями, кнопками, чекбоксами и т.д.).
При составлении тестовой документации
Acceptance Sheet мобильного приложения «Импорт
расписания УГАТУ» в процессе проведения
тестовых проверок были выявлены дефекты,
представленные на рисунке 1.1, их описания,
приведенные в таблице 1.1.

Рис.1.1.
Acceptance Sheet
Таблица 1.1
Описание дефектов
|
№ |
Название дефекта |
Важность |
Алгоритм |
Фактический |
Ожидаемый |
Приложение |
|
1 |
Главный экран: Строка Отсутствие |
Minor |
Шаги по 1. 2. |
Заглушка строки |
Заглушка строки |
Рисунок А.1 |
|
2 |
Главный экран: Кнопки Отсутствие |
Minor |
Шаги по 1. 2. |
Заголовок кнопки |
Заголовок кнопки |
Рисунок А.1 |
|
3 |
Главный экран: Всплывающее Отсутствие |
Minor |
Шаги по 1. 2. 3. 4. |
Текст уведомления |
Текст уведомления |
Рисунок А.2 |
-
Ответы на контрольные вопросы
-
Шакиров Айдар
-
Ответ на вопрос №5 «Что такое Severity в
описании дефекта?»:
Severity (степень критичности). Степень
критичности (серьезности, важности)
показывает степень ущерба, который
наносится проекту существованием
дефекта. В общем случае выделяют следующие
градации критичности дефектов, указанные
в таблице 2.1.1.
Таблица
2.1.1
Степени критичности дефектов
|
№ |
Severity |
Описание |
Примеры |
|
1 |
Critical (критический) |
Функциональная Функциональная |
Заблокирована Неправильно Раскрывается |
|
2 |
Major (значительный) |
Функциональная |
Невозможно Необходимо |
|
3 |
Average (средней |
Не очень важная |
Не работает |
|
4 |
Minor (незначительный) |
Редко встречающиеся 90 |
Введены Грамматические, |
|
5 |
Enhancement (предложение |
Функциональные |
Добавить кнопку |
Вывод
В
ходе лабораторной работы протестировал
мобильное приложение и описал найденные
дефекты.
Приложение А

Рисунок А.1. Отсутствие интернационализации
элементов GUI

Рисунок А.2. Отсутствие интернационализации
текста всплывающего уведомления о
результате операции
Обработка исключительных ситуаций. Методы и способы идентификации сбоев и ошибок.
Конструкция try..catch..finally
Иногда при выполнении программы возникают ошибки, которые трудно предусмотреть или предвидеть, а иногда и вовсе невозможно. Например, при передачи файла по сети может неожиданно оборваться сетевое подключение. такие ситуации называются исключениями. Язык C# предоставляет разработчикам возможности для обработки таких ситуаций. Для этого в C# предназначена конструкция try…catch…finally.
try { } catch { } finally { }
При использовании блока try…catch..finally вначале пытаются выполниться инструкции в блоке try. Если в этом блоке не возникло исключений, то после его выполнения начинает выполняться блок finally. И затем конструкция try..catch..finally завершает свою работу.
Если же в блоке try вдруг возникает исключение, то обычный порядок выполнения останавливается, и среда CLR (Common Language Runtime) начинает искать блок catch, который может обработать данное исключение. Если нужный блок catch найден, то он выполняется, и после его завершения выполняется блок finally.
Если нужный блок catch не найден, то при возникновении исключения программа аварийно завершает свое выполнение.
Рассмотрим следующий пример:
class Program { static void Main(string[] args) { int x = 5; int y = x / 0; Console.WriteLine($"Результат: {y}"); Console.WriteLine("Конец программы"); Console.Read(); } }
В данном случае происходит деление числа на 0, что приведет к генерации исключения. И при запуске приложения в режиме отладки мы увидим в Visual Studio окошко, которое информирует об исключении:
В этом окошке мы видим, что возникло исключение, которое представляет тип System.DivideByZeroException, то есть попытка деления на ноль. С помощью пункта View Details можно посмотреть более детальную информацию об исключении.
И в этом случае единственное, что нам остается, это завершить выполнение программы.
Чтобы избежать подобного аварийного завершения программы, следует использовать для обработки исключений конструкцию try…catch…finally. Так, перепишем пример следующим образом:
class Program { static void Main(string[] args) { try { int x = 5; int y = x / 0; Console.WriteLine($"Результат: {y}"); } catch { Console.WriteLine("Возникло исключение!"); } finally { Console.WriteLine("Блок finally"); } Console.WriteLine("Конец программы"); Console.Read(); } }
В данном случае у нас опять же возникнет исключение в блоке try, так как мы пытаемся разделить на ноль. И дойдя до строки
выполнение программы остановится. CLR найдет блок catch и передаст управление этому блоку.
После блока catch будет выполняться блок finally.
Возникло исключение!
Блок finally
Конец программы
Таким образом, программа по-прежнему не будет выполнять деление на ноль и соответственно не будет выводить результат этого деления, но теперь она не будет аварийно завершаться, а исключение будет обрабатываться в блоке catch.
Следует отметить, что в этой конструкции обязателен блок try. При наличии блока catch мы можем опустить блок finally:
try { int x = 5; int y = x / 0; Console.WriteLine($"Результат: {y}"); } catch { Console.WriteLine("Возникло исключение!"); }
И, наоборот, при наличии блока finally мы можем опустить блок catch и не обрабатывать исключение:
try { int x = 5; int y = x / 0; Console.WriteLine($"Результат: {y}"); } finally { Console.WriteLine("Блок finally"); }
Однако, хотя с точки зрения синтаксиса C# такая конструкция вполне корректна, тем не менее, поскольку CLR не сможет найти нужный блок catch, то исключение не будет обработано, и программа аварийно завершится.
Обработка исключений и условные конструкции
Ряд исключительных ситуаций может быть предвиден разработчиком. Например, пусть программа предусматривает ввод числа и вывод его квадрата:
static void Main(string[] args) { Console.WriteLine("Введите число"); int x = Int32.Parse(Console.ReadLine()); x *= x; Console.WriteLine("Квадрат числа: " + x); Console.Read(); }
Если пользователь введет не число, а строку, какие-то другие символы, то программа выпадет в ошибку. С одной стороны, здесь как раз та ситуация, когда можно применить блок try..catch, чтобы обработать возможную ошибку. Однако гораздо оптимальнее было бы проверить допустимость преобразования:
static void Main(string[] args) { Console.WriteLine("Введите число"); int x; string input = Console.ReadLine(); if (Int32.TryParse(input, out x)) { x *= x; Console.WriteLine("Квадрат числа: " + x); } else { Console.WriteLine("Некорректный ввод"); } Console.Read(); }
Метод Int32.TryParse() возвращает true, если преобразование можно осуществить, и false — если нельзя. При допустимости преобразования переменная x будет содержать введенное число. Так, не используя try…catch можно обработать возможную исключительную ситуацию.
С точки зрения производительности использование блоков try..catch более накладно, чем применение условных конструкций. Поэтому по возможности вместо try..catch лучше использовать условные конструкции на проверку исключительных ситуаций.
Блок catch и фильтры исключений
Определение блока catch
За обработку исключения отвечает блок catch, который может иметь следующие формы:
-
Обрабатывает любое исключение, которое возникло в блоке try. Выше уже был продемонстрирован пример подобного блока.
catch { // выполняемые инструкции }
-
Обрабатывает только те исключения, которые соответствуют типу, указаному в скобках после оператора catch.
catch (тип_исключения) { // выполняемые инструкции }
Например, обработаем только исключения типа DivideByZeroException:
try { int x = 5; int y = x / 0; Console.WriteLine($"Результат: {y}"); } catch(DivideByZeroException) { Console.WriteLine("Возникло исключение DivideByZeroException"); }
Однако если в блоке try возникнут исключения каких-то других типов, отличных от DivideByZeroException, то они не будут обработаны.
-
Обрабатывает только те исключения, которые соответствуют типу, указаному в скобках после оператора catch. А вся информация об исключении помещается в переменную данного типа.
catch (тип_исключения имя_переменной) { // выполняемые инструкции }
Например:
try { int x = 5; int y = x / 0; Console.WriteLine($"Результат: {y}"); } catch(DivideByZeroException ex) { Console.WriteLine($"Возникло исключение {ex.Message}"); }
Фактически этот случай аналогичен предыдущему за тем исключением, что здесь используется переменная. В данном случае в переменную ex, которая представляет тип DivideByZeroException, помещается информация о возникшем исключени. И с помощью свойства Message мы можем получить сообщение об ошибке.
Если нам не нужна информация об исключении, то переменную можно не использовать как в предыдущем случае.
Фильтры исключений
Фильтры исключений позволяют обрабатывать исключения в зависимости от определенных условий. Для их применения после выражения catch идет выражение when, после которого в скобках указывается условие:
В этом случае обработка исключения в блоке catch производится только в том случае, если условие в выражении when истинно. Например:
int x = 1; int y = 0; try { int result = x / y; } catch(DivideByZeroException) when (y==0 && x == 0) { Console.WriteLine("y не должен быть равен 0"); } catch(DivideByZeroException ex) { Console.WriteLine(ex.Message); }
В данном случае будет выброшено исключение, так как y=0. Здесь два блока catch, и оба они обрабатывают исключения типа DivideByZeroException, то есть по сути все исключения, генерируемые при делении на ноль. Но поскольку для первого блока указано условие y == 0 && x == 0, то оно не будет обрабатывать исключение — условие, указанное после оператора when возвращает false. Поэтому CLR будет дальше искать соответствующие блоки catch далее и для обработки исключения выберет второй блок catch. В итоге если мы уберем второй блок catch, то исключение вобще не будет обрабатываться.
Типы исключений. Класс Exception
Базовым для всех типов исключений является тип Exception. Этот тип определяет ряд свойств, с помощью которых можно получить информацию об исключении.
-
InnerException: хранит информацию об исключении, которое послужило причиной текущего исключения
-
Message: хранит сообщение об исключении, текст ошибки
-
Source: хранит имя объекта или сборки, которое вызвало исключение
-
StackTrace: возвращает строковое представление стека вызывов, которые привели к возникновению исключения
-
TargetSite: возвращает метод, в котором и было вызвано исключение
Например, обработаем исключения типа Exception:
static void Main(string[] args) { try { int x = 5; int y = x / 0; Console.WriteLine($"Результат: {y}"); } catch (Exception ex) { Console.WriteLine($"Исключение: {ex.Message}"); Console.WriteLine($"Метод: {ex.TargetSite}"); Console.WriteLine($"Трассировка стека: {ex.StackTrace}"); } Console.Read(); }
Однако так как тип Exception является базовым типом для всех исключений, то выражение catch (Exception ex) будет обрабатывать все исключения, которые могут возникнуть.
Но также есть более специализированные типы исключений, которые предназначены для обработки каких-то определенных видов исключений. Их довольно много, я приведу лишь некоторые:
-
DivideByZeroException: представляет исключение, которое генерируется при делении на ноль
-
ArgumentOutOfRangeException: генерируется, если значение аргумента находится вне диапазона допустимых значений
-
ArgumentException: генерируется, если в метод для параметра передается некорректное значение
-
IndexOutOfRangeException: генерируется, если индекс элемента массива или коллекции находится вне диапазона допустимых значений
-
InvalidCastException: генерируется при попытке произвести недопустимые преобразования типов
-
NullReferenceException: генерируется при попытке обращения к объекту, который равен null (то есть по сути неопределен)
И при необходимости мы можем разграничить обработку различных типов исключений, включив дополнительные блоки catch:
static void Main(string[] args) { try { int[] numbers = new int[4]; numbers[7] = 9; // IndexOutOfRangeException int x = 5; int y = x / 0; // DivideByZeroException Console.WriteLine($"Результат: {y}"); } catch (DivideByZeroException) { Console.WriteLine("Возникло исключение DivideByZeroException"); } catch (IndexOutOfRangeException ex) { Console.WriteLine(ex.Message); } Console.Read(); }
В данном случае блоки catch обрабатывают исключения типов IndexOutOfRangeException, DivideByZeroException и Exception. Когда в блоке try возникнет исключение, то CLR будет искать нужный блок catch для обработки исключения. Так, в данном случае на строке
происходит обращение к 7-му элементу массива. Однако поскольку в массиве только 4 элемента, то мы получим исключение типа IndexOutOfRangeException. CLR найдет блок catch, который обрабатывает данное исключение, и передаст ему управление.
Следует отметить, что в данном случае в блоке try есть ситуация для генерации второго исключения — деление на ноль. Однако поскольку после генерации IndexOutOfRangeException управление переходит в соответствующий блок catch, то деление на ноль int y = x / 0 в принципе не будет выполняться, поэтому исключение типа DivideByZeroException никогда не будет сгенерировано.
Однако рассмотрим другую ситуацию:
static void Main(string[] args) { try { object obj = "you"; int num = (int)obj; // InvalidCastException Console.WriteLine($"Результат: {num}"); } catch (DivideByZeroException) { Console.WriteLine("Возникло исключение DivideByZeroException"); } catch (IndexOutOfRangeException) { Console.WriteLine("Возникло исключение IndexOutOfRangeException"); } Console.Read(); }
В данном случае в блоке try генерируется исключение типа InvalidCastException, однако соответствующего блока catch для обработки данного исключения нет. Поэтому программа аварийно завершит свое выполнение.
Мы также можем определить для InvalidCastException свой блок catch, однако суть в том, что теоретически в коде могут быть сгенерированы сами различные типы исключений. А определять для всех типов исключений блоки catch, если обработка исключений однотипна, не имеет смысла. И в этом случае мы можем определить блок catch для базового типа Exception:
static void Main(string[] args) { try { object obj = "you"; int num = (int)obj; // InvalidCastException Console.WriteLine($"Результат: {num}"); } catch (DivideByZeroException) { Console.WriteLine("Возникло исключение DivideByZeroException"); } catch (IndexOutOfRangeException) { Console.WriteLine("Возникло исключение IndexOutOfRangeException"); } catch (Exception ex) { Console.WriteLine($"Исключение: {ex.Message}"); } Console.Read(); }
И в данном случае блок catch (Exception ex){} будет обрабатывать все исключения кроме DivideByZeroException и IndexOutOfRangeException. При этом блоки catch для более общих, более базовых исключений следует помещать в конце — после блоков catch для более конкретный, специализированных типов. Так как CLR выбирает для обработки исключения первый блок catch, который соответствует типу сгенерированного исключения. Поэтому в данном случае сначала обрабатывается исключение DivideByZeroException и IndexOutOfRangeException, и только потом Exception (так как DivideByZeroException и IndexOutOfRangeException наследуется от класса Exception).
Создание классов исключений
Если нас не устраивают встроенные типы исключений, то мы можем создать свои типы. Базовым классом для всех исключений является класс Exception, соответственно для создания своих типов мы можем унаследовать данный класс.
Допустим, у нас в программе будет ограничение по возрасту:
class Program { static void Main(string[] args) { try { Person p = new Person { Name = "Tom", Age = 17 }; } catch (Exception ex) { Console.WriteLine($"Ошибка: {ex.Message}"); } Console.Read(); } } class Person { private int age; public string Name { get; set; } public int Age { get { return age; } set { if (value < 18) { throw new Exception("Лицам до 18 регистрация запрещена"); } else { age = value; } } } }
В классе Person при установке возраста происходит проверка, и если возраст меньше 18, то выбрасывается исключение. Класс Exception принимает в конструкторе в качестве параметра строку, которое затем передается в его свойство Message.
Но иногда удобнее использовать свои классы исключений. Например, в какой-то ситуации мы хотим обработать определенным образом только те исключения, которые относятся к классу Person. Для этих целей мы можем сделать специальный класс PersonException:
class PersonException : Exception { public PersonException(string message) : base(message) { } }
По сути класс кроме пустого конструктора ничего не имеет, и то в конструкторе мы просто обращаемся к конструктору базового класса Exception, передавая в него строку message. Но теперь мы можем изменить класс Person, чтобы он выбрасывал исключение именно этого типа и соответственно в основной программе обрабатывать это исключение:
class Program { static void Main(string[] args) { try { Person p = new Person { Name = "Tom", Age = 17 }; } catch (PersonException ex) { Console.WriteLine("Ошибка: " + ex.Message); } Console.Read(); } } class Person { private int age; public int Age { get { return age; } set { if (value < 18) throw new PersonException("Лицам до 18 регистрация запрещена"); else age = value; } } }
Однако необязательно наследовать свой класс исключений именно от типа Exception, можно взять какой-нибудь другой производный тип. Например, в данном случае мы можем взять тип ArgumentException, который представляет исключение, генерируемое в результате передачи аргументу метода некорректного значения:
class PersonException : ArgumentException { public PersonException(string message) : base(message) { } }
Каждый тип исключений может определять какие-то свои свойства. Например, в данном случае мы можем определить в классе свойство для хранения устанавливаемого значения:
class PersonException : ArgumentException { public int Value { get;} public PersonException(string message, int val) : base(message) { Value = val; } }
В конструкторе класса мы устанавливаем это свойство и при обработке исключения мы его можем получить:
class Person { public string Name { get; set; } private int age; public int Age { get { return age; } set { if (value < 18) throw new PersonException("Лицам до 18 регистрация запрещена", value); else age = value; } } } class Program { static void Main(string[] args) { try { Person p = new Person { Name = "Tom", Age = 13 }; } catch (PersonException ex) { Console.WriteLine($"Ошибка: {ex.Message}"); Console.WriteLine($"Некорректное значение: {ex.Value}"); } Console.Read(); } }
Поиск блока catch при обработке исключений
Если код, который вызывает исключение, не размещен в блоке try или помещен в конструкцию try..catch, которая не содержит соответствующего блока catch для обработки возникшего исключения, то система производит поиск соответствующего обработчика исключения в стеке вызовов.
Например, рассмотрим следующую программу:
using System; namespace HelloApp { class Program { static void Main(string[] args) { try { TestClass.Method1(); } catch (DivideByZeroException ex) { Console.WriteLine($"Catch в Main : {ex.Message}"); } finally { Console.WriteLine("Блок finally в Main"); } Console.WriteLine("Конец метода Main"); Console.Read(); } } class TestClass { public static void Method1() { try { Method2(); } catch (IndexOutOfRangeException ex) { Console.WriteLine($"Catch в Method1 : {ex.Message}"); } finally { Console.WriteLine("Блок finally в Method1"); } Console.WriteLine("Конец метода Method1"); } static void Method2() { try { int x = 8; int y = x / 0; } finally { Console.WriteLine("Блок finally в Method2"); } Console.WriteLine("Конец метода Method2"); } } }
В данном случае стек вызовов выглядит следующим образом: метод Main вызывает метод Method1, который, в свою очередь, вызывает метод Method2. И в методе Method2 генерируется исключение DivideByZeroException. Визуально стек вызовов можно представить следующим образом:
Внизу стека метод Main, с которого началось выполнение, и на самом верху метод Method2.
Что будет происходить в данном случае при генерации исключения?
-
Метод Main вызывает метод Method1, а тот вызывает метод Method2, в котором генерируется исключение DivideByZeroException.
-
Система видит, что код, который вызывал исключение, помещен в конструкцию try..catch
try { int x = 8; int y = x / 0; } finally { Console.WriteLine("Блок finally в Method2"); }
Система ищет в этой конструкции блок catch, который обрабатывает исключение DivideByZeroException. Однако такого блока catch нет.
-
Система опускается в стеке вызовов в метод Method1, который вызывал Method2. Здесь вызов Method2 помещен в конструкцию try..catch
try { Method2(); } catch (IndexOutOfRangeException ex) { Console.WriteLine($"Catch в Method1 : {ex.Message}"); } finally { Console.WriteLine("Блок finally в Method1"); }
Система также ищет в этой конструкции блок catch, который обрабатывает исключение DivideByZeroException. Однако здесь также подобный блок catch отсутствует.
-
Система далее опускается в стеке вызовов в метод Main, который вызывал Method1. Здесь вызов Method1 помещен в конструкцию try..catch
try { TestClass.Method1(); } catch (DivideByZeroException ex) { Console.WriteLine($"Catch в Main : {ex.Message}"); } finally { Console.WriteLine("Блок finally в Main"); }
Система снова ищет в этой конструкции блок catch, который обрабатывает исключение DivideByZeroException. И в данном случае ткой блок найден.
-
Система наконец нашла нужный блок catch в методе Main, для обработки исключения, которое возникло в методе Method2 — то есть к начальному методу, где непосредственно возникло исключение. Но пока данный блок catch НЕ выполняется. Система поднимается обратно по стеку вызовов в самый верх в метод Method2 и выполняет в нем блок finally:
finally { Console.WriteLine("Блок finally в Method2"); }
-
Далее система возвращается по стеку вызовов вниз в метод Method1 и выполняет в нем блок finally:
finally { Console.WriteLine("Блок finally в Method1"); }
-
Затем система переходит по стеку вызовов вниз в метод Main и выполняет в нем найденный блок catch и последующий блок finally:
catch (DivideByZeroException ex) { Console.WriteLine($"Catch в Main : {ex.Message}"); } finally { Console.WriteLine("Блок finally в Main"); }
-
Далее выполняется код, который идет в методе Main после конструкции try..catch:
Console.WriteLine("Конец метода Main");
Стоит отметить, что код, который идет после конструкции try…catch в методах Method1 и Method2, не выполняется, потому что обработчик исключения найден именно в методе Main.
Консольный вывод программы:
Блок finally в Method2
Блок finally в Method1
Catch в Main: Попытка деления на нуль.
Блок finally в Main
Конец метода Main
Генерация исключения и оператор throw
Обычно система сама генерирует исключения при определенных ситуациях, например, при делении числа на ноль. Но язык C# также позволяет генерировать исключения вручную с помощью оператора throw. То есть с помощью этого оператора мы сами можем создать исключение и вызвать его в процессе выполнения.
Например, в нашей программе происходит ввод строки, и мы хотим, чтобы, если длина строки будет больше 6 символов, возникало исключение:
static void Main(string[] args) { try { Console.Write("Введите строку: "); string message = Console.ReadLine(); if (message.Length > 6) { throw new Exception("Длина строки больше 6 символов"); } } catch (Exception e) { Console.WriteLine($"Ошибка: {e.Message}"); } Console.Read(); }
После оператора throw указывается объект исключения, через конструктор которого мы можем передать сообщение об ошибке. Естественно вместо типа Exception мы можем использовать объект любого другого типа исключений.
Затем в блоке catch сгенерированное нами исключение будет обработано.
Подобным образом мы можем генерировать исключения в любом месте программы. Но существует также и другая форма использования оператора throw, когда после данного оператора не указывается объект исключения. В подобном виде оператор throw может использоваться только в блоке catch:
try { try { Console.Write("Введите строку: "); string message = Console.ReadLine(); if (message.Length > 6) { throw new Exception("Длина строки больше 6 символов"); } } catch { Console.WriteLine("Возникло исключение"); throw; } } catch (Exception ex) { Console.WriteLine(ex.Message); }
В данном случае при вводе строки с длиной больше 6 символов возникнет исключение, которое будет обработано внутренним блоком catch. Однако поскольку в этом блоке используется оператор throw, то исключение будет передано дальше внешнему блоку catch.
Методы поиска ошибок в программах
Международный стандарт ANSI/IEEE-729-83 разделяет все ошибки в разработке программ на следующие типы.
Ошибка (error) — состояние программы, при котором выдаются неправильные результаты, причиной которых являются изъяны (flaw) в операторах программы или в технологическом процессе ее разработки, что приводит к неправильной интерпретации исходной информации, следовательно, и к неверному решению.
Дефект (fault) в программе — следствие ошибок разработчика на любом из этапов разработки, которая может содержаться в исходных или проектных спецификациях, текстах кодов программ, эксплуатационной документация и т.п. В процессе выполнения программы может быть обнаружен дефект или сбой.
Отказ (failure) — это отклонение программы от функционирования или невозможность программы выполнять функции, определенные требованиями и ограничениями, что рассматривается как событие, способствующее переходу программы в неработоспособное состояние из-за ошибок, скрытых в ней дефектов или сбоев в среде функционирования [7.6, 7.11]. Отказ может быть результатом следующих причин:
- ошибочная спецификация или пропущенное требование, означающее, что спецификация точно не отражает того, что предполагал пользователь;
- спецификация может содержать требование, которое невозможно выполнить на данной аппаратуре и программном обеспечении;
- проект программы может содержать ошибки (например, база данных спроектирована без средств защиты от несанкционированного доступа пользователя, а требуется защита);
- программа может быть неправильной, т.е. она выполняет несвойственный алгоритм или он реализован не полностью.
Таким образом, отказы, как правило, являются результатами одной или более ошибок в программе, а также наличия разного рода дефектов.
Ошибки на этапах процесса тестирования. Приведенные типы ошибок распределяются по этапам ЖЦ и им соответствуют такие источники их возникновения:
- непреднамеренное отклонение разработчиков от рабочих стандартов или планов реализации;
- спецификации функциональных и интерфейсных требований выполнены без соблюдения стандартов разработки, что приводит к нарушению функционирования программ;
- организации процесса разработки — несовершенная или недостаточное управление руководителем проекта ресурсами (человеческими, техническими, программными и т.д.) и вопросами тестирования и интеграции элементов проекта.
Рассмотрим процесс тестирования, исходя из рекомендаций стандарта ISO/IEC 12207, и приведем типы ошибок, которые обнаруживаются на каждом процессе ЖЦ.
Процесс разработки требований. При определении исходной концепции системы и исходных требований к системе возникают ошибки аналитиков при спецификации верхнего уровня системы и построении концептуальной модели предметной области.
Характерными ошибками этого процесса являются:
- неадекватность спецификации требований конечным пользователям;
- некорректность спецификации взаимодействия ПО со средой функционирования или с пользователями;
- несоответствие требований заказчика к отдельным и общим свойствам ПО;
- некорректность описания функциональных характеристик;
- необеспеченность инструментальными средствами всех аспектов реализации требований заказчика и др.
Процесс проектирования. Ошибки при проектировании компонентов могут возникать при описании алгоритмов, логики управления, структур данных, интерфейсов, логики моделирования потоков данных, форматов ввода-вывода и др. В основе этих ошибок лежат дефекты спецификаций аналитиков и недоработки проектировщиков. К ним относятся ошибки, связанные:
- с определением интерфейса пользователя со средой;
- с описанием функций (неадекватность целей и задач компонентов, которые обнаруживаются при проверке комплекса компонентов);
- с определением процесса обработки информации и взаимодействия между процессами (результат некорректного определения взаимосвязей компонентов и процессов);
- с некорректным заданием данных и их структур при описании отдельных компонентов и ПС в целом;
- с некорректным описанием алгоритмов модулей;
- с определением условий возникновения возможных ошибок в программе;
- с нарушением принятых для проекта стандартов и технологий.
Этап кодирования. На данном этапе возникают ошибки, которые являются результатом дефектов проектирования, ошибок программистов и менеджеров в процессе разработки и отладки системы. Причиной ошибок являются:
- бесконтрольность значений входных параметров, индексов массивов, параметров циклов, выходных результатов, деления на 0 и др.;
- неправильная обработка нерегулярных ситуаций при анализе кодов возврата от вызываемых подпрограмм, функций и др.;
- нарушение стандартов кодирования (плохие комментарии, нерациональное выделение модулей и компонент и др.);
- использование одного имени для обозначения разных объектов или разных имен одного объекта, плохая мнемоника имен;
- несогласованное внесение изменений в программу разными разработчиками и др.
Процесс тестирования. На этом процессе ошибки допускаются программистами и тестировщиками при выполнении технологии сборки и тестирования, выбора тестовых наборов и сценариев тестирования и др. Отказы в программном обеспечении, вызванные такого рода ошибками, должны выявляться, устраняться и не отражаться на статистике ошибок компонент и программного обеспечения в целом.
Процесс сопровождения. На процессе сопровождения обнаруживаются ошибки, причиной которых являются недоработки и дефекты эксплуатационной документации, недостаточные показатели модифицируемости и удобочитаемости, а также некомпетентность лиц, ответственных за сопровождение и/или усовершенствование ПО. В зависимости от сущности вносимых изменений на этом этапе могут возникать практически любые ошибки, аналогичные ранее перечисленным ошибкам на предыдущих этапах.
Все ошибки, которые возникают в программах, принято подразделять на следующие классы:
- логические и функциональные ошибки;
- ошибки вычислений и времени выполнения;
- ошибки вводавывода и манипулирования данными;
- ошибки интерфейсов;
- ошибки объема данных и др.
Логические ошибки являются причиной нарушения логики алгоритма, внутренней несогласованности переменных и операторов, а также правил программирования. Функциональные ошибки — следствие неправильно определенных функций, нарушения порядка их применения или отсутствия полноты их реализации и т.д.
Ошибки вычислений возникают по причине неточности исходных данных и реализованных формул, погрешностей методов, неправильного применения операций вычислений или операндов. Ошибки времени выполнения связаны с необеспечением требуемой скорости обработки запросов или времени восстановления программы.
Ошибки ввода-вывода и манипулирования данными являются следствием некачественной подготовки данных для выполнения программы, сбоев при занесении их в базы данных или при выборке из нее.
Ошибки интерфейса относятся к ошибкам взаимосвязи отдельных элементов друг с другом, что проявляется при передаче данных между ними, а также при взаимодействии со средой функционирования.
Ошибки объема относятся к данным и являются следствием того, что реализованные методы доступа и размеры баз данных не удовлетворяют реальным объемам информации системы или интенсивности их обработки.
Приведенные основные классы ошибок свойственны разным типам компонентов ПО и проявляются они в программах по разному. Так, при работе с БД возникают ошибки представления и манипулирования данными, логические ошибки в задании прикладных процедур обработки данных и др. В программах вычислительного характера преобладают ошибки вычислений, а в программах управления и обработки — логические и функциональные ошибки. В ПО, которое состоит из множества разноплановых программ, реализующих разные функции, могут содержаться ошибки разных типов. Ошибки интерфейсов и нарушение объема характерны для любого типа систем.
Анализ типов ошибок в программах является необходимым условием создания планов тестирования и методов тестирования для обеспечения правильности ПО.
На современном этапе развития средств поддержки разработки ПО (CASE-технологии, объектно-ориентированные методы и средства проектирования моделей и программ) проводится такое проектирование, при котором ПО защищается от наиболее типичных ошибок и тем самым предотвращается появление программных дефектов.
Связь ошибки с отказом. Наличие ошибки в программе, как правило, приводит к отказу ПО при его функционировании. Для анализа причинно-следственных связей «ошибкаотказ» выполняются следующие действия:
- идентификация изъянов в технологиях проектирования и программирования;
- взаимосвязь изъянов процесса проектирования и допускаемых человеком ошибок;
- классификация отказов, изъянов и возможных ошибок, а также дефектов на каждом этапе разработки;
- сопоставление ошибок человека, допускаемых на определенном процессе разработки, и дефектов в объекте, как следствий ошибок спецификации проекта, моделей программ;
- проверка и защита от ошибок на всех этапах ЖЦ, а также обнаружение дефектов на каждом этапе разработки;
- сопоставление дефектов и отказов в ПО для разработки системы взаимосвязей и методики локализации, сбора и анализа информации об отказах и дефектах;
- разработка подходов к процессам документирования и испытания ПО.
Конечная цель причинно-следственных связей «ошибка-отказ» заключается в определении методов и средств тестирования и обнаружения ошибок определенных классов, а также критериев завершения тестирования на множестве наборов данных; в определении путей совершенствования организации процесса разработки, тестирования и сопровождения ПО.
Приведем следующую классификацию типов отказов:
- аппаратный, при котором общесистемное ПО не работоспособно;
- информационный, вызванный ошибками во входных данных и передаче данных по каналам связи, а также при сбое устройств ввода (следствие аппаратных отказов);
- эргономический, вызванный ошибками оператора при его взаимодействии с машиной (этот отказ — вторичный отказ, может привести к информационному или функциональному отказам);
- программный, при наличии ошибок в компонентах и др.
Некоторые ошибки могут быть следствием недоработок при определении требований, проекта, генерации выходного кода или документации. С другой стороны, они порождаются в процессе разработки программы или при разработке интерфейсов отдельных элементов программы (нарушение порядка параметров, меньше или больше параметров и т.п.).
Источники ошибок. Ошибки могут быть порождены в процессе разработки проекта, компонентов, кода и документации. Как правило, они обнаруживаются при выполнении или сопровождении программного обеспечения в самых неожиданных и разных ее точках.
Некоторые ошибки в программе могут быть следствием недоработок при определении требований, проекта, генерации кода или документации. С другой стороны, ошибки порождаются в процессе разработки программы или интерфейсов ее элементов (например, при нарушении порядка задания параметров связи — меньше или больше, чем требуется и т.п.).
Причиной появления ошибок — непонимание требований заказчика; неточная спецификация требований в документах проекта и др. Это приводит к тому, что реализуются некоторые функции системы, которые будут работать не так, как предлагает заказчик. В связи с этим проводится совместное обсуждение заказчиком и разработчиком некоторых деталей требований для их уточнения.
Команда разработчиков системы может также изменить синтаксис и семантику описания системы. Однако некоторые ошибки могут быть не обнаружены (например, неправильно заданы индексы или значения переменных этих операторов).







