Файл: Отладка и тестирование программ: основные подходы и ограничения (РАЗРАБОТКА ПРОГРАММ).pdf
Добавлен: 30.03.2023
Просмотров: 243
Скачиваний: 2
СОДЕРЖАНИЕ
2.2. Тестирование надежности
Известно, что качество программного обеспечения определяется несколькими признаками:
- функциональные возможности – набор действий, реализующих потребности пользователя;
- надежность – способность программного продукта сохранять свой уровень качества функционирования при установленных условиях;
- практичность - определенный набор атрибутов, относящихся к индивидуальной пользовательской оценке;
- эффективность – соотношение уровня качества функционирования программного продукта и объема потребляемых им ресурсов;
- сопровождаемость – набор атрибутов, необходимых для процессов модификации продукта;
- мобильность – способность переносимости продукта [7].
Понятие надежности также является комплексным свойством. Оно включает в себя следующие понятия:
- безотказность – способность сохранять работоспособное состояние в течение определенного времени;
- долговечность – способность сохранять работоспособное состояние до предельного состояния;
- ремонтопригодность – способность приспосабливаться к поддержанию и восстановлению работоспособного состояния путем обслуживания и ремонта;
- сохраняемость – способность сохранять значения параметров в заданных пределах [5].
Так как в процессе эксплуатации программных продуктов они не изнашиваются, то поломки и ремонт здесь не применяются. Следовательно, надежность характеризуется только с точки зрения безотказности [7].
Для определения надежности программного обеспечения принято использовать следующие свойства:
- стабильность – совокупность свойств программного продукта, которые определяют частоту отказов, вызванных ошибками исходного кода;
- устойчивость – совокупность свойств программного продукта, отражающих его способность поддерживать требуемый уровень пригодности в случае возникновения программных ошибок или нарушении определенного интерфейса;
- восстанавливаемость – совокупность свойств программного продукта, характеризующая его возможность восстанавливать уровень качества функционирования в случае отказа.
Важно отметить, что за безотказность здесь отвечают свойства стабильности и устойчивости, а восстанавливаемость является лишь возможностью восстановления функциональности после отказа [8].
Для оценки стабильности программного продукта принято использовать следующие характеристики [11]:
- вероятность безотказной работы – вероятность того, что в пределах заданного промежутка времени не возникнет поломка. Такой промежуток времени называется наработкой на отказ;
- гамма-процентная наработка до отказа – наработка, в течение которой поломка не возникнет с заданным процентом вероятности;
- средняя наработка до отказа – математическое ожидание наработки до возникновения поломки;
- средняя наработка на отказ – отношение суммарной наработки к его математическому ожиданию;
- интенсивность отказов – условная плотность вероятности поломки, которая определяется при условии, что до рассматриваемого момента времени поломки не было [5];
- параметр потока отказов – отношение математического ожидания количества поломок за достаточно малый период наработки к значению этой наработки;
- осредненный параметр потока отказов – отношение математического ожидания количества поломок за конечный промежуток наработки к значению этой наработки.
Существует целый ряд причин возникновения ошибок в программах:
- процесс проектирования – преобразование и детализация различных представлений. Ошибки могут вноситься на любом из этапов, имея накопительный эффект. Главной причиной здесь является высокая сложность грамотного процесса проектирования программного обеспечения;
- ошибки, вносимые на этапе кодирования – в большинстве случаев эти ошибки вызваны невнимательностью разработчиков и неправильной трактовкой исходных требований [8].
Всего существует два вида ошибок в программном обеспечении:
- функциональные – нарушения программной спецификации – несоответствие каким-либо заявленным требованиям. Такие ошибки ведут к ухудшению функциональности (точности и пригодности);
- нефункциональные – нарушение правил языка программирования, а также некорректное использование библиотечных функций. Такие ошибки являются причинами снижения надежности и ухудшения функциональности. Примеры таких ошибок [11]:
- ошибки использования неинициализированных указателей;
- утечки памяти;
- игнорируемые участки кода;
- отсутствие инициализации интервальных переменных;
- выход за границы диапазонов;
- отсутствие проверки возвращаемых значений и т.п.
Программные ошибки обладают собственным жизненным циклом, который состоит из следующих этапов:
- действие программиста, которое приводит к возникновению ошибки – незнание, опечатка, неверное понимание функциональных особенностей;
- программная ошибка – совокупность конструкций исходного кода, способных привести к некорректным действиям [8];
- срабатывание ошибки – возникновение таких условий в рамках программного кода, при которых выполняются некорректные действия;
- проявление ошибки – негативное влияние ошибки на работоспособность программного обеспечения – аварийное завершение, получение некорректных результатов и т.п. [16]
Принято выделять несколько категорий тяжести ошибки в программном обеспечении, нарушение работоспособности которого могут привести к катастрофическим последствиям [7]:
- катастрофическая – высокая вероятность прекращения функционирования системы в случае возникновения ошибки. Может вызвать повреждение не только системы, но и окружающей среды, а также привести к тяжелым травмам и гибели людей;
- критическая – высокая вероятность прекращения функционирования системы в случае возникновения ошибки. Может вызвать повреждение не только системы, но и окружающей среды, однако, не угрожает здоровью и жизни людей;
- существенная – наблюдается снижение эффективности функционирования программного продукта в случае возникновения ошибки. Может вызвать прекращение работы программного обеспечения без заметных повреждений в системе. Не угрожает здоровью и жизни людей;
- несущественная – может наблюдаться снижение эффективности функционирования программного продукта в случае возникновения ошибки. Практически не приводит к возникновению отказа.
Для оценки надежности программных продуктов применяются различные методы:
- динамические – опираются на результаты выполнения программы. Такие методы позволяют получать абсолютные показатели надежности, однако они характеризуются высокой трудоемкостью сбора исходных данных, используют упрощающие предположения о взаимном влиянии ошибок, а также сильно зависят от качества и объема исходных данных;
- статические – опираются на анализ различных артефактов, полученных на этапе проектирования. Такие методы характеризуются низкой трудоемкостью, они позволяют выполнять оценку автоматически. Минус данных методов в сложности реализации, а также в том, что они не обеспечивают абсолютных показателей надежности [12];
- архитектурные – базируются на анализе архитектуры всей системы, могут включать в себя как статические, так и динамические подходы;
- эмпирические – методы, полученные только на базе информации о процессе проектирования [14].
Все эти методы обладают общими свойствами:
- универсальность по отношению к различным программам;
- универсальность по отношению к различным условиям эксплуатации программного обеспечения;
- стадии применения метода;
- требуемый набор исходных данных;
- сложность получения оценки;
- точность и достоверность оценки [12].
2.3. Финишные этапы разработки
Заключительные этапы разработки программных продуктов предполагают переход от реализации и тестирования системы к ее сопровождению. Под сопровождением понимается процесс внесения изменений в используемую программную систему [6].
Цель вносимых изменений бывает разная:
- исправление системных ошибок;
- улучшение качественных характеристик;
- адаптация системы к изменившимся условиям [9].
В большинстве случаев данный этап реализуется за счет сбора сообщений от пользователей. В различных случаях затраты на сопровождение составляю 40-90% общей стоимости жизненного цикла продукта.
Также на заключительных этапах формируется итоговая документация. В этот момент знания разработчиков о системе максимальны, и они должны быть зафиксированы.
Программная документация является неотъемлемой частью любого процесса разработки. Сюда же относится эксплуатационная документация и сертифицирование программного продукта – регистрация авторских прав, защита от пиратского распространения, а также формирование лицензионного соглашения. Сертификация программного продукта в большинстве случаев является дополнительным внешним тестированием [11].
С целью защиты интересов разработчиков вводится понятие интеллектуальной собственности – совокупность исключительных прав на результаты творческой деятельности и средства индивидуализации.
На финальных этапах разработки очень важно оформить юридические отношения в рамках индивидуальной собственности между тремя основными участника процесса:
- разработчиком;
- заказчиком;
- пользователем.
Интеллектуальные права бывают двух видов:
- авторские права – интеллектуальные права на произведение. Возникают с момента создания и всегда принадлежат гражданам, создавшим произведение. При этом они не зависят от факта регистрации;
- исключительное право – право пользования результатом интеллектуальной деятельности по личному усмотрению [13].
Таким образом, в рамках данной главы рассмотрены виды тестирования, а также финишные этапы разработки программных систем. Отдельно рассмотрен вопрос тестирования программ на примере оценки их надежности.
3. ПРАКТИЧЕСКАЯ ЧАСТЬ
3.1. Разработка приложения
В рамках практической части разработаем приложение на языке С++, целью которого будет работа с двумерной матрицей:
- ввод размерности;
- ввод матрицы;
- вывод матрицы на экран;
- поиск максимального и минимального значений.
Исходный код программы выглядит следующим образом:
#include <iostream>
using namespace std;
void main()
{
int m,n,min,max;
int mas[][];
cout<<"m = ";
cin>>m;
cout<<"n = ";
cin>>n;
cout<<"Enter matrix:"<<endl;
for (int i=0; i<m; i++)
for (int j=0; j<n; j++)
cin>>mas[i][j];
min=0; max=0;
for (int i=0; i<m; i++)
for (int j=0; j<n; j++)
{
if (mas[i][j]<min)
min=mas[i][j];
if (mas[i][j]<max)
max=mas[i][j];
}
cout<<"Matrix:"<<endl;
for (int i=0; i<m; i++)
{
for (int j=0; j<n; j++)
cout<<mas[i][j]<<" ";
cout<<endl;
}
cout<<"Max = "<<max<<endl;
cout<<"Min = "<<min<<endl;
system("pause");
}
3.2. Корректность программы
Корректностью программного кода называется степень соответствия исходных программ формализованным правилам языков спецификаций и программирования [7].
В современных средах программирования корректность программы определяется на этапе компиляции.
Компиляция написанной программы в среде разработки Dev-C++ 5.11 происходит с ошибками, представленными на рисунке 3 [8].
Данные сообщения говорят о следующих ошибках:
- функция main() должна иметь целочисленный тип и возвращаемое значение [19];
- неверно объявлен двумерный массив.
Рисунок 3 – Проверка корректности программы
Для устранения ошибок компиляции выполняются следующие действия:
- функции main присвоен тип int;
- добавлена строка «return 0»;
- инициализация массива изменена на «int mas[10][10]».
Результат компиляции исправленной программы приведен на рисунке 4 [2].
Рисунок 4 – Результат успешной компиляции
3.3. Тестирование, отладка и анализ
Этап отладки программы неразрывно связан с ее тестированием. Тестирование будет проводиться на трех примерах (см. таблицу 2). Результаты тестов приведены на рисунках 5-7 [11].
Таблица 2 – Тестирование
|
Тест |
Исходные данные |
Ожидаемый результат |
|
1 |
n=3 m=3 1 2 3 4 5 6 7 8 9 |
1 2 3 4 5 6 7 8 9 min = 1, max = 9 |
|
2 |
n = 3 m = 3 -1 0 3 2 4 5 0 9 1 |
-1 0 3 2 4 5 0 9 1 min = -1, max = 9 |
|
3 |
n = 3, m = 3 -1 -2 -3 -4 -5 -6 -7 -8 -9 |
-1 -2 -3 -4 -5 -6 -7 -8 -9 min = -9, max = -1 |