【问题标题】:Generate temporary file/folder c++ GTEST生成临时文件/文件夹 c++ GTEST
【发布时间】:2016-07-15 14:12:43
【问题描述】:

我需要为测试生成临时文件。看起来我不能使用mkstemp,因为我需要文件名具有特定的后缀,但文件名的其余部分我不在乎。 GTest 中有没有办法创建一个临时文件来处理文件的创建以及测试结束时的删除。

另一种方法是创建我自己的类来做到这一点。

【问题讨论】:

  • Google 测试 AFAIK 中没有内置任何内容。

标签: c++ googletest


【解决方案1】:

虽然它不构建临时文件,但 googletest 提供了两个不同的测试宏,TEST 和 TEST_F,后者是固定的。请参阅the Primer 标题为“测试夹具:使用相同的数据配置...”的部分,了解有关夹具的更多信息。

我对这个问题的解决方案是使用带有固定测试的 Boost.Filesystem。我希望能够拥有一个为所有测试共享的命名临时子目录。在这种情况下,我正在调整我的案例以适应 OP 对指定后缀的请求。

包括:

// Boost.Filesystem VERSION 3 required
#include <string>
#include <boost/filesystem.hpp>

测试类定义:

class ArchiveTest : public ::testing::Test {
protected:
    boost::filesystem::path mTempFileRel;
    boost::filesystem::path mTempFileAbs;
    std::ofstream mExampleStream;

    ArchiveTest() {
         mTempFileRel = boost::filesystem::unique_path("%%%%_%%%%_%%%%_%%%%.your_suffix");
         mTempFileAbs = boost::filesystem::temp_directory_path() / mTempFileRel;
         mExampleStream.open(mTempFileAbs);
    }

    ~ArchiveTest() {
        if(mExampleStream.is_open())
        {
            mExampleStream.close();
        }
    }
    // Note there are SetUp() and TearDown() that are probably better for
    // actually opening/closing in case something throws
};

注意:虽然您可以在构造函数或 SetUp() 中创建文件对象并在析构函数或 TearDown() 中关闭,但我更喜欢在测试中这样做,因为我不使用在所有测试中创建的文件名固定。因此,在使用流示例时要格外小心。

这是我对文件名的使用:

// Tests that an ArchiveFile can be written
TEST_F(ArchiveTest, TestWritingArchive) {
    try
    {
        TheInfo info_;  // some metadata for the archive
        MyArchive archive_; // Custom class for an archive
        archive_.attachToFile(mTempFile, info_);

        ...
    }
    catch(const std::exception& e_)
    {
        FAIL() << "Caught an exception in " << typeid(*this).name()
               << ": " << e_.what();
    }
}

如果您对 '%' 字符感到好奇,来自the reference on unique_path

unique_path 函数生成一个适合创建的路径名 临时文件,包括目录。名称基于模型 使用百分号字符指定替换为 随机十六进制数字。

注意事项:

  1. 感谢 Robbie Morrison 对临时文件的 concise answer 让我开始工作
  2. 我从更长的类定义和一组测试中复制/粘贴了摘录,如果有任何不清楚的地方或是否存在印刷(复制/粘贴)错误,请告诉我。

【讨论】:

    【解决方案2】:

    Googletest 现在包含 testing::TempDir(),但它只返回 /tmp/ 或特定于平台的等效项,它不进行任何清理。

    【讨论】:

      【解决方案3】:

      您可以在某些系统上使用 mkstemps,尽管它不是标准的。来自 man page 的 mkstemp:

      mkstemps() 函数与 mkstemp() 类似,不同之处在于模板中的字符串包含 suffixlen 个字符的后缀。因此,模板的形式为 prefixXXXXXXsuffix,字符串 XXXXXX 被修改为 mkstemp()。

      因此,您可以像这样使用 mkstemps:

      // The template in use. Replace '.suffix' with your needed suffix.
      char temp[] = "XXXXXX.suffix";
      // strlen is used for ease of illistration.
      int fd = mkstemps(temp, strlen(".suffix"));
      
      // Since the template is modified, you now have the name of the file.
      puts(temp);
      

      您需要跟踪文件名,以便在程序结束时将其删除。如果您希望能够将所有这些文件放入/tmp 中,您应该能够添加“/tmp/”作为前缀。不过,似乎没有办法让它创建一个临时目录。

      【讨论】:

        【解决方案4】:

        创建文件和文件夹不在任何测试框架的范围内,包括 Google 测试。为此目的,将其他一些库链接到您的测试二进制文件。

        【讨论】:

        • 在其他生态系统/编程语言中,测试框架通常会为了方便而提供此类功能(创建临时文件/文件夹,包括清理)。但是,是的,便利在 C++ 世界中很少见。
        猜你喜欢
        • 2018-07-06
        • 1970-01-01
        • 2015-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-06
        • 2022-01-15
        相关资源
        最近更新 更多