boost statechart, unit-testing fraction of a state-machine - c++

I'm looking for a way to execute (for unit-testing purposes) only fractions of a complex state -machine. For that purpose I'm evaluating boost::statechart framework.
One way that I considered was to design a hierarchical state machine, where each state is defined as a nested state-machine, that should be tested separately.
Consider the FSM definition from the following code snippet:
struct Fsm: boost::statechart::state_machine< Fsm, StateA >
{
...
}
struct StatA : boost::simple_state< StateA, Fsm, StateA1 >
{
...
}
struct StateB : boost::simple_state< StateB, Fsm, StateB1 >
{
....
}
struct StateA1 : boost::simple_state< StateA1, StateA >
{
....
}
struct StateA2 : boost::simple_state< StateA2, StateA >
{
....
}
struct StateB1 : boost::simple_state< StateB1, StateB >
{
....
}
struct StateB2 : boost::simple_state< StateB2, StateB >
{
....
}
Is it possible to unit-test the logic defined inside state B i.e. B1 and B2 inner states, without executing or even compiling the logic defined for state A including its inner A1 and A2 states?
Thanks in advance,
AmirH

Related

How to implement the State design pattern?

Let's say I am going to implement (in the C++) following finite state machine consisting of 5 states where the transitions between the states occur based on value of 6 boolean flags. In each of the states only a couple of the total number of the boolean flags is relevant e.g. in the State_A the transition into the State_B is conditional by following condition: flag_01 == true && flag_02 == true and the value of the rest of the flags is irrelevant.
I would like to exploit the State design pattern for implementation of the state machine
I have unfortunately stuck at the very beginning. Namely on definition of the interface of the common base class for all the state subclasses. It seems to me that my situation is little bit different from the examples mentioned in the literature where the state transitions occur based on single events with a guard condition. Can anybody give me an advice how to define the interface for the common base class in my situation where the transitions between states occur based on logic expressions with several operands?
You can create some reducer which will decide what state should be user. Let me show an example via C#.
This is an abstraction of state:
public interface IAtmMachineState
{
void Execute();
}
and its concrete states:
public class WithdrawState : IAtmMachineState
{
public void Execute()
{
Console.WriteLine("You are taking money");
}
}
public class DepositState : IAtmMachineState
{
public void Execute()
{
Console.WriteLine("You are putting money");
}
}
public class SleepState : IAtmMachineState
{
public void Execute()
{
Console.WriteLine("Insert your card");
}
}
and this is context of state:
public class AtmStateContext
{
private IAtmMachineState _currentState;
public AtmStateContext()
{
_currentState = new SleepState();
}
public void SetState(IAtmMachineState currentState)
{
_currentState = currentState;
}
public void Execute()
{
_currentState.Execute();
}
}
And this is a reducer which can take parameters:
public class StateReducer
{
public IAtmMachineState Get(int a, string b)
{
if (a == 0)
return new WithdrawState();
else if (!string.IsNullOrEmpty(b))
return new DepositState();
return new SleepState();
}
}
And it can be used like this:
AtmStateContext atmState = new AtmStateContext();
StateReducer stateReducer = new StateReducer();
atmState.SetState(stateReducer.Get(1, ""));
atmState.Execute(); // OUTPUT: insert your card

State Machine Change State

