wxWidgets:如何在不使用宏且不进入主应用程序循环的情况下初始化wxApp?

发布于 2024-07-07 05:08:54 字数 522 浏览 8 评论 0 原文

我们需要使用 Google 测试框架wxWidgets 应用程序编写单元测试。 问题在于wxWidgets使用宏IMPLMENT_APP(MyApp)来初始化并进入应用程序主循环。 该宏创建了多个函数,包括int main()。 谷歌测试框架还为每个测试使用宏定义。

问题之一是不可能从测试宏中调用 wxWidgets 宏,因为第一个宏创建了函数。因此,我们发现可以用以下代码替换该宏:

wxApp* pApp = new MyApp(); 
wxApp::SetInstance(pApp);
wxEntry(argc, argv);

这是一个很好的替换,但是wxEntry() 调用进入原始应用程序循环。 如果我们不调用wxEntry(),应用程序的某些部分仍然没有初始化。

问题是如何初始化 wxApp 运行所需的一切,而不实际运行它,以便我们能够对其部分进行单元测试?

We need to write unit tests for a wxWidgets application using Google Test Framework.
The problem is that wxWidgets uses the macro IMPLEMENT_APP(MyApp) to initialize and enter the application main loop. This macro creates several functions including int main(). The google test framework also uses macro definitions for each test.

One of the problems is that it is not possible to call the wxWidgets macro from within the test macro, because the first one creates functions.. So, we found that we could replace the macro with the following code:

wxApp* pApp = new MyApp(); 
wxApp::SetInstance(pApp);
wxEntry(argc, argv);

That's a good replacement, but wxEntry() call enters the original application loop. If we don't call wxEntry() there are still some parts of the application not initialized.

The question is how to initialize everything required for a wxApp to run, without actually running it, so we are able to unit test portions of it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

情释 2024-07-14 05:08:54

我自己刚刚在 2.8.10 中经历过这个。 神奇之处在于:

// MyWxApp derives from wxApp
wxApp::SetInstance( new MyWxApp() );
wxEntryStart( argc, argv );
wxTheApp->CallOnInit();

// you can create top level-windows here or in OnInit()
...
// do your testing here

wxTheApp->OnRun();
wxTheApp->OnExit();
wxEntryCleanup();

您可以只创建一个 wxApp 实例,而不是使用上面的技术派生您自己的类。

我不确定您希望如何在不进入主循环的情况下对应用程序进行单元测试,因为许多 wxWidgets 组件需要传递事件才能发挥作用。 通常的方法是在进入主循环后运行单元测试。

Just been through this myself with 2.8.10. The magic is this:

// MyWxApp derives from wxApp
wxApp::SetInstance( new MyWxApp() );
wxEntryStart( argc, argv );
wxTheApp->CallOnInit();

// you can create top level-windows here or in OnInit()
...
// do your testing here

wxTheApp->OnRun();
wxTheApp->OnExit();
wxEntryCleanup();

You can just create a wxApp instance rather than deriving your own class using the technique above.

I'm not sure how you expect to do unit testing of your application without entering the mainloop as many wxWidgets components require the delivery of events to function. The usual approach would be to run unit tests after entering the main loop.

与往事干杯 2024-07-14 05:08:54
IMPLEMENT_APP_NO_MAIN(MyApp);
IMPLEMENT_WX_THEME_SUPPORT;

int main(int argc, char *argv[])
{
    wxEntryStart( argc, argv );
    wxTheApp->CallOnInit();
    wxTheApp->OnRun();

    return 0;
}
IMPLEMENT_APP_NO_MAIN(MyApp);
IMPLEMENT_WX_THEME_SUPPORT;

int main(int argc, char *argv[])
{
    wxEntryStart( argc, argv );
    wxTheApp->CallOnInit();
    wxTheApp->OnRun();

    return 0;
}
别再吹冷风 2024-07-14 05:08:54

你想使用函数:

bool wxEntryStart(int& argc, wxChar **argv)

而不是wxEntry。 它不会调用应用程序的 OnInit() 或运行主循环。

您可以在测试中需要时调用wxTheApp->CallOnInit()来调用OnInit()。

您需要使用。

void wxEntryCleanup()

完成后

You want to use the function:

bool wxEntryStart(int& argc, wxChar **argv)

instead of wxEntry. It doesn't call your app's OnInit() or run the main loop.

You can call wxTheApp->CallOnInit() to invoke OnInit() when needed in your tests.

You'll need to use

void wxEntryCleanup()

when you're done.

黎夕旧梦 2024-07-14 05:08:54

