【问题标题】:globally suppress c++ std::cout when testing测试时全局抑制 c++ std::cout
【发布时间】:2015-07-17 16:58:13
【问题描述】:

我在数值数据上有一个 Struct 点,它带有一个 returnNext() 方法,该方法在每次调用时返回并在 stdout 中发布下一个数据。我也有一系列使用这种方法的单元测试:在这些测试中,我想抑制所有 Data 的 std::cout,这样我只检查返回值的有效性,而不会使屏幕因消息而膨胀。例如

struct Data { 
  Data(int n): datum{n} {};
  int datum;
  int returnNext() { 
    std::cout << datum << " returned" << std::endl;
    return datum;
  }
}

// main.cpp
int main() {
  Data d{100};
  d.returnNext(); // I want this to print at the screen 
  return 0;
}

// test.cpp
int main() {
  TEST( ... ) {
    Data d{100};
    ASSERT_THAT(d.returnNext(), 100); // I want just to check the output, not to check
  }
std::cout << "some message" << std::endl; // I want this printed
return 0;
}

一个明显的解决方案是使用预编译器标志/命令从 TEST 构建中排除 std::cout。但这需要编辑几个模块,也会让我的代码变得丑陋。

另一种情况是从控制台使用重定向标准输出到 dev/null,但这也会抑制标准输出我的测试模块。

难道没有办法在程序生命周期的特定时刻以编程方式抑制/重定向标准输出???

【问题讨论】:

  • 您可以使用不同精度级别的记录器,并在运行时选择要打印的内容。
  • 您可以创建具有各种详细级别的日志流类。
  • 为什么不使用/dev/null
  • 有人知道-1是干什么用的吗?对我来说似乎是个好问题:)

标签: c++ c++11 iostream


【解决方案1】:

对于抑制std::cout的一般问题,可以将std::basic_ios::rdbuf与空缓冲区一起使用:

auto old_buffer = std::cout.rdbuf(nullptr);

要恢复它,只需这样做

std::cout.rdbuf(old_buffer);

【讨论】:

  • 有趣,我以前没见过 :) 也许您可以详细说明如何使用它来抑制 returnNext() 而不抑制单元测试框架的任何输出?
  • 不错的技巧,在其他情况下值得注意,但作为一个全局修饰符,它对于所提出的问题来说太笼统了。
  • 注意这个过程是可逆的 - rdbuf()返回之前的流缓冲区,所以你可以保存这个函数的返回值,以后再恢复。
【解决方案2】:

这正是为什么在成员函数中硬编码标准输出是一个坏主意的原因。现在你认为你必须在全局范围内阻止 std::cout,因为你的类的行为是不灵活的。

相反,将std::cout 调用移动到其他地方(使其使用可选)或让它成为任意std::ostream,您可以将其路由到无处。

【讨论】:

    猜你喜欢
    • 2020-11-05
    • 2018-09-20
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 2018-05-31
    • 2020-09-24
    • 1970-01-01
    相关资源
    最近更新 更多