生成临时 file/folder c++ GTEST
Generate temporary file/folder c++ GTEST
我需要为测试生成临时文件。看起来我不能使用 mkstemp
因为我需要文件名有一个特定的后缀,但文件名的其余部分我不在乎。在 GTest 中有没有办法创建一个临时文件来处理文件的创建以及测试结束时的删除。
另一种方法是创建我自己的 class 来做到这一点。
创建文件和文件夹不在任何测试框架的范围内,包括 Google 测试。 Link 为此目的将一些其他库添加到您的测试二进制文件中。
虽然它不构建临时文件,googletest 提供了两个不同的测试宏,TEST 和 TEST_F,后者是固定的。有关灯具的更多信息,请参阅 the Primer 中标题为 "Test Fixtures: Using the Same Data Config..." 的部分。
我对这个问题的解决方案是使用 Boost.Filesystem 和固定测试。我希望能够拥有一个为所有测试共享的命名临时子目录。在这种情况下,我正在调整我的案例以适应 OP 对指定后缀的请求。
包括:
// Boost.Filesystem VERSION 3 required
#include <string>
#include <boost/filesystem.hpp>
测试class定义:
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() 中创建文件 object 并在析构函数或 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:
The unique_path function generates a path name suitable for creating
temporary files, including directories. The name is based on a model
that uses the percent sign character to specify replacement by a
random hexadecimal digit.
备注:
- 感谢 Robbie Morrison for the concise answer 让我开始的临时文件
- 我 copied/pasted 摘自更长的 class 定义和一组测试,所以如果有任何不清楚的地方或有印刷 (copy/paste) 错误,请告诉我。
您可以在某些系统上使用 mkstemps,尽管它不是标准的。来自 man page for mkstemp:
The mkstemps() function is like mkstemp(), except that the string in template contains a suffix of suffixlen characters. Thus, template is of the form prefixXXXXXXsuffix, and the string XXXXXX is modified as for 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/”作为前缀。不过,似乎没有办法让它创建临时目录。
Googletest 现在包括 testing::TempDir()
,但它只是 returns /tmp/
或特定于平台的等效项,它不进行任何清理。
我需要为测试生成临时文件。看起来我不能使用 mkstemp
因为我需要文件名有一个特定的后缀,但文件名的其余部分我不在乎。在 GTest 中有没有办法创建一个临时文件来处理文件的创建以及测试结束时的删除。
另一种方法是创建我自己的 class 来做到这一点。
创建文件和文件夹不在任何测试框架的范围内,包括 Google 测试。 Link 为此目的将一些其他库添加到您的测试二进制文件中。
虽然它不构建临时文件,googletest 提供了两个不同的测试宏,TEST 和 TEST_F,后者是固定的。有关灯具的更多信息,请参阅 the Primer 中标题为 "Test Fixtures: Using the Same Data Config..." 的部分。
我对这个问题的解决方案是使用 Boost.Filesystem 和固定测试。我希望能够拥有一个为所有测试共享的命名临时子目录。在这种情况下,我正在调整我的案例以适应 OP 对指定后缀的请求。
包括:
// Boost.Filesystem VERSION 3 required
#include <string>
#include <boost/filesystem.hpp>
测试class定义:
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() 中创建文件 object 并在析构函数或 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:
The unique_path function generates a path name suitable for creating temporary files, including directories. The name is based on a model that uses the percent sign character to specify replacement by a random hexadecimal digit.
备注:
- 感谢 Robbie Morrison for the concise answer 让我开始的临时文件
- 我 copied/pasted 摘自更长的 class 定义和一组测试,所以如果有任何不清楚的地方或有印刷 (copy/paste) 错误,请告诉我。
您可以在某些系统上使用 mkstemps,尽管它不是标准的。来自 man page for mkstemp:
The mkstemps() function is like mkstemp(), except that the string in template contains a suffix of suffixlen characters. Thus, template is of the form prefixXXXXXXsuffix, and the string XXXXXX is modified as for 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/”作为前缀。不过,似乎没有办法让它创建临时目录。
Googletest 现在包括 testing::TempDir()
,但它只是 returns /tmp/
或特定于平台的等效项,它不进行任何清理。