Upload
elle
View
63
Download
3
Embed Size (px)
DESCRIPTION
Тестирование на основе моделей. к.ф.-м.н. В. В. Кулямин ИСП РАН. Тестирование вообще. Тестирование ( IEEE 610, SWEBOK ): Оценка соответствия системы требованиям к ней на основе результатов наблюдения за ее работой в специально подготовленных ситуациях - PowerPoint PPT Presentation
Citation preview
Тестирование на основе моделей
к.ф.-м.н. В. В. КуляминИСП РАН
Тестирование вообще
Тестирование (IEEE 610, SWEBOK):Оценка соответствия системы требованиям к нейна основе результатов наблюдения за ее работойв специально подготовленных ситуациях Система в ходе тестирования должна работать Нужно готовить специальные ситуации – тесты Оценивается соответствие – ищем ошибки Нужна общая оценка – ищем все ошибки
«Обычное» тестирование
1. Придумываем ситуацию2. Оформляем ее в виде сценария взаимодействия
теста с системой3. Понимаем, как должна система вести себя в его
рамках4. Дополняем сценарий проверкой правильности
Результат – тестовый вариант (test case)5. Оцениваем достаточность имеющегося набора
ситуаций: достаточно – конец, нет – goto 1
«Обычное» тестированиеОграниченная очередь размера 3
1. В начале – пуста2. put(X)3. Y = take()4. assert (Y == X)
?
1. В начале – полна2. put(X)3. assert (exception)
Зачем здесь модели?
Распознавание ошибки– ментальная модель правильной работы
Math.abs(-2147483648) = Полнота набора ситуаций
– ментальная модель всех важных ситуаций
При тестировании на основе моделей
модели выделяются явно и заранее
-2147483648
Используемые модели
Конечные автоматы(Finite State Machines, FSM)
Программные контракты(Software Contracts)
...
Конечный автомат (банкомат)Начало
Выбор операции
Авторизация
Карта / Вывести приглашение ввести PIN
Корректный PIN / Вывести менюАвторизация 1
Некорректный PIN / Сообщение
Авторизация 2
Некорректный PIN / Сообщение
Некорректный PIN / Заблокировать карту
Сообщение о блокировке
Сообщение о выдаче баланса
Сообщение о выдаче денег
Запрос баланса / Выдать чек
Запрос денег / Вывести вопрос о сумме
Выбор суммы
Сумма / Выдать деньги
Время / Вывести исходное сообщение
Время / Вывести исходное сообщение
Тестирование на основе FSM
Можно ли проверить, ведет ли себя неизвестная реализация всегда так же, как модель?
При каких условиях это можно сделать?
0
1 2
a/x
a/x
b/x
b/yb/y
a/y
Модель
0
1 2
a/x
a/x
b/x
b/yb/y
a/y
Реализация
Проверка соответствия
Требования к модели Полная определенность Минимальность Сильная связность
Гипотезы о реализации Реализация – конечный автомат с
теми же стимулами и реакциями Полная определенность В начале находимся в начальном
состоянии Число состояний ограничено
0
1 2
a/x
a/x
b/x
b/yb/y
a/y
0
a, b
x, y
1
2
3
0 1b/y
a/x
a/y0 1
b/y
a/x
a/xb/y
0a/x
b/y=
Методы проверки – обход
Построение обхода (transition tour)
aababbs = status – возвращает
идентификатор состоянияsasasbsasbsbs 0x1x1x2y2y0y2 (xxxyyy) 0x1x1x2y2y1x2 (xxxyyx) 0x1x1x2y2y2y2 (xxxyyy)
0
1 2
a/x
a/x
b/x
b/yb/y
a/y
0
1 2
a/x
a/x
b/x
b/y
b/y
a/y
0
1 2
a/x
a/x
b/x
b/yb/y
a/y
Методы проверки – W-метод0
1 2
a/x
a/x
b/x
b/yb/y
a/y
0
1
2
3
reset
0
1 2
a/x
a/x
b/x
b/yb/y
a/y
r = reset – переводит в начальное состояниеS – множество последовательностей, достигающих
всех состоянийS = {ε, a, b}W – множество последовательностей,
различающих все состоянияW = {a, b} – 0:{x, y}; 1:{x, x}; 2:{y, y}S{a,b}W – полный тест {ε, a, b}{a, b}{a, b} = {aa, ab, ba, bb, aaa, aab, aba,
abb, baa, bab, bba, bbb}aarabrbarbbraaaraabrabarabbrbaarbabrbbarbbb xx.xx.yy.yy.xxx.xxx.xxy.xxy.yyy.yyy.yyx.yyy xx.xx.yy.yy.xxx.xxx.xxy.xxy.yyy.yyy.yyy.yyy
S{a,b}m-nW – полный тест для больших реализаций
Другие методы проверки
D-метод
различающая последовательность
u = ba – 0:yy; 1:xy; 2:yx
S{a,b}u
abarbbaraabarabbarbabarbbba Методы, работающие без reset Адаптивные методы
0
1 2
a/x
a/x
b/x
b/yb/y
a/y
Получаемые тесты
abarbbaraabarabbarbabarbbba xxy.yyx.xxxy.xxyx.yyyx.yyyy
z = a(); assert(z == ‘x’);z = b(); assert(z == ‘x’);z = a(); assert(z == ‘y’); reset();…
Тесты теперь можно генерировать полностью автоматически, если выполнены все ограничения на модель
Конечные автоматы – еще не все
Не всякую задачу удобно описывать конечным автоматом
Часто можно только очень большимСложность построения тестов O(p(m-n+1)n3)
Чаще всего ограничения на число состояний в реализации неизвестны
Часто требования недетерминированы Часто результат в некотором состоянии
определен не для всех стимулов
Конечные автоматы – еще не все
Ограниченная очередь размера 3
[X]
[Y]
[X, X]
[X, Y]
[Y, X]
[Y, Y]
[X, X, X]
[X, X, Y]
[X, Y, X]
[X, Y, Y]
[Y, X, X]
[Y, X, Y]
[Y, Y, X]
[Y, Y, Y]
Конечные автоматы – еще не все
Система управления памятьюvoid* malloc(int n)void free(void* m)
malloc(3); malloc(5); malloc(4); malloc(7); malloc(7);
Конечные автоматы – еще не все
Таймер включить сигналсигналсигналвыключить
Барьер
Высота 3
init(3)
wait()
wait()
wait()
Программные контракты
Система – набор взаимодействующих компонентов
Компоненты взаимодействуют с помощью вызовов интерфейсных операций друг друга
Каждая операция имеет Предусловие
Определяет, когда операцию можно вызывать Постусловие
Описывает результаты работы операции
Пример контракта
Вычисление целочисленного логарифма
int logn(int x, int b)
pre (b > 1) & (x > 0)
post blogn ≤ x & blogn+1 > x
Что это дает для тестирования?
Можно тестировать отдельные компоненты большие подсистемы систему в целом
Постусловие дает критерий правильности Тест можно разбить на два компонента
Генератор тестовых данных Оракул – проверяет правильность работы на любых данных
Можно записывать сложные и недетерминированные ограничения
Более сложный пример
АРМ компоновщика заказов Показывает список заказов для обработки Позволяет
Добавить новый заказ в конец списка Добавить срочный заказ в конец подсписка
срочных заказов Пометить заказ как срочный Убрать первый заказ из списка (когда он
обработан)
Контракт добавления заказов
List urgent;List ordinary;int MAX;
boolean addOrdinary(Order o) { pre { return true; } post { if(@ordinary.size + @urgent.size < MAX) return ordinary == @( ordinary.add(o) ) && urgent == @urgent && addOrdinary == true ; else return ordinary == @ordinary && urgent == @urgent && addOrdinary == false ; }}
Контракт переноса заказа в срочные
boolean moveToUrgent(Order o) { pre { return true; } post { if(@( o in ordinary )) return ordinary == @( ordinary.remove(o) ) && urgent == @( urgent.add(o) ) && moveToUrgent == true ; else return ordinary == @ordinary && urgent == @urgent && moveToUrgent == false ; }}
Контракт удаления заказа
Order removeFirst() { pre { return urgent.size != 0 || ordinary.size != 0 ; } post { if(urgent.size != 0) return ordinary == @ordinary && urgent == @( urgent.removeFirst() ) && removeFirst == @( urgent[0] ) ; else return ordinary == @( ordinary.removeFirst() ) && urgent == @urgent && removeFirst == @( ordinary[0] ) ; }}
Что получилось?
Тестируемая система Модель
true / falsetrue / false
Оракул
Что еще надо?
Проверка правильности
Построение тестовых данных
Оценка полноты набора тестов
+
?
?
Полнота тестов
Покрытие кода тестируемых функций Метод функциональных диаграмм
Покрытие постусловия
post {
if ( a <= 0 || c.isActive() ) …
else if( a > 3 & !b.closed() ) …
else …
}
a > 0 && !c.isActive() && a <= 3
|| a > 0 && !c.isActive() && b.closed()
Покрытия контракта и кодаПостусловие Код
Если покрытие постусловия выше, то покрытие кода выше
100% постусловия и 100% кода не следуют друг из друга
Метод функциональных диаграмм
+: int × int → int int = {positive, 0, negative}
Первый аргумент Второй аргумент Пример
pos pos 2, 3
pos 0 2, 0
pos neg 2, -1
0 pos 0, 3
0 0 0, 0
0 neg 0, -1
neg pos -2, 3
neg 0 -2, 0
neg neg -2, -1
Метод функциональных диаграмм
a > 0
F(b) < 5
isActive(c)
f == g(a)-F(b)*b
a == @a + 1
f == -1
a == @a
f == 0
if(a > 0 && F(b) < 5) return f == g(a)-F(b)*b && a == @a + 1;else if(isActive(c)) return f == -1 && a == @a;else return f == 0 && a == @a;
Пример – ветви постусловий
addOrdinary() ordinary.size + urgent.size < MAX ordinary.size + urgent.size == MAX
addUrgent() ordinary.size + urgent.size < MAX ordinary.size + urgent.size == MAX
moveToUrgent(o) ( o in ordinary ) !( o in ordinary )
removeFirst () urgent.size != 0 ordinary.size != 0
adOrNadOrE
adUrNadUrE
mvNmvE
rmUrrmOr
Обобщение состояний, шаг 1
Условия Состояние adOr adUr mv rm
(0, 0) A B D A -
(0, 0 < o < M) B B, C E, F E A, B
(0, M) C C C F B
(0 < u < M, 0) D E, F D, G D A, D
(u, o) u+o < M E E, F E, F E B, E
(u, o) u+o = M F F F F B, E
(M,0) G G G G E
Обобщение состояний, шаг 2
addOrN
addUrN
addOrE, addUrE
mvN
rmUr
mvE
rmOr
ordinary.size
urgent.size
0
0
MAX
MAX
Редукция сложных автоматов
Итоги
Программные контракты Оракул Ветви постусловий – важные ситуации
Построить обход переходов обобщенного автомата
Подготовить тестовые данные (?)
В чем цель тестирования?
(Дейкстра)Тестирование не может подтвердить правильность, но может найти ошибки
=> (?)Цель тестирования – поиск ошибок
<=Тестирование, не находящее ошибок – бесполезно
В чем цель тестирования?
А как бы мы иначе узнали, что ошибок в программе нет?
Тестирование – это метод оценки качества системы Если ошибки есть, оно их должно находить Если их нет, оно должно это подтверждать Оно должно давать еще много информации
Какие части системы наиболее устойчивы Где, вероятно, еще есть ошибки и какого рода Достаточно ли высоко качество системы в целом и стоит ли
тратить усилия на доработку
Модели – способ сделать эту оценку более надежной и объективной