I'm continuously running into the same problem, and can't fix it even when looking through tutorials.
I've "set up" my State machine, but I can't transition between states.
Here is my StateMachine:
class StateMachine
{
State* m_State;
public:
StateMachine();
~StateMachine();
void changeState(State* state);
};
And here is an example State:
class A : State
{
public:
A();
~A();
void handleInput(int a);
}
If I pass a = 1 into A::handleInput() I want to transition to State B. But when I implement it I can't access the StateMachine from A::handleInput(), making me scrub my head in agony.
But when I implement it I can't access the StateMachine from A::handleInput()
Well, that's a well known problem with the State Pattern, that there's no mention how to keep the state classes in track with an enclosing State Machine.
IMO, that's one of the valid use cases to consider the StateMachine class as being implemented as a Singleton.
This way it's instance would be accessible from any Stateclass implementation.
As I'm talking in terms of Design Patterns here, the State classes could be designed with help of the Flyweight Pattern, since they're usually stateless themselves.
I've once driven all that into a c++ template framework, which abstracts the interfaces of State and State Machine (see link below).
Here's a short code example by these means:
StateMachine.h
struct State {
virtual void handleInput(int x) = 0;
virtual ~State() {} = 0;
};
class StateMachine {
State* m_State;
StateMachine();
public:
static StateMachine& instance() {
static StateMachine theInstance;
return theInstance;
}
void changeState(State* state) {
m_State = state;
}
void triggerInput(int x) {
m_State->handleInput(x);
}
};
StateA.h
#include "StateMachine.h"
class StateB;
extern StateB* stateB;
class StateA : public State {
public:
virtual ~StateA() {}
virtual void handleInput(int x) {
if(x == 1) {
// Change to StateB
StateMachine::instance.changeState(stateB);
}
else {
// Do something with x
}
}
};
I omit the definition od StateB here, should be the same manner as StateA.
References:
C++ Singleton Design Pattern
State machine template class framework for C++
I've taken a look at the Sourcemaking example and for me the implementation example really sucks; having to create new instances upon every state change:
https://sourcemaking.com/design_patterns/state/cpp/1
Personally as someone who's designed state machines in electronics with JK flip flops, I would use a similar but semantically different approach. The complexity in state machines involves the action performed according to the state and input; typically in C you would do this with lots of switch statements and possibly arrays describing how to handle the current state and new input aka event.
So to me the OO approach to this would be to model the event handler. This would have an interface which describes the format of the inputs. You then have different implementations of that interface for each different state. With that, the state machine can simply implement a collection of states to event handlers - array, vector or map. Although the handlers still may contain case statements, the overall spaghettiness is very much reduced. You can easily extend the design with new state handlers as and when necessary:
So you could have something like this:
#include <map>
typedef enum
{
//TODO : state list, e.g.
eOff,
eOn
}
teCurrentState;
typedef struct
{
//TODO : Add inputs here, e.g.
bool switch1;
}
tsInputDesc;
typedef struct
{
//TODO : Add outputs here, e.g.
bool relay1;
}
tsOutputDesc;
// ------------------------------------------------
class IEventHandler
{
public:
virtual ~IEventHandler() {}
// returns new state
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) = 0;
};
// ------------------------------------------------
class OnStateHandler : public IEventHandler
{
public:
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) override
{
//TODO : IMPLEMENT
teCurrentState newState = TODO....
return (newState);
}
};
// ------------------------------------------------
class OffStateHandler : public IEventHandler
{
public:
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) override
{
//TODO : IMPLEMENT
teCurrentState newState = TODO....
return (newState);
}
};
// ------------------------------------------------
class StateMachine
{
protected:
teCurrentState mCurrentState;
std::map<teCurrentState, IEventHandler*> mStateHandlers;
void makeHandlers()
{
mStateHandlers[eOff] = new OffStateHandler();
mStateHandlers[eOn] = new OnStateHandler();
}
public:
StateMachine()
{
makeHandlers();
mCurrentState = eOff;
}
void handleInput(tsInputDesc const& input, tsOutputDesc output)
{
teCurrentState newState = mStateHandlers[mCurrentState]->handleInput(input, output);
mCurrentState = newState;
}
};
// ------------------------------------------------
void runFsm()
{
StateMachine fsm;
tsInputDesc input;
tsOutputDesc output;
bool alive = true;
while (alive)
{
// TODO : set input according to....inputs (e.g. read I/O port etc)
fsm.handleInput(input, output);
// TODO : use output
}
}

How call a method on all step of class derivation hierarchy?

