我正在Vala中的Gtk应用程序上编写一系列单元测试,我遇到了在测试程序中多次实例化和运行Gtk应用程序的问题。
第一次实例化应用程序并运行时,一切都按预期工作,但随后的时间失败并显示消息:
Failed to register: An object is already exported for the interface org.gtk.Application at /org/valarade/testtools
根据我对Gtk应用程序生命周期的理解,Application已将自身注册在本地DBus会话总线上作为单实例应用程序,以防止运行其他实例。
使用d-feet应用程序我能够在第一次运行时在本地总线上观察应用程序注册本身,并且当运行的测试功能终止时,它似乎会注销自身。当后续测试函数实例化并运行一个新实例时,它没有任何痕迹,但仍会返回上述错误。
我尝试了几件事,包括确保应用程序引用的所有对象以及测试函数之间的应用程序对象本身都被销毁。我试过在类析构函数中调用connection.close_sync并将register_session设置为false但是没有任何影响。
测试计划的示例代码
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 ();
}
以及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 ();
}
在我看来,DBus会话注册是针对正在运行的测试程序的生命周期,而不是Application类本身。我已经阅读了那些珍贵的小文档,我似乎无法解决任何可以让我在每次测试后取消注册应用程序的事情。
虽然我可以通过为每个单元测试设置不同的测试程序来解决这个问题,但这似乎是很多不必要的重复。理想情况下,我希望在整个应用程序中为每个逻辑单元设置一个测试程序,这样,当有任何重要的代码覆盖时,它可能会产生相当多的数字。
我的问题是 - 我有什么方法可以在测试程序中多次创建,运行和销毁Gtk应用程序?或者,有没有更好的方法来测试Gtk应用程序来避免这个问题?
答案 0 :(得分:1)
由于DBus通信是异步的,我猜你的应用程序名称在下一次测试启动下一个应用程序时尚未从总线取消注册。
测试应用程序类的一些技巧:
PS。我相信Test.run()
已经为你运行了一个主循环,所以你不需要在空闲函数中启动测试套件。