如何对涉及文件输入输出的方法进行单元测试?

时间:2009-07-10 19:00:37

标签: c++ unit-testing file stub

我正在使用Parasoft的C ++ Test来测试C ++代码。 我遇到了以下问题。我有一个类似于下一个函数的函数(伪代码):

bool LoadFileToMem(const std::string& rStrFileName)
{
    if( openfile(rStrFileName) == successfull )
    {
         if( get_file_size() == successfull )
         {
            if( read_entire_file_to_buffer() == successfull )
            {
                return true;
            }
            return false;
         }
         return false;
    }
    return false;
}

我在这种情况下的问题是:

我应该使用存根来存储文件系统吗?或者我应该包含用于运行单元测试的特定样本测试文件吗?

在我的情况下,std::fstream类用于文件输入。

有没有更好的建议? (如果在C ++测试中完成但不是强制性的,则最好。)

6 个答案:

答案 0 :(得分:6)

我会选择简短的样本测试文件。可以将它们与测试代码一起检入源代码控制。我这样做的原因是你的函数的意图是加载一个文件,所以这就是你应该测试的。

答案 1 :(得分:4)

对于单元测试THIS函数,您应该为每个被调用函数使用存根。

每个被调用的函数都有自己的单元测试套件,它可以运行该函数。

对于read_entire_file_to_buffer(),您希望至少有一个测试文件大量溢出缓冲区,以确保在它们为您提供纽约证券交易所历史记录而不是40个字符的配置时不会崩溃和刻录你期待的文件。

答案 2 :(得分:2)

我的建议:

为将调用此函数的函数创建存根。

使用示例测试文件为此特定功能创建单元测试。

创建一个没有存根的集成测试来测试整个过程。

答案 3 :(得分:1)

我认为您正在寻找一种名为fault injection的技术。几年前我看到一个项目会导致程序进入很少测试的错误条件(文件权限错误,malloc返回0等)。我只是记不起它的名字。希望维基百科链接可以帮助您入门。

答案 4 :(得分:1)

老实说,我会把这个功能分成两部分。一个函数将从std::istream读取,一个函数将打开文件并返回ifstream(可能是由智能指针分配的堆)。然后,您可以通过提供istringstream代替ifstream轻松对第一个进行单元测试,而后者也应该易于测试。

答案 5 :(得分:0)

在单元测试中,您通常希望尽可能接近地模仿原始功能,同时覆盖您正在测试的代码(代码覆盖率)。除了我不熟悉的存根,一个例子就是你要确保,如果给出了错误的文件名,等等你的文件中的第3行:

if(openfile(rStrFileName)== successfull)

然后你将准确处理这种情况并返回false。如果这可以通过存根完成,那么就这样吧。在我的情况下,我将使用示例测试文件并将其存储在我的测试中。这是一种常见的做法。

请记住,重点是尽可能地将功能测试为接近现实。这将确保您可以自动捕获许多您无法预料到的奇怪情况,以便您可以修复它,这是开始进行单元测试的重点。