Take this example:
#include <iostream>
#include <typeindex>
#include <vector>
#include <map>
class _IEventHandler {}; // just for abstract template type
class IEvent {
public:
virtual void visitEventHandler(_IEventHandler *handler) = 0;
};
#define EXTENDS(type, parentType) \
public: \
using ParentClass = parentType; \
void visitEventHandler(_IEventHandler* handler) override { \
static_cast<IEventHandler<type>*>(handler)->on(*this); \
} \
template<typename Event>
class IEventHandler : public _IEventHandler {
public:
//virtual void on(Event& e) = 0;
void on(Event &e) {
std::cout << "handle " << typeid(Event).name() << std::endl;
}
};
class EventA : public IEvent {
EXTENDS(EventA, IEvent)
};
class EventB : public EventA {
EXTENDS(EventB, EventA)
};
class EventC : public EventB {
EXTENDS(EventC, EventB)
};
class EventD : public EventC {
EXTENDS(EventD, EventC)
};
class EventBus {
public:
void fire(IEvent *event) {
while (typeid(*event) != typeid(IEvent)) {
for (_IEventHandler *handler : m_handlers[typeid(*event)])
event->visitEventHandler(handler);
// Need to update event so the loop progresses. Need to upper cast?
}
}
template<typename T>
void hook(IEventHandler<T> *handler) {
m_handlers[typeid(T)].push_back(handler);
}
protected:
std::map<std::type_index, std::vector<_IEventHandler *>> m_handlers{};
};
int main() {
EventBus eb{};
IEventHandler<EventD> ehd{};
IEventHandler<EventC> ehc{};
IEventHandler<EventA> eha{};
eb.hook(&ehd);
eb.hook(&ehc);
eb.hook(&eha);
EventD eD{};
EventB eB{};
eb.fire(&eD); // need to stdout handle EventD handle EventC handle EventA
eb.fire(&eB); // need to stdout handle EventA
return 0;
}
I would like when I fire a IEvent it call on(EventX& e) on all intermediate derived class and stop on abstract class IEvent.
Currently I don't find solution, I looked about dyn_cast with a typeid, using decltype to access a static method from a instance (yes it's not the basic usage of these operators ;) and not permitted).
Summary:
The goal is to build an event system that supports hooking handlers and firing events. Events are hierarchical, deriving from a common ancestor class. Handlers should be called for their nominal event type and all types derived from that.
So far, the EventBus class is able to call handlers for the specific event type that was fired. The handlers are organized in a map from type_index to a vector of handlers. Getting the entry for a specific event type is not a problem, but how to get the less-derived types?
This is currently solve my issue:
#include <iostream>
#include <typeindex>
#include <vector>
#include <map>
class _IEventHandler {}; // just for abstract template type
class IEvent {
public:
virtual void visit_IEventHandler(std::type_index _index, _IEventHandler *handler) {}
virtual std::type_index getParentTypeIndex(std::type_index index) {
return typeid(IEvent);
}
};
#define EXTENDS(type, parentType) \
public: \
using Class = type; \
using ParentClass = parentType; \
std::type_index getParentTypeIndex(std::type_index index) { \
if (index == typeid(type)) \
return typeid(ParentClass); \
else \
return ParentClass::getParentTypeIndex(index); \
} \
#define HIERARCHICAL_VISITOR(interfaceType, reelType, methodName) \
public: \
void visit##interfaceType(std::type_index _index, interfaceType* _instanceToVisit) override { \
if (_index == typeid(Class)) \
static_cast<reelType<Class>*>(_instanceToVisit)->methodName(*this); \
else \
ParentClass::visit##interfaceType(_index, _instanceToVisit); \
} \
template<typename Event>
class IEventHandler : public _IEventHandler {
public:
//virtual void on(Event& e) = 0;
void on(Event &e) {
std::cout << "handle " << typeid(Event).name() << std::endl;
}
};
class EventA : public IEvent {
EXTENDS(EventA, IEvent)
HIERARCHICAL_VISITOR(_IEventHandler, IEventHandler, on)
};
class EventB : public EventA {
EXTENDS(EventB, EventA)
HIERARCHICAL_VISITOR(_IEventHandler, IEventHandler, on)
};
class EventC : public EventB {
EXTENDS(EventC, EventB)
HIERARCHICAL_VISITOR(_IEventHandler, IEventHandler, on)
};
class EventD : public EventC {
EXTENDS(EventD, EventC)
HIERARCHICAL_VISITOR(_IEventHandler, IEventHandler, on)
};
class EventBus {
public:
void fire(IEvent *event) {
std::type_index index = typeid(*event);
while (index != typeid(IEvent)) {
for (_IEventHandler *handler : m_handlers[index])
event->visit_IEventHandler(index, handler);
index = event->getParentTypeIndex(index);
}
}
template<typename T>
void hook(IEventHandler<T> *handler) {
m_handlers[typeid(T)].push_back(handler);
}
protected:
std::map<std::type_index, std::vector<_IEventHandler *>> m_handlers{};
};
int main() {
EventBus eb{};
IEventHandler<EventD> ehd{};
IEventHandler<EventC> ehc{};
IEventHandler<EventA> eha{};
eb.hook(&ehd);
eb.hook(&ehc);
eb.hook(&eha);
EventD eD{};
EventB eB{};
eb.fire(&eD); // need to stdout handle EventD handle EventC handle EventA
eb.fire(&eB); // need to stdout handle EventA
return 0;
}
/*
handle 6EventD
handle 6EventC
handle 6EventA
handle 6EventA
Process finished with exit code 0
*/
The only way that I found is use the basic inheritance process with the typeid check at all stage. I don't know if is the best way, I looking for a better way ;)
The keywords for this answer are "simplify" and "encapsulate".
Let's start with simplifications. There are several elements of the question's code that serve no purpose other than making the code more complicated than it needs to be. (There might be a small performance benefit, but it is premature to worry about that.) In order to better see what the actual solution is, I think it is useful to include these improvements. On the other hand, these are only indirectly related to the actual solution, so I will refrain from giving a detailed rationale for each of these.
Rename _IEventHandler to BaseEventHandler to comply with naming requirements.
Make on() a virtual function in BaseEventHandler so that visitEventHandler() does not need a static_cast.
Make visitEventHandler() a non-virtual function since all implementations are now the same.
Declare ~IEvent() to be virtual so that IEvent still has a virtual function.
Remove the EXTENDS macro because (macros are evil and) the things it defines are no longer used.
Moving on to encapsulation, let's look at the problem from the point of view of EventBus. This class is responsible for triggering handlers in response to events. It has inferred which event each handler wants, and organized the handlers by those event types. This already breaks encapsulation a bit since the bus uses knowledge about the handler's innards. Now they want me to also know about inheritance among the event types??? I need more information or you can go handle it yourself!
Since encapsulation encourages less information, rather than more, let's consider the other option: handle it yourself! Er, let the handlers decide if they want to handle an event. This simplifies EventBus since it no longer needs to be concerned about event types. Its map containing vectors can become a single vector, its hook() method no longer needs to be a template, and its fire() method can drop the loop that has been so difficult to implement. The trade-off is that the event handlers now need to examine the event types. Fortunately, dynamic_cast makes the check very simple.
#include <iostream>
#include <vector>
#include <map>
class IEvent;
/* ** Event handler ** */
class BaseEventHandler {
public:
virtual void on(IEvent &) = 0;
};
template<typename Event>
class IEventHandler : public BaseEventHandler {
public:
void on(IEvent & e) override {
// Only fire for events of the templated type.
if ( dynamic_cast<Event *>(&e) )
std::cout << "handle " << typeid(Event).name() << std::endl;
}
};
/* ** Event ** */
class IEvent {
public:
virtual ~IEvent() {} // To force run time type information (RTTI)
void visitEventHandler(BaseEventHandler* handler)
{
handler->on(*this);
}
};
class EventA : public IEvent {};
class EventB : public EventA {};
class EventC : public EventB {};
class EventD : public EventC {};
/* ** Event Bus ** */
class EventBus {
public:
void fire(IEvent *event) {
for (BaseEventHandler *handler : m_handlers)
event->visitEventHandler(handler);
}
void hook(BaseEventHandler *handler) {
m_handlers.push_back(handler);
}
protected:
std::vector<BaseEventHandler *> m_handlers{};
};
int main() {
EventBus eb{};
IEventHandler<EventD> ehd{};
IEventHandler<EventC> ehc{};
IEventHandler<EventA> eha{};
eb.hook(&ehd);
eb.hook(&ehc);
eb.hook(&eha);
EventD eD{};
EventB eB{};
std::cout << "Firing event D.\n";
eb.fire(&eD); // need to stdout handle EventD handle EventC handle EventA
std::cout << "\nFiring event B.\n";
eb.fire(&eB); // need to stdout handle EventA
return 0;
}
Some things to note about this approach:
Event handlers are fired in the order in which they were hooked. Previously, the order was handlers for the most derived class in the order they were hooked, followed by handlers for that class's direct parent in the order they were hooked, etc. If this is an important consideration, see my other answer.
There are still some issues with this code, but I am willing to chalk them up to being artifacts arising from the need to minimize the example.
There is no need to #include <typeindex>! This is good. I consider use of that header to be a yellow flag for design flaws. Better than a red flag (such as macros), but still an indication that maybe there's a better way to do things.
The keywords for this answer are "simplify" and "delegate".
Let's start with simplifications. There are several elements of the question's code that serve no purpose other than making the code more complicated than it needs to be. (There might be a small performance benefit, but it is premature to worry about that.) In order to better see what the actual solution is, I think it is useful to include these improvements. On the other hand, these are only indirectly related to the actual solution, so I will refrain from giving a detailed rationale for each of these.
Rename _IEventHandler to BaseEventHandler to comply with naming requirements.
Make on() a virtual function in BaseEventHandler so that visitEventHandler() does not need a static_cast.
Remove the EXTENDS macro because (macros are evil and) the things it defines either are no longer used or will be defined elsewhere.
Moving on to delegation, let's look at why EventBus has trouble traversing the inheritance tree of events. One reason is straight-forward: EventBus is not an event. Instead of trying to replicate the inheritance tree, let's use existing elements of the language. Instead of trying to deduce things about events, let's hand the problem off to someone who knows better, namely the event itself.
What I have in mind is a shift of responsibilities, basically shifting most of EventBus::fire() to the events' visitEventHandler(). Since each class knows its parent, it can invoke its parent's version of visitEventHandler(), stepping up the hierarchy until the end is reached. The trade-off is that the type of the map becomes public knowledge, rather than merely a private implementation detail of EventBus. Probably a fair trade.
#include <iostream>
#include <typeindex>
#include <vector>
#include <map>
class IEvent;
/* ** Event handler ** */
class BaseEventHandler {
public:
virtual void on(IEvent &) = 0;
};
template<typename Event>
class IEventHandler : public BaseEventHandler {
public:
void on(IEvent &) override {
std::cout << "handle " << typeid(Event).name() << std::endl;
}
};
using HandlerMap = std::map<std::type_index, std::vector<BaseEventHandler *>>;
/* ** Event ** */
class IEvent {
public:
// This is not an actual event type, so there are no handlers to visit.
virtual void visitEventHandlers(HandlerMap &) = 0;
};
// Need a definition for derived classes to call:
void IEvent::visitEventHandlers(HandlerMap &) {}
template<class Base>
class EventFrom : public Base {
public:
void visitEventHandlers(HandlerMap & handlers) override
{
// Visit the handlers for this specific event type.
for (BaseEventHandler *handler : handlers[typeid(EventFrom)])
handler->on(*this);
// Visit the handlers for the parent event type.
Base::visitEventHandlers(handlers);
}
};
using EventA = EventFrom<IEvent>;
using EventB = EventFrom<EventA>;
using EventC = EventFrom<EventB>;
using EventD = EventFrom<EventC>;
/* ** Event Bus ** */
class EventBus {
public:
void fire(IEvent *event) {
event->visitEventHandlers(m_handlers);
}
template<typename T>
void hook(IEventHandler<T> *handler) {
m_handlers[typeid(T)].push_back(handler);
}
protected:
HandlerMap m_handlers{};
};
int main() {
EventBus eb{};
IEventHandler<EventD> ehd{};
IEventHandler<EventC> ehc{};
IEventHandler<EventA> eha{};
eb.hook(&ehd);
eb.hook(&ehc);
eb.hook(&eha);
EventD eD{};
EventB eB{};
std::cout << "Firing event D.\n";
eb.fire(&eD); // need to stdout handle EventD handle EventC handle EventA
std::cout << "\nFiring event B.\n";
eb.fire(&eB); // need to stdout handle EventA
return 0;
}
Some things to note about this approach:
There is quite a bit of complexity used to make sure all event handlers for the most derived class are fired before any handlers for less derived classes. If this is not important, see my other answer.
There are still some issues with this code, but I am willing to chalk them up to being artifacts arising from the need to minimize the example.
There are no macros! (Macros are a red flag, indicating a likely design flaw.)
I would change the signature of hook() to void hook(BaseEventHandler *handler). While this means changes like eb.hook(&ehd) to eb.hook<EventD>(&ehd), it gives more freedom in defining your event handlers (no need for the IEventHandler template). Probably a good trade.