看起来在 wxApp::OnRun() 函数中进行测试也许可以工作。
下面是使用 cppUnitLite2 测试对话框标题的代码。

 
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif
#include  "wx/app.h"  // use square braces for wx includes: I made quotes to overcome issue in HTML render
#include  "wx/Frame.h"
#include "../CppUnitLite2\src/CppUnitLite2.h"
#include "../CppUnitLite2\src/TestResultStdErr.h" 
#include "../theAppToBeTested/MyDialog.h"
 TEST (MyFirstTest)
{
    // The "Hello World" of the test system
    int a = 102;
    CHECK_EQUAL (102, a);
}

 TEST (MySecondTest)
 {
    MyDialog dlg(NULL);   // instantiate a class derived from wxDialog
    CHECK_EQUAL ("HELLO", dlg.GetTitle()); // Expecting this to fail: title should be "MY DIALOG" 
 }

class MyApp: public wxApp
{
public:
    virtual bool OnInit();
    virtual int OnRun();
};

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{   
    return true;
}

int MyApp::OnRun()
{
    fprintf(stderr, "====================== Running App Unit Tests =============================\n");
    if ( !wxApp::OnInit() )
        return false;

    TestResultStdErr result;
    TestRegistry::Instance().Run(result);   
    fprintf(stderr, "====================== Testing end: %ld errors =============================\n", result.FailureCount() );

    return result.FailureCount(); 
}

It looks like doing the tests in the wxApp::OnRun() function can perhaps work.
Here's code that tests a dialog's title with cppUnitLite2.

 
#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif
#include  "wx/app.h"  // use square braces for wx includes: I made quotes to overcome issue in HTML render
#include  "wx/Frame.h"
#include "../CppUnitLite2\src/CppUnitLite2.h"
#include "../CppUnitLite2\src/TestResultStdErr.h" 
#include "../theAppToBeTested/MyDialog.h"
 TEST (MyFirstTest)
{
    // The "Hello World" of the test system
    int a = 102;
    CHECK_EQUAL (102, a);
}

 TEST (MySecondTest)
 {
    MyDialog dlg(NULL);   // instantiate a class derived from wxDialog
    CHECK_EQUAL ("HELLO", dlg.GetTitle()); // Expecting this to fail: title should be "MY DIALOG" 
 }

class MyApp: public wxApp
{
public:
    virtual bool OnInit();
    virtual int OnRun();
};

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{   
    return true;
}

int MyApp::OnRun()
{
    fprintf(stderr, "====================== Running App Unit Tests =============================\n");
    if ( !wxApp::OnInit() )
        return false;

    TestResultStdErr result;
    TestRegistry::Instance().Run(result);   
    fprintf(stderr, "====================== Testing end: %ld errors =============================\n", result.FailureCount() );

    return result.FailureCount(); 
}
香草可樂 2024-07-14 05:08:54

您可以扭转这种情况:

初始化并启动 wxPython 应用程序(包括主循环),然后从应用程序内运行单元测试。 我认为在所有初始化工作完成后,有一个在主循环入口处调用的函数。

You could possibly turn the situation around:

Initialize and start the wxPython app including the main loop, then run the unit tests from within the app. I think there is a function called upon main loop entry, after all init stuff is done.

情深已缘浅 2024-07-14 05:08:54

您是否尝试过 IMPLMENT_APP_NO_MAIN 宏? 宏定义上方提供的注释表明它可能会执行您需要的操作。

\include\wx.h:

// Use this macro if you want to define your own main() or WinMain() function
// and call wxEntry() from there.
#define IMPLEMENT_APP_NO_MAIN(appname)                                      \
   wxAppConsole *wxCreateApp()                                             \
    {                                                                       \
        wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE,         \
                                        "your program");                    \
        return new appname;                                                 \
    }                                                                       \
    wxAppInitializer                                                        \
        wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp);        \
    DECLARE_APP(appname)                                                    \
    appname& wxGetApp() { return *wx_static_cast(appname*, wxApp::GetInstance()); }

Have you tried the IMPLEMENT_APP_NO_MAIN macro? The comment provided above the macro definition suggests it might do what you need it to.

From <wxWidgets' source dir>\include\wx.h:

// Use this macro if you want to define your own main() or WinMain() function
// and call wxEntry() from there.
#define IMPLEMENT_APP_NO_MAIN(appname)                                      \
   wxAppConsole *wxCreateApp()                                             \
    {                                                                       \
        wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE,         \
                                        "your program");                    \
        return new appname;                                                 \
    }                                                                       \
    wxAppInitializer                                                        \
        wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp);        \
    DECLARE_APP(appname)                                                    \
    appname& wxGetApp() { return *wx_static_cast(appname*, wxApp::GetInstance()); }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文