我们需要使用 Google Test Framework 为 wxWidgets 应用程序编写单元测试。 问题是 wxWidgets 使用宏 IMPLEMENT_APP(MyApp)来初始化并进入应用程序主循环。该宏创建了几个函数,包括 int main()。谷歌测试框架还为每个测试使用宏定义。
其中一个问题是无法从测试宏中调用wxWidgets宏,因为第一个宏创建了函数..因此,我们发现我们可以用以下代码替换宏:
wxApp* pApp = new MyApp();
wxApp::SetInstance(pApp);
wxEntry(argc, argv);
这是一个很好的替代品,但是wxEntry()调用进入原始应用程序循环。如果我们不调用wxEntry(),那么应用程序的某些部分仍未初始化。
问题是如何初始化运行wxApp所需的所有内容,而不实际运行它,因此我们可以对其中的部分进行单元测试?
答案 0 :(得分:12)
用2.8.10自己完成了这个。神奇的是:
// MyWxApp derives from wxApp
wxApp::SetInstance( new MyWxApp() );
wxEntryStart( argc, argv );
wxTheApp->OnInit();
// you can create top level-windows here or in OnInit()
...
// do your testing here
wxTheApp->OnRun();
wxTheApp->OnExit();
wxEntryCleanup();
你可以创建一个wxApp实例,而不是使用上面的技术派生你自己的类。
我不确定您希望如何在不进入mainloop的情况下对应用程序进行单元测试,因为许多wxWidgets组件需要传递事件才能运行。通常的方法是在进入主循环后运行单元测试。
答案 1 :(得分:5)
IMPLEMENT_APP_NO_MAIN(MyApp);
IMPLEMENT_WX_THEME_SUPPORT;
int main(int argc, char *argv[])
{
wxEntryStart( argc, argv );
wxTheApp->CallOnInit();
wxTheApp->OnRun();
return 0;
}
答案 2 :(得分:3)
您想使用以下功能:
bool wxEntryStart(int& argc, wxChar **argv)
而不是wxEntry。它不会调用您的应用程序的OnInit()或运行主循环。
您可以在测试中需要时调用wxTheApp->CallOnInit()
来调用OnInit()。
您需要使用
void wxEntryCleanup()
当你完成。
答案 3 :(得分:1)
看起来在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(); }
答案 4 :(得分:-1)
你可能会扭转局面:
初始化并启动包含主循环的wxPython应用程序,然后在应用程序内运行单元测试。我认为在完成所有初始化之后,有一个函数调用主循环入口。
答案 5 :(得分:-1)
您是否尝试过IMPLEMENT_APP_NO_MAIN
宏?宏观定义上面提供的评论表明它可能会满足您的需求。
来自< 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()); }