How to use composition instead of inheritance when dependency injection is involved?

I have a bunch of checkers in my program that I modelled as classes: check the RAM is OK, check the disk is OK, check the temperatures are OK, etc. These checkers have a lot in common, so I modelled them with inheritance: all that is in common goes into a base class CheckerBase that is derived from by specialised classes with checker-specific functionality and dependencies.
However I've often read that composition should be preferred over inheritance, so I'm wondering how this would be done in C++ with composition?
#include <chrono>
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
/** Dependencies of various checkers that I pass in via dependency injection. */
struct ErrorReporter {
void report_error(string myMsg) {
cout << myMsg;
}
};
struct TemperatureSensor {
int get_cpu_temp() { return 42; }
int get_disk_temp() { return 32; }
};
struct DiskStressor {
void stress_disk() { }
};
/** Contains dependencies that are common to all checkers.. */
class CheckerBase {
public:
CheckerBase(ErrorReporter* errReporter ) :
mErrReporter(errReporter) { }
virtual void runTest() = 0;
protected:
ErrorReporter* mErrReporter;
};
/** Needs `TemperatureSensor` dependency. */
class TemperatureChecker : public CheckerBase {
public:
TemperatureChecker(ErrorReporter* errReporter,
TemperatureSensor* tempSensor) :
CheckerBase(errReporter), mTempSensor(tempSensor) { }
void runTest() override {
if (mTempSensor->get_cpu_temp() > 42) {
mErrReporter->report_error("CPU too hot");
}
};
private:
TemperatureSensor* mTempSensor;
};
/** Needs `TemperatureSensor` and `DiskStressor` dependencies. */
class DiskChecker : public CheckerBase {
public:
DiskChecker(ErrorReporter* errReporter, TemperatureSensor* tempSensor,
DiskStressor* diskStressor) :
CheckerBase(errReporter), mTempSensor(tempSensor) { }
void runTest() override {
mDiskStressor->stress_disk();
mTempSensor->get_disk_temp();
if (mTempSensor->get_cpu_temp() > 32) {
mErrReporter->report_error("HDD too hot after strees test");
}
};
private:
TemperatureSensor* mTempSensor;
DiskStressor* mDiskStressor;
};
/** Periodically runs each checker. */
class MasterChecker {
public:
MasterChecker() :
mTempChecker { &mErrReporter, &mTempSensor },
mDiskChecker { &mErrReporter, &mTempSensor, &mDiskStressor },
mAllCheckers({&mTempChecker, &mDiskChecker}) {};
void start() {
// In reality I use a timer that continously runs each checker at
// a certain interval.
while (true) {
for (CheckerBase *checker : mAllCheckers) {
checker->runTest();
}
this_thread::sleep_for(chrono::milliseconds(5000));
}
}
private:
ErrorReporter mErrReporter;
TemperatureSensor mTempSensor;
DiskStressor mDiskStressor;
DiskChecker mDiskChecker;
TemperatureChecker mTempChecker;
vector<CheckerBase*> mAllCheckers;
};
int main() {
MasterChecker master;
master.start();
}
EDIT: Updated to include an approximation of how the checkers are used. A MasterChecker runs all the individual checkers periodically. It has a list of the checkers and calls their runTest() member function--which all checkers override from their base class.
... composition should be preferred over inheritance
That means, where you could choose either, prefer composition. In this case, MasterChecker (correctly) composes the various concrete checkers, as your advice recommended.
The fact that the individual checkers inherit/implement an abstract base class isn't a problem, because you can't compose an interface. There's no choice here, and the advice didn't say you should never use inheritance even when composition isn't an alternative.
The case your advice actually warns against is doing something like:
class MasterChecker: public DiskChecker, public TemperatureChecker
where inheritance is abused to aggregate the base class subobjects.
In your case this probably wouldn't work well anyway, at least without changes, due to initialization order and diamond-shaped inheritance reasons.

