jeudi 3 septembre 2015

Unable to run unit tests on Gtk Application more than once in same test program

I am writing a series of unit tests on a Gtk Application in Vala and I have encountered a problem with instantiating and running a Gtk Application more than once inside the test program.

The first time the application is instantiated and run everything works as expected but the subsequent times it fails with the message:

Failed to register: An object is already exported for the interface org.gtk.Application at /org/valarade/testtools

From what I understand of the Gtk Application life cycle the Application has registered itself on the local DBus session bus as a single instance application which prevents additional instances from being run.

Using the d-feet application I am able to watch the application register itself on the local bus the first time it runs and it appears to deregister itself when the running test function terminates. There is no trace of it when the subsequent test function instantiates and runs a new instance but the above error is returned nonetheless.

I have tried several things, including making sure that all the objects referenced by the application are destroyed as well as the application object itself between test functions. I have tried calling connection.close_sync in the class destructor and setting register_session to false but neither had any effect.

The sample code for the Test Program

static void main (string[] args) {

    Gtk.test_init (ref args);

    TestSuite.get_root ().add_suite (new FileLoaderPluginTests ().get_suite ());

    Idle.add (() => {
        Test.run ();
        Gtk.main_quit ();
        return true;
    });

    Gtk.main ();
}

and the code for the Test Suite

public FileLoaderPluginTests () {
    add_test ("method on_open_activate ()", file_loader_on_open_activate);
    add_test ("method on_open_response_ok ()", file_loader_on_open_response_ok);
}


public void file_loader_on_open_activate () {
    var app = new MockApplication ();

    app.activate.connect ((a) => {
        var action = app.shell.lookup_action ("file_open");
        action.activate (null);
        app.quit();
    });

    app.run ();
    app = null;

}

public void file_loader_on_open_response_ok () {
    var app = new MockApplication ();

    app.activate.connect ((a) => {
        var action = app.shell.lookup_action ("file_open");
        action.activate (null);
        app.quit();
    });

    app.run ();
}

It appears to me that the DBus session registration is for the life of the running Test program not the Application class itself. I've been through the precious little documentation there is and I can't seem to grock anything that would allow me deregister the Application after each test.

Although I can work around this by setting up distinct Test programs for each unit test, this seems to be a lot of unnecessary duplication. Ideally I would like to have one test program for each logical unit in the whole application whereas this way it could result in quite a number by the time there's any significant code coverage.

My question is then - is there any way I can create, run and destroy a Gtk Application multiple times within a Test program? Alternatively, is there a better way to test Gtk Applications that obviates this problem?

Aucun commentaire:

Enregistrer un commentaire