本文最開始介紹模板元編程的時候說過猾封,模板元編程是寫C++框架離不開的技術(shù)噪珊。本例將通過介紹模板元編程在dates框架中的應(yīng)用,來介紹如何使用模板元編程在框架開發(fā)中操縱類型磷箕,幫助你的代碼更易用阵难,性能更高并且更安全。
Dates是本人開發(fā)的一個針對C++程序的模塊和系統(tǒng)級別的FT(Functional Test)測試框架呜叫。它可以模擬被測系統(tǒng)的交互系統(tǒng),讓它們以同步或者異步的方式發(fā)消息給被測系統(tǒng)家厌,然后再由模擬系統(tǒng)接收被測系統(tǒng)的返回消息并進行校驗椎工。用Dates描述測試用例,主要工作就是在框架中創(chuàng)建被測系統(tǒng)的周邊交互系統(tǒng)维蒙,并且按照消息的時序關(guān)系描述測試用例,構(gòu)造消息颅痊,并對接收到的消息內(nèi)容進行斷言校驗。
Dates需要結(jié)合一款針對“運行時C++”的xUnit測試框架一同使用菱属,它需要借助xUnit測試框架提供的測試斷言和測試管理的能力舰罚。Dates的設(shè)計是和下層的xUnit測試框架解耦的,所以你可以使用任何一款“運行時C++” xUnit測試框架來和dates組合营罢。如下是一個用Dates描述的測試用例,在這個例子中我們使用的是常用的C++ xUnit測試框架gtest蝙搔。
#include <gtest/gtest.h>
struct AccessTest : public testing::Test
{
// ...
FakeSystem visitor;
FakeSystem commander;
};
TEST_F(AccessTest, shoud_response_success_to_visitor_when_commander_response_ok)
{
visitor.send([this](AccessReq& req)
{
req.capability = CAPABILITY;
});
commander.recv([this](const CfgReq& cfg)
{
ASSERT_EQ(CAPABILITY, cfg.capability);
});
commander.send([](CfgRsp& rsp)
{
rsp.result = OK;
});
visitor.recv([](const AccessRsp& rsp)
{
ASSERT_EQ(SUCCESS, rsp.result);
});
}
該用例中模擬了與被測系統(tǒng)SUT(System Under Test)交互的兩個周邊系統(tǒng)visitor和commander证鸥。通過測試用例我們可以看到败玉,SUT一旦收到從visitor發(fā)來的AccessReq消息敌土,就需要給commander發(fā)一條CfgReq消息运翼,CfgReq消息中需要攜帶AccessReq中的capability字段值給commander。一旦commander返回OK矩欠,則SUT需要給visitor發(fā)送AccessRsp消息悠夯,其中的result值為SUCCESS。
關(guān)于dates的具體實現(xiàn)細(xì)節(jié)沦补,感興趣的話可以下載dates的源碼:https://github.com/MagicBowen/dates。本文只介紹幾處dates如何使用模板元編程來做類型操縱虚倒,最終使得dates變得更加易用产舞、高效和安全的例子。