Run typed_test for only one of specified types

Let's suppose i've written a code like this.
template <typename T>
class FooTest : public testing::Test
{
//class body
};
typedef ::testing::Types<int, float/*, and few more*/> TestTypes;
TYPED_TEST_CASE(FooTest, TestTypes);
TYPED_TEST(FooTest, test1)
{
//...
}
TYPED_TEST(FooTest, test2)
{
//...;
}
Is there any possibility to run, for example second test, for only one of data types specified in TestTypes and avoid any code duplication?
You should be able to do this by creating a second test class using inheiritance.
This is similar to the approaches on two faq entries:
Can I derive a test fixture from another?
I have several test cases which share the same logic...
In the code outline below, I have separate the types into two disjoint sets.
template <typename T>
class FooTest : public testing::Test
{
//class body
};
// TestTypes only contains some of the types as before
// in this example, floating point types are tested only with FooTest.
typedef ::testing::Types<float, double, /*, and few more*/> TestTypes;
TYPED_TEST_CASE(FooTest, TestTypes);
TYPED_TEST(FooTest, test1)
{
//...
}
// Optional, but could allow you to reuse test constructor
// and SetUp/TearDown functions
template <typename T>
class ExtendedFooTest : public FooTest<T>
{}
// And integral types are given extended tests
typedef ::testing::Types<int, unsigned int, and few more*/> ExtendedFooTypes;
TYPED_TEST_CASE(FooTest, ExtendedFooTypes); // repeat the tests above
TYPED_TEST_CASE(ExtendedFooTest, ExtendedFooTypes); // Plus add new tests.
TYPED_TEST(ExtendedFooTest, test2)
{
//...;
}