【问题标题】:How to reach directly any state in a state-machine written with Boost MSM如何在使用 Boost MSM 编写的状态机中直接达到任何状态
【发布时间】:2020-01-09 21:33:46
【问题描述】:

我目前正在使用 Boost MSM 库来编写状态机,并且我想编写单元测试来检查其状态之间的转换。对于每个单元测试,我需要编写重复的代码行以达到我想要开始的状态。因此,我想知道它们是否是一种在给定状态而不是启动状态下启动状态机的方法。

例如,如果我有一个像这样的简单状态机,通常从 StartingState 开始,我想直接到达 IdleState 进行测试:

  • --> StartingState --> IdleState --> ErrorState

【问题讨论】:

    标签: c++ unit-testing boost state-machine boost-msm


    【解决方案1】:

    Boost.MSM 不直接支持您想要的功能。

    但是您可以使用initial_state 内部类型和预处理器宏来控制初始状态。

    假设您的状态机在sm1.hpp 中定义。

    sm1.hpp

    #include <iostream>
    #include <boost/msm/back/state_machine.hpp>
    
    #include <boost/msm/front/state_machine_def.hpp>
    #include <boost/msm/front/functor_row.hpp>
    
    namespace msm = boost::msm;
    namespace msmf = boost::msm::front;
    namespace mpl = boost::mpl;
    
    // ----- Events
    struct Event1 {};
    
    // Test helper code
    #if !defined(TEST_SM1_STATE)
    #define TEST_SM1_STATE StartingState
    #endif //!defined(TEST_SM1_STATE)
    
    // ----- State machine
    struct Sm1_:msmf::state_machine_def<Sm1_> {
        // States
        struct StartingState:msmf::state<> {
            // Entry action
            template <class Event,class Fsm>
            void on_entry(Event const&, Fsm&) {
                std::cout << "StartingState::on_entry()" << std::endl;
            }
        };
        struct IdleState:msmf::state<> {
            // Entry action
            template <class Event,class Fsm>
            void on_entry(Event const&, Fsm&) {
                std::cout << "IdleState::on_entry()" << std::endl;
            }
        };
        struct ErrorState:msmf::state<> {
            // Entry action
            template <class Event,class Fsm>
            void on_entry(Event const&, Fsm&) {
                std::cout << "ErrorState::on_entry()" << std::endl;
            }
        };
    
        // Set initial state
        using initial_state = TEST_SM1_STATE;
    
        // Transition table
        struct transition_table:mpl::vector<
            //          Start          Event   Next        Action      Guard
            msmf::Row < StartingState, Event1, IdleState,  msmf::none, msmf::none >,
            msmf::Row < IdleState,     Event1, ErrorState, msmf::none, msmf::none >
        > {};
    };
    
    // Pick a back-end
    typedef msm::back::state_machine<Sm1_> Sm1;
    

    test.cpp

    #define TEST_SM1_STATE IdleState
    #include "sm1.hpp"
    
    int main() {
        Sm1 sm1;
        sm1.start(); 
    }
    

    演示:https://wandbox.org/permlink/dnLrAZ7fTJhg473q

    关键点如下代码:

    // Set initial state
    using initial_state = TEST_SM1_STATE;
    

    您可以将任何状态设置为初始状态。 在包含sm1.hpp 之前定义初始状态,如下所示:

    #define TEST_SM1_STATE IdleState
    #include "sm1.hpp"
    

    【讨论】:

      猜你喜欢
      • 2013-05-22
      • 1970-01-01
      • 1970-01-01
      • 2017-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多