Гоша, это не так сложно, как кажется. Код конечного автомата очень прост и короток.
Сохраните состояние в переменной, скажем, в myState.
Ваша конечная машина будет оператором switch, разветвляющимся по значению переменной myState для выполнения кода для каждого состояния.
Код будет заполнен такими строками:
myState = newState;
Чтобы обеспечить соблюдение требований перехода между состояниями, вам нужно вместо этого добавить небольшой метод, например такой
void DoSafeStateTransition( int newState )
{
// check myState -. newState is not forbidden
// lots of ways to do this
// perhaps nested switch statement
switch( myState ) {
…
case X: switch( newState )
case A: case B: case Z: HorribleError( newState );
break;
...
}
// check that newState is not undetermined
switch( newState ) {
// all the determined states
case A: case B: case C … case Z: myState = newState; break;
default: HorribleError( newState );
}
}
void HorribleError( int newState )
{ printf("Attempt to go from %d to %d - disallowed\n",
myState, newState );
exit(1);
}
Я предполагаю, что это просто и достаточно коротко, чтобы проверка работала лучше, чем модульное тестирование - это, безусловно, будет намного быстрее!
На мой взгляд, смысл модульного тестирования в том, чтобы тестовый код был проще тестируемого кода, чтобы его было легче проверить на правильность, а затем использовать для тестирования сложного кода. Часто проще проверить код конечного автомата, чем тестовый код конечного автомата. Нет особого смысла сообщать о 100% прохождении юнит-тестов, если вы плохо представляете, верны ли юнит-тесты.
Скажем иначе: написать конечный автомат легко, а спроектировать правильный — сложно. Модульные тесты сообщат вам только о том, правильно ли вы закодировали дизайн, а не о том, был ли дизайн правильным.
person
ravenspoint
schedule
24.04.2010