单元测试的条件派生

Conditional Derivation for Unit Testing

本文关键字:派生 条件 单元测试      更新时间:2023-10-16

我正在编写封装硬件驱动程序(用户空间)的单元测试,我使用的设计模式如下:

class uio
{
    virtual uint32_t readbit(...);
    virtual bool writebit(...);
    // other driver related functions
    // ...
};
class uio_test : public uio
{
    virtual uint32_t readbit(...) override { /* don't talk to hardware, send back test data */ }
    virtual bool writebit(...) override { /* don't talk to hardware, write test data */ }
};
class spi : public uio
{
    // spi related functions
};
class i2c : public uio
{
    // i2c related functions
};

我的问题是如何去使spi和uio正确地从uio或uio_test继承取决于模块(真正的程序与gtest)。我已经看了条件语句,例如:

template<bool test>
class spi : public std::conditional<test, uio_test, uio>

,这将适用于所有对象都直接从main派生的世界。

/* main.cpp */
spi<false> s;
s.init();
s.writebit();
/* gtest_main.cpp */
spi<true> s;
ASSERT_TRUE(s.init());
ASSERT_EQ(/* read/write test bits, etc*/);

然而,uio派生对象在整个程序的其他专门化类中使用,并且我看不到条件构造的好方法,例如:

class temperature_monitor
{
    createBuses();
    spi<???>* spictrl_;
};
/* perhaps derive test classes, easy since most high level objects are singletons */
temperature_monitor::createBuses()
{
    if (testmode)
        spictrl_ = new spi<true>;
    else
        spictrl_ = new spi<false>;     
}

希望这对每个人来说都很清楚。我先回答几个问题,然后再问:

。预处理条件呢?

。不,如果可能的话,永远不要。

。为什么要为像spi这样的低级驱动编写单元测试?

。为什么不呢,有一些内部逻辑在运行,我宁愿在单元测试中捕获错误,也不愿花一天时间调试一个愚蠢的遗漏0。

我认为你需要的是一个策略模式。uio提供了一个非虚接口和一个指向实现的指针。您认为有一个虚拟接口,并向uio对象提供一个普通或测试实例,而不是试图在中间插入继承。使用策略模式甚至允许您插入其他实现。