【发布时间】:2015-09-04 00:10:35
【问题描述】:
我正在 Vala 中对 Gtk 应用程序编写一系列单元测试,但在测试程序中多次实例化和运行 Gtk 应用程序时遇到了问题。
第一次实例化应用程序并运行一切正常,但随后失败并显示消息:
Failed to register: An object is already exported for the interface org.gtk.Application at /org/valarade/testtools
根据我对 Gtk 应用程序生命周期的了解,该应用程序已在本地 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 ();
}
以及测试套件的代码
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 会话注册是针对正在运行的测试程序的生命周期,而不是应用程序类本身。我已经浏览了那里宝贵的小文档,但我似乎无法在每次测试后取消注册应用程序的任何内容。
虽然我可以通过为每个单元测试设置不同的测试程序来解决这个问题,但这似乎是很多不必要的重复。理想情况下,我希望为整个应用程序中的每个逻辑单元都有一个测试程序,而这样一来,当有任何重要的代码覆盖时,它可能会产生相当多的结果。
然后我的问题是 - 有什么方法可以在测试程序中多次创建、运行和销毁 Gtk 应用程序?或者,有没有更好的方法来测试 Gtk 应用程序来避免这个问题?
【问题讨论】:
标签: unit-testing gtk dbus vala