66

我有一组要作为控制台应用程序运行的 Boost 单元测试。

当我处理项目并运行测试时,我希望能够调试测试,并且希望在测试运行后控制台保持打开状态。

我看到如果我在发布模式下运行,程序退出后控制台窗口会保持打开状态,但在调试模式下并非如此。

我不想添加 'system("pause");' 或任何其他技巧,例如将字符读取到我的程序中。我只想让 Visual Studio 在运行带有调试的测试后暂停,就像我在发布模式下运行一样。如果测试的输出是在 Visual Studio 的输出窗口之一中捕获的,我也希望这样做,但这似乎也比它应该的要难。

我怎样才能做到这一点?

4

17 回答 17

126

尝试使用Ctrl+F5组合运行应用程序。

于 2008-12-14T10:07:10.273 回答
78

http://connect.microsoft.com/VisualStudio/feedback/details/540969/missing-press-any-key-to-continue-when-lauching-with-ctrl-f5

在旧版本中,即使您选择了“空项目”,它也会默认为控制台子系统,但在 2010 年不会,因此您必须手动设置它。为此,请在右侧或左侧的解决方案资源管理器中选择项目(可能已被选中,因此您不必担心这一点)。然后从菜单栏下拉菜单中选择“项目”,然后选择“项目名称属性”>“配置属性”>“链接器”>“系统”并设置第一个属性,下拉“子系统”属性为“控制台(/子系统:控制台)”。控制台窗口现在应该像往常一样在执行后保持打开状态。

于 2012-02-03T14:35:46.967 回答
19

Boost test为 Visual Studio提供了以下使用建议,使您能够在编译结束时自动运行单元测试并将输出捕获到构建窗口中。

这个技巧的一个很好的副作用是它使您能够将测试失败视为编译错误。“...您可以使用用于编译错误分析的常用键盘快捷键/鼠标单击来跳过这些错误...”

于 2008-10-11T06:56:49.687 回答
12

在代码的最后一行设置断点。

于 2008-10-11T04:20:04.073 回答
8

我刚刚从http://social.msdn.microsoft.com/forums/en-US/Vsexpressvc/thread/1555ce45-8313-4669-a31e-b95b5d28c787/?prof=required复制:

以下对我有用:-)

///////////////////////////////////////// //////////////////////////////

这是控制台可能消失的另一个原因。和解决方案:

使用新的 Visual Studio 2010,即使您使用Ctrl+ F5aka“不调试就开始”,您也可能会看到这种行为。这很可能是因为您创建了一个“空项目”而不是“Win32 控制台应用程序”。如果您将项目创建为“Win32 控制台应用程序”,则可以忽略它,因为它不适用。

在旧版本中,即使您选择了“空项目”,它也会默认使用控制台子系统,但在 Visual Studio 2010 中则不会,因此您必须手动设置它。为此,请在右侧或左侧的解决方案资源管理器中选择项目(可能已被选中,因此您不必担心这一点)。

然后从菜单栏下拉菜单中选择“项目”,然后选择“项目名称属性”→“配置属性”→“链接器”→“系统”并设置第一个属性,下拉“子系统”属性为“控制台(/子系统:控制台)”。控制台窗口现在应该像往常一样在执行后保持打开状态。

///////////////////////////////////////// //////////////////////////////

于 2011-02-23T09:37:55.070 回答
6

如果是控制台应用程序,请使用Ctrl+ F5

于 2010-11-14T01:56:46.457 回答
3

你说你不想使用system("pause")黑客。为什么不?

如果是因为您不希望程序在调试时提示,那么有一种解决方法。这对我有用:

void pause () {
    system ("pause");
}

