четверг, 13 декабря 2012 г.

State-Transition Testing

State-Transition Testing



Вступление

State-Transition testing, как и decision tables testing, отличный инструмент для фиксирования требований и описания дизайна приложения. В отличии от Decision tables testing, которые описывают конкретное состояние приложения, State-Transition testing описывают как эти состояния приложения могут меняться. Диаграммы определяют все события, которые возникают во время работы приложения, и как приложение реагирует на эти события.

Подход

Использование техники State-Transition testing легче объяснять сразу в работе, на примерах. Разберем 2 вида визуального представления этой техники:
 * State-Transition Diagrams (диаграмы)
 * State-Transition Tables (таблицы)

State-Transition Diagrams

Разберем пример резервации авиабилетов. Работает она следующим образом.

Сначала, мы как клиенты, предоставляем авиакомпании информацию для резервации - место отправления, место прибытия, дату и время отправления. Служащий авиакомпании служит интерфейсом между нами и системой резервации авиабилетов, и использует предоставленную нами информацию для создания резервации. После этого наша резервация находиться в состоянии "Made" (сделана). Вдобавок, после создания резервации, система резервации, запускает таймер. Если таймер выходит, а зарезервированный билет не оплачен - система отменяет резервацию.
В виде State-Transition diagrams это будет выглядеть так:




Круг представляет собой состояние системы резервации авиабилетов, в нашем случае это "Made" состояние. Стрелка показывает переход в состояние "Made". Описание под стрелкой ("giveInfo") это событие исходящие извне системы. Команда, в описании под стрелкой (после "/"), говорит нам, что система сделала какое то действие в ответ на событие, в нашем случае это запуск таймера. Черная точка указывает на начало/вход диаграммы.





Далее. Если таймер не истекает и мы оплатили зарезервированный билет, то система приобретает состояние "Paid" (оплаченный). Это показано стрелкой "payMoney" (заплатить деньги) и переходом из состояния "Made" в состояние "Paid".

Перед тем как продолжим стоит определиться с понятиями:

 * Состояние (state)(представленное в виде круга на диаграмме) - это состояние приложения, в котором оно ожидает 1 или более событий. Состояние помнит входные данные полученные до этого и показывает как приложение будет реагировать на полученные события. События могут вызывать смену состояния и/или инициировать действия.
 * Переход (transition) (представленное в виде стрелки на диаграмме) - представляет переход одного состояния в другое, происходящий по событию.
 * Событие (event) (представленное ярлыком над стрелкой) - событие это что то, что заставляет приложение поменять свое состояние. Cобытия могут поступать извне приложения, поступающие через интерфейс приложения. Так же само приложение может генерировать события, например как событие "истек таймер". Когда происходит событие приложение может поменять состояние или остаться в том же состоянии и/или выполнить действие. События могут иметь параметры, например событие "payMoney" может иметь параметры "Cash", "Check", "Debit Card", или "Credit Card".
 * Действие (action) (представлено после "/" в ярлыке над преходом) - это действие инициированное сменой состояния. Это может быть "напечатать билет", "показать на экране" и др. Обычно действия создают что то, что является выходными/возвращаемыми данными системы. Действия возникают при переходах, сами по себе состояния пассивны.
 * Точка входа показывается на диаграмме как черная точка.
 * Точка выхода показывается на диаграмме как мишень.

Вернемся к нашей диаграмме резервации.

Из состояния "Paid" должен быть переход в состояние "Ticketed" (обилечен), когда билет будет напечатан и передан нам в руки. Обратите внимание, что при переходе в состояние "Ticketed", авиабилет (Ticket) является входными данными состояния.



Из состояния "Ticketed" мы переходим в состояние "Used" (использованный), когда отдаем свой билет персоналу аэропорта, при посадке в самолет.



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



Но эта диаграмма показывает еще не все возможные состояния и переходы в жизненном цикле резервации. Начнем дополнять.

Если резервация не оплачена по истечению таймера, то она отменяется как не оплаченная.



Иногда клиенты отменяют заказы из состояния "Made". На это дело нам нужно еще 1 состояние "Cancelled By Customer".



Так же, клиент может отменить резервацию на состоянии "Paid". В этом случае состояние тоже становиться "Cancelled By Customer" и стоимость билета клиенту возмещают.



