1

We are using the boost statechart library and have troubles writing unit tests for the code.

In our normal execution the state machine starts in ClosedState:

struct BoostStateMachine : sc::state_machine<BoostStateMachine, ClosedState >

We would like to test a specific state transition without having to traverse the state machine till that state, for example we would like to start the test in AnotherState. The problem is that sc::state_machine is templated on its initial state. Feeding the state machine with all the events that lead to the tested states, usually requires a lot of work and complicates the tests.

A primitive solution is to write special debug-only event and add it to ClosedState. This event will trigger an immediate transition to AnotherState.

Do you know any other way to accomplish the task?

FireAphis
  • 6,650
  • 8
  • 42
  • 63

1 Answers1

0

I'll admit it's not great, but

#ifdef DEBUG
typedef AnotherState StartingState;
#else
typedef ClosedState StartingState;
#endif
struct BoostStateMachine : sc::state_machine<BoostStateMachine, StartingState > {...

EDIT addressing comment

#ifndef INITIAL_STATE
#define INITIAL_STATE ClosedState
#endif
struct BoostStateMachine : sc::state_machine<BoostStateMachine, INITIAL_STATE > {...

of course that means you need to recompile to do each test =[

We could try the following:

typedef<class InitialState>
struct StateMachine : sc::state_machine< typename /*?*/ StateMachine<InitialState>, InitialState > {...}

typedef StateMachine<ClosedState> BoostStateMachine; //default case

#ifdef DO_TESTS
    ...
    StateMachine<AnotherState> astate1;
    ...
    StateMachine<AnotherState2> astate2;
    ...
    StateMachine<AnotherState3> astate3;
    ...
#endif

This of course does not help when it's a substate that needs to start in a different state. But the same thing could apply:

typedef <typename InitialChild>
struct ClosedState : sc::simple_state< ClosedState<InitialChild>, BoostStateMachine, InitialChild > {...};

or something like it. I have done templated states before (so that I could have common sub-state sequences) and it is a royal PITA to debug (more so that the rest of statechart).

KitsuneYMG
  • 12,753
  • 4
  • 37
  • 58
  • Won't work because we naturally want many test cases that start with different states. – FireAphis Nov 17 '10 at 14:55
  • @FireAphis see edit in my original post for another way for another way – KitsuneYMG Nov 17 '10 at 18:32
  • Thanks for the elaborated answer. I guess, technically, I don't really need the DO_TESTS ifdef because these types won't be used in the production code anyway. Right? – FireAphis Nov 22 '10 at 08:13
  • @FireAphis Since Boost.Statechart use compile time meta-programming to do a lot of its magic, you should include the `ifdef DO_TESTS` so that your compiler doesn't waste time instantiating those test-types. It is true that a decent optimizer will completely eliminate the test-code from runtime, but your compile-time could/will be much larger if you don't remove the tests. – KitsuneYMG Nov 22 '10 at 13:08