int main (int argc, char ** argv) {
    // If "launched", then don't let the console close at the end until
    // the user has seen the report.
    // (See the MSDN ConGUI sample code)
    //
    do {
        HANDLE hConsoleOutput = ::GetStdHandle (STD_OUTPUT_HANDLE);
        if (INVALID_HANDLE_VALUE == hConsoleOutput)
            break;
        CONSOLE_SCREEN_BUFFER_INFO csbi;
        if (0 == ::GetConsoleScreenBufferInfo (hConsoleOutput, &csbi))
            break;
        if (0 != csbi.dwCursorPosition.X)
            break;
        if (0 != csbi.dwCursorPosition.Y)
            break;
        if (csbi.dwSize.X <= 0)
            break;
        if (csbi.dwSize.Y <= 0)
            break;
        atexit (pause);
    } while (0);

我只是将此代码粘贴到我正在编写的每个新控制台应用程序中。如果程序正在从命令窗口运行,则光标位置不会是 <0,0>,并且不会调用atexit(). 如果它已从您的调试器(任何调试器)启动,则控制台光标位置将为 <0,0> 并且atexit()将执行调用。

我从以前在 MSDN 库中的示例程序中得到了这个想法,但我认为它已被删除。

注意:system() 例程的 Microsoft Visual Studio 实现需要 COMSPEC 环境变量来识别命令行解释器。如果这个环境变量搞砸了——例如,如果你在 Visual Studio 项目的调试属性中遇到问题,以至于在程序启动时环境变量没有正确传递——那么它就会默默地失败.

于 2008-11-25T21:39:53.407 回答
3

在 Boost.Test 中,有一个--auto_start_dbg参数用于在测试失败时(异常或断言失败)进入调试器。出于某种原因,它对我不起作用。

请参阅http://www.boost.org/doc/libs/1_40_0/libs/test/doc/html/utf/usage-recommendations/dot-net-specific.html

出于这个原因,我创建了我的自定义 test_observer,它会在出现断言失败或异常时进入调试器。当我们在调试器下运行时,这在调试版本中启用。

在我的单元测试 EXE 文件的源文件之一中,我添加了以下代码:

#ifdef _DEBUG

#include <boost/test/framework.hpp>
#include <boost/test/test_observer.hpp>

struct BoostUnitTestCrtBreakpointInDebug: boost::unit_test::test_observer
{
    BoostUnitTestCrtBreakpointInDebug()
    {
        boost::unit_test::framework::register_observer(*this);
    }

    virtual ~BoostUnitTestCrtBreakpointInDebug()
    {
        boost::unit_test::framework::deregister_observer(*this);
    }

    virtual void assertion_result( bool passed /* passed */ )
    {
        if (!passed)
            BreakIfInDebugger();
    }

    virtual void exception_caught( boost::execution_exception const& )
    {
        BreakIfInDebugger();
    }

    void BreakIfInDebugger()
    {
        if (IsDebuggerPresent())
        {
            /**
             * Hello, I know you are here staring at the debugger :)
             *
             * If you got here then there is an exception in your unit
             * test code. Walk the call stack to find the actual cause.
             */
            _CrtDbgBreak();
        }
    }
};

BOOST_GLOBAL_FIXTURE(BoostUnitTestCrtBreakpointInDebug);

#endif
于 2011-05-03T10:50:11.137 回答
1

这实际上会更费力,但您可以在 VS.Net 中构建,从常规命令行 (cmd.exe) 运行它,然后在它开始运行后附加到进程。然而,这可能不是您正在寻找的解决方案。

于 2008-10-11T01:04:16.810 回答
1

我会在您自己选择的特定时间(毫秒)内使用“等待”命令。应用程序一直执行到您要检查的行,然后在时间到期后继续。

包括<time.h>标题:

clock_t wait;

wait = clock();
while (clock() <= (wait + 5000)) // Wait for 5 seconds and then continue
    ;
wait = 0;
于 2011-02-15T23:35:40.247 回答
1

或者您可以使用 boost_test “测试日志输出”。

http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-output/test-log.html

那么控制台窗口是否显示都无关紧要,并且您的构建日志记录可以将单元测试输出保留为用于检查失败构建的工件......

于 2011-10-26T03:28:09.280 回答
0

只需使用 log4net 之类的日志库,并将其记录到文件 appender。

于 2008-10-11T01:16:29.233 回答
0

您还可以将可执行文件设置为外部工具,并将该工具标记为Use output window。这样,该工具的输出将在 Visual Studio 本身中可见,而不是单独的窗口。

于 2008-10-11T01:58:55.373 回答
0

我用 F11 启动应用程序并在 unit_test_main.ipp 的某处获得一个断点(可以是汇编代码)。我使用 shift-f11 (Step out) 来运行单元测试并在 CRT 中获取下一条汇编指令(通常在 mainCRTStartup() 中)。我使用 F9 在该指令处设置断点。

在下一次调用时,我可以使用 F5 启动应用程序,运行测试后应用程序将中断,因此我有机会查看控制台窗口

于 2010-03-13T23:21:26.357 回答
0

添加以下行将执行一个简单的 MS-DOS,pause不显示任何消息。

system("pause >nul | set /p \"=\"");

并且不需要Ctrl+ F5(这将使您的应用程序在发布模式下运行)

于 2013-08-05T12:54:12.197 回答
0

提示用户输入。

https://www.youtube.com/watch?v=NIGhjrWLWBo

展示了如何为 C++ 做到这一点。对于 Node.js,这是直接从文档中获取的(并且有效):

'use strict';

console.log('Hello world');

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.question('Press enter to continue...', (answer) => {
    rl.close(); /* discard the answer */
});
于 2020-01-12T23:40:18.180 回答
-1

在最后做一个 readline(它是“forma cochina”,就像我们在哥伦比亚说的那样,但它有效):

static void Main(string[] args)
{
    .
    .
    .
    String temp = Console.ReadLine();
}
于 2010-06-05T17:40:54.633 回答