Отменить резервацию можно и с состояния "Ticketed". В этом случае состояние опять становиться "Cancelled By Customer" и авиакомпания возмещает стоимость билета клиенту. Но! Компания возместит стоимость билета только тогда, когда клиент вернет билет. Этот случай представляет еще один не описанный элемент диаграмм - квадратные скобки " [ ] ", которые представляют условие к переходу. Переход в состояние в этом случае случится только если условие (то что в " [ ] ") =  true.



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

State-Transition Tables

State-Transition Tables имеет не такой наглядный вид, зато более полный и систематизированный. State-transition tables состоит из 4ех столбцов - Текущее состояние (Current State), Событие (Event), Действие (Action) и Следующее состояние (next state).

Опишем уже известный нам процесс резервации авиабилетов с помощью State-Transition Table:

Текущее состояниеСобытиеДействиеСледующее состояние
nullgiveInfostartPayTimerMade
nullpayMoney--null
nullprint--null
nullgiveTicket--null
nullcancel--null
nullPayTimerExpires--null




MadegiveInfo--Made
MadepayMoney--Paid
Madeprint--Made
MadegiveTicket--Made
Madecancel--Can-Cust
MadePayTimerExpires--Can-NonPay




PaidgiveInfo--Paid
PaidpayMoney--Paid
PaidprintTicketTicketed
PaidgiveTicket--Paid
PaidcancelRefundCan-Cust
PaidPayTimerExpires--Paid




TicketedgiveInfo--Ticketed
TicketedpayMoney--Ticketed
Ticketedprint--Ticketed
TicketedgiveTicket--Used
TicketedcancelRefundCan-Cust
TicketedPayTimerExpires--Ticketed




UsedgiveInfo--Used
UsedpayMoney--Used
Usedprint--Used
UsedgiveTicket--Used
Usedcancel--Used
UsedPayTimerExpires--Used




Can-NonPaygiveInfo--Can-NonPay
Can-NonPaypayMoney--Can-NonPay
Can-NonPayprint--Can-NonPay
Can-NonPaygiveTicket--Can-NonPay
Can-NonPaycancel--Can-NonPay
Can-NonPayPayTimerExpires--Can-NonPay




Can-Custgivelnfo--Can-Cust
Can-CustpayMoney--Can-Cust
Can-Custprint--Can-Cust
Can-CustgiveTicket--Can-Cust
Can-Custcancel--Can-Cust
Can-CustPayTimerExpires--Can-Cust

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

Создание тест кейсов

State-Transition Diagrams могут быть легко использованы для создания тест кейсов. Необходимо создать набор тест-кейсов, который должен пройти по всем переходам хотя бы раз.



Из State-Transition Tables тоже достаточно легко делать тест кейсы. Стоит пройтись по всем валидным комбинациям (если есть время или не позволяют рискиможно пройтись и по всем невалидным комбинациям). В таблице отмечены все валидные комбинации жирным:

Текущее состояниеСобытиеДействиеСледующее состояние
nullgiveInfostartPayTimerMade
nullpayMoney--null
nullprint--null
nullgiveTicket--null
nullcancel--null
nullPayTimerExpires--null




MadegiveInfo--Made
MadepayMoney--Paid
Madeprint--Made
MadegiveTicket--Made
Madecancel--Can-Cust
MadePayTimerExpires--Can-NonPay




PaidgiveInfo--Paid
PaidpayMoney--Paid
PaidprintTicketTicketed
PaidgiveTicket--Paid
PaidcancelRefundCan-Cust
PaidPayTimerExpires--Paid




TicketedgiveInfo--Ticketed
TicketedpayMoney--Ticketed
Ticketedprint--Ticketed
TicketedgiveTicket--Used
TicketedcancelRefundCan-Cust
TicketedPayTimerExpires--Ticketed




UsedgiveInfo--Used
UsedpayMoney--Used
Usedprint--Used
UsedgiveTicket--Used
Usedcancel--Used
UsedPayTimerExpires--Used




Can-NonPaygiveInfo--Can-NonPay
Can-NonPaypayMoney--Can-NonPay
Can-NonPayprint--Can-NonPay
Can-NonPaygiveTicket--Can-NonPay
Can-NonPaycancel--Can-NonPay
Can-NonPayPayTimerExpires--Can-NonPay




Can-Custgivelnfo--Can-Cust
Can-CustpayMoney--Can-Cust
Can-Custprint--Can-Cust
Can-CustgiveTicket--Can-Cust
Can-Custcancel--Can-Cust
Can-CustPayTimerExpires--Can-Cust

Ну вот и всё. Надеюсь получилось понятно описать суть техники.

Заимствованно с http://w1zle.blogspot.ru

Комментариев нет:

Отправить комментарий