wxWidgets: Wie initialisieren wxApp ohne Makros zu verwenden und ohne die Hauptschleife eingeben?

StackOverflow https://stackoverflow.com/questions/208373

Frage

Wir brauchen Unit-Tests für eine wxWidgets Anwendung mit Google Test Framework schreiben. Das Problem ist, dass wxWidgets verwendet das Makro IMPLEMENT_APP (MyApp) zu initialisieren und die Anwendung Hauptschleife ein. Dieses Makro erstellt mehrere Funktionen einschließlich int main () . Das Google-Test-Framework verwendet auch Makrodefinitionen für jeden Test.

Eines der Probleme ist, dass es nicht möglich ist, die wxWidgets Makro aus dem Test-Makro aufrufen, weil die erste Funktionen schafft .. So fanden wir, dass wir das Makro mit dem folgenden Code ersetzen könnte:

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

Das ist ein guter Ersatz, aber wxEntry () Aufruf tritt in die ursprüngliche Anwendung Schleife. Wenn wir es nicht wxEntry () aufrufen, sind noch einige Teile der Anwendung nicht initialisiert.

Die Frage ist, wie alles für einen wxApp zur Initialisierung auszuführen, ohne es wirklich zu laufen, also sind wir zu Unit-Test-Teilen davon können?

War es hilfreich?

Lösung

Sie möchten die Funktion verwenden:

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

statt wxEntry. Dabei spielt es keine App-OnInit () aufrufen oder die Hauptschleife ausgeführt werden.

Sie können wxTheApp->CallOnInit() nennen OnInit () aufzurufen, wenn in Ihren Tests benötigt werden.

Sie müssen verwenden

void wxEntryCleanup()

, wenn Sie fertig sind.

Andere Tipps

Nur durch diese gewesen, mich mit 2.8.10. Die Magie ist dies:

// 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();

Sie können nur eine Instanz wxApp erstellen, anstatt Ihre eigene Klasse mit der Technik, die oben abgeleitet wird.

Ich bin mir nicht sicher, wie Sie Unit-Tests Ihrer Anwendung zu tun erwarten ohne Eingabe funktionieren die mainloop so viele wxWidgets-Komponenten, die Lieferung von Ereignissen erfordern. Die übliche Vorgehensweise wäre Unit-Tests auszuführen, nachdem die Hauptschleife eingeben.

IMPLEMENT_APP_NO_MAIN(MyApp);
IMPLEMENT_WX_THEME_SUPPORT;

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

    return 0;
}

Es sieht die Tests im wxApp :: OnRun () Funktion kann vielleicht funktionieren wie zu tun. Hier ist Code, der einen Dialog Titel mit cppUnitLite2 testet.

 
#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(); 
}

Sie könnten möglicherweise die Situation umdrehen:

Initialisieren und den WxPython App mit der Hauptschleife beginnen, dann die Unit-Tests aus der App heraus laufen. Ich denke, dass es eine Funktion bei der Hauptschleife Eintrag, nachdem alle init Sachen gemacht wird genannt wird.

Haben Sie das IMPLEMENT_APP_NO_MAIN Makro versucht? Der Kommentar über die Makrodefinition bereitgestellt schlägt vor, es könnte das tun, was Sie brauchen, um es zu.

Von \ 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()); }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top