单元测试驱动编程大致思想是,首先要想实现什么功能,为该功能编写空实现类及单元测试类,之后再写具体的实现,具体的实现可以重构。下面是一个例子:
1、我要实现求字符串指定起始与终止位置的字串,那么我定义了一个MyString类,先声明并且定义该类,但是不具体实现
2、开始写单元测试
3、具体实现该类。注意,由于subQString函数比较简单,在该函数体内部实现即可。如果功能在一个函数体内实现太过庞大,那么就可以考虑重构了。
所以我认为私有函数是经过重构来的,那么对私有函数的单元测试是不必要的。
1、我要实现求字符串指定起始与终止位置的字串,那么我定义了一个MyString类,先声明并且定义该类,但是不具体实现
//头文件
#ifndef MYSTRING_H
#define MYSTRING_H
#include <QString>
class CGMyString
{
public:
QString subQString(int start, int end);
public:
CGMyString(QString& qstr);
};
#endif // MYSTRING_H
//实现文件#include "MyString.h"
CGMyString::CGMyString(QString &qstr)
{
}
QString CGMyString::subQString(int start, int end)
{
QString re;
return re;
}
2、开始写单元测试
#include <QString>
#include <QtTest>
#include <MyString.h>
class MyStringTest : public QObject
{
Q_OBJECT
public:
MyStringTest();
private Q_SLOTS:
void testSubQString();
void testSubQString_data();
};
MyStringTest::MyStringTest()
{
}
void MyStringTest::testSubQString()
{
QFETCH(QString, str);
QFETCH(int, start);
QFETCH(int, end);
QFETCH(QString, result);
CGMyString testStr(str);
QString execResult = testStr.subQString(start, end);
QVERIFY2(0 == result.compare(execResult), "MyStringTest_subQString");
}
void MyStringTest::testSubQString_data()
{
QTest::addColumn<QString>("str");
QTest::addColumn<int>("start");
QTest::addColumn<int>("end");
QTest::addColumn<QString>("result");
QTest::newRow("illegal start") << QString::fromLocal8Bit("HELLO") << -1 << 2 << "";
QTest::newRow("illegal end") << QString::fromLocal8Bit("HELLO") << 0 << 7 << "";
QTest::newRow("legal") << QString::fromLocal8Bit("HELLO") << 0 << 3 << "HELL";
}
QTEST_APPLESS_MAIN(MyStringTest)
#include "tst_unittesttest.moc"
3、具体实现该类。注意,由于subQString函数比较简单,在该函数体内部实现即可。如果功能在一个函数体内实现太过庞大,那么就可以考虑重构了。
所以我认为私有函数是经过重构来的,那么对私有函数的单元测试是不必要的。
//头文件
#ifndef MYSTRING_H
#define MYSTRING_H
#include <QString>
class CGMyString
{
private:
QString* m_str;
public:
QString subQString(int start, int end);
public:
CGMyString(QString& qstr);
~CGMyString();
};
#endif // MYSTRING_H
//实现
#include "MyString.h"
CGMyString::CGMyString(QString &qstr)
{
m_str = new QString(qstr);
}
CGMyString::~CGMyString()
{
delete m_str;
}
QString CGMyString::subQString(int start, int end)
{
QString re;
if ( start < 0 || start > end || end >= m_str->length())
{
return re;
}
for(int i = start; i <= end; i++)
{
re.append(m_str->at(i));
}
return re;
}
4、贵在坚持,一开始会觉得写单元测试浪费时间,但我觉得这是值得的,坚持下去,一定有好处!!