【问题标题】:NUnit does not capture output of std::cerrNUnit 不捕获 std::cerr 的输出
【发布时间】:2010-03-29 11:53:52
【问题描述】:

我在 C# 中有一个 nunit 测试,它调用 C++ DLL 中函数的 C# 包装器。 C++代码使用std::cerr输出各种消息。

这些消息无法使用 nunit-console /out /err 或 /xml 开关重定向。 在 nunit(GUI 版本)中,输出不会出现在任何地方。

我希望能够在 nunit(GUI 版本)中看到此输出。 理想情况下,我希望能够在测试中访问此输出。

感谢您的帮助。

【问题讨论】:

  • 我也有类似的问题。更糟糕的是,我使用 std::wcerr 和 std::wcout 输出到控制台或日志文件,具体取决于标志..但它们都不能在 NUnit 中工作,但它们在我的 C# 程序中工作..

标签: c# c++ nunit


【解决方案1】:

重定向 std::cerr 是将流缓冲区替换为您自己的问题。 在我们退出之前恢复原始缓冲区很重要。我不知道你的包装器是什么样子,但你可能会弄清楚如何让它读取 output.str()。

#include <iostream>
#include <sstream>
#include <cassert>

using namespace std;

int main()
{
    streambuf* buf(cerr.rdbuf());
    stringstream output;

    cerr.rdbuf(output.rdbuf());
    cerr << "Hello, world!" << endl;

    assert(output.str() == "Hello, world!\n");
    cerr.rdbuf(buf);

    return 0;
}

【讨论】:

  • 查看我的另一个“答案”,了解我对此做了什么。
【解决方案2】:

感谢您的提示。 这就是我最终要做的:

.CPP 文件------------------------

#include <iostream>
#include <sstream>

static std::stringstream buffer;
static std::streambuf * savedBuffer = NULL;


extern "C" __declspec(dllexport) bool Redirect()
{
    if (savedBuffer)
    {
        return false;
    }
    std::streambuf * buf(std::cerr.rdbuf());
    std::cerr.rdbuf(buffer.rdbuf());

    // This two lines are for illustration purposes only!
    std::cerr << "Hello world" << std::endl;

    return true;
}


extern "C" __declspec(dllexport) void Revert()
{
    if (savedBuffer)
    {
        std::cerr.rdbuf(savedBuffer);
    }
    savedBuffer = NULL;
}


extern "C" __declspec(dllexport) const char * getCerr()
{
    return _strdup(buffer.str().c_str());
}

extern "C" __declspec(dllexport) void freeCharPtr(char *ptr)
{
    free(ptr);
}

.CS 文件 ------------------------------------------

public static class Redirector
{
    // PRIVATE ------------------------------------------------------------
    private const String LibraryName = "MyCpp.dll";

    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    private static extern IntPtr getCerr();

    // PUBLIC -------------------------------------------------------------
    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    public static extern bool Redirect();

    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    public static extern void Revert();

    [DllImport(LibraryName, CharSet = CharSet.Ansi)]
    internal static extern void freeCharPtr(IntPtr ptr);

    public static string GetCerr()
    {
        IntPtr temp = getCerr();
        string result = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(temp);
        freeCharPtr(temp);
        return result;
    }
}

NUnit 测试-----------

    [Test]
    // [Ignore]
    public void TestRedirect()
    {
        Redirector.Redirect();
        // Call more functions that output to std::cerr here.
        Redirector.Revert();
        System.Console.WriteLine(Redirector.GetCerr());
    }

freeCharPtr() 是从 _strdup() 中释放分配的内存所必需的,因为我不知道(如果可能的话)如何编组 std::string。

注意:这不是线程安全的!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 2015-08-16
    • 2011-10-29
    • 2013-03-12
    • 1970-01-01
    • 2014-04-26
    • 2013-02-08
    • 1970-01-01
    相关资源
    最近更新 更多