automation
making hooq work with pyQt and Qt4.7
GUI automation test for desktop apps with Qt could be a PIA, not only because GUI automation is simply a PIA in general,
but there are just not that much free open source tools you can make use of for Qt. Or I should say at least for me it is not easy to find any.
Almost all tools I found online are heavy weight commercial software
that have this long and fancy feature set that I have to buy as a whole, out of which most I may never touch.
Luckily I found hooq, a free, open source tool to help recording qt events
and replay them (which is exactly what I need, for now). Like all other free lunches it does take me some effort to make it useful for me. And kudos to my genius coworker Leaf
who figured out how to build all the packages hooq requires to make this happen. It seems most people got stuck on this very first step.
But then I got stuck on another problem:
although hooq can be executed fine and it can launch my app correctly, it won’t record any of my actions.
All I got was requireHooqScriptVersion(2);
I spent a whole day digging into this and it seems to be a timing issue.
fundamentally hooq uses gdb to track all the qt events by inserting breaks on all QCoreApplication::exec
and sometimes (I’m not sure if this is a system thing) the timing of loading the shared libraries could be different
and that will cause the breaks failed to be set, thus the recording won’t take effect
after trying different combinations, I modify void GdbInjector::startProcess() in GdbInjecter.cpp into the following
and this seem to work for me:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | void GdbInjector::startProcess() { QString argumentsString; Q_FOREACH(QString argument, m_applicationArguments) { argument.replace('"', "\\\""); argumentsString.append(QString(" \"%1\"").arg(argument)); } Q_ASSERT(m_gdb->state() == QProcess::Running); Q_ASSERT(m_gdb->isWritable()); m_gdbStream.setDevice(m_gdb); m_gdbStream << "set breakpoint pending on" << endl; m_gdbStream << "set auto-solib-add off" << endl; // avoid loading symbols for shared libraries // that we do not need to interact with from GDB m_gdbStream << "break _start" << endl; // C entry point - after main libraries have been loaded m_gdbStream << "set args" << argumentsString << endl; m_gdbStream << "run" << endl; // run until we hit it, and therefore Qt shared libraries are loaded m_gdbStream << "sharedlibrary libdl" << endl; // load the libdl library so that we can call __dlopen() m_gdbStream << "sharedlibrary libc" << endl; // load the libc library so that we can call __dlopen() //m_gdbStream << QString("call dlopen(\"/usr/lib64/libQtCore.so.4\",%1)").arg(QString::number(RTLD_NOW)) << endl; // Newer systems m_gdbStream << QString("call dlopen(\"%1\", %2)").arg(libraryPath()).arg(QString::number(RTLD_NOW)) << endl; // load our library // Older systems m_gdbStream << QString("call __dlopen(\"%1\", %2)").arg(libraryPath()).arg(QString::number(RTLD_NOW)) << endl; // load our library m_gdbStream << "sharedlibrary libQtCore" << endl; // load QtCore for breaking on QCoreApplication::exec() m_gdbStream << "sharedlibrary libQtGui" << endl; // load QtCore for breaking on QCoreApplication::exec() m_gdbStream << "break QCoreApplication::exec" << endl; // now, we can set this breakpoint... m_gdbStream << "continue" << endl; m_gdbStream << "sharedlibrary injectedHooq" << endl; // load the hooq injector library so that we can call startHooq() m_gdbStream << "call startHooq()" << endl; // install our plugin (which required QCoreApplication setup) m_gdbStream << "continue" << endl; // run the app m_gdbStream << "backtrace" << endl; // just in case (use with --spam) m_gdbStream << "quit" << endl; // after the application has exited, quit gdb } |
| M | T | W | T | F | S | S |
|---|---|---|---|---|---|---|
| « Aug | ||||||
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 | 31 | ||
Archives
Tags
Recent Posts
Recent Comments
- LIBPF blog Testing UI with UI scripting: getting hooq to work | on making hooq work with pyQt and Qt4.7
- Mads Bondo Dydensborg on making hooq work with pyQt and Qt4.7
- Automatic Qt gui testing with Hooq – getting it to compile and work « Madsdyd's Weblog on making hooq work with pyQt and Qt4.7
- wangtian on A regular expression I just wrote today (and a wonderful tool I just digged)
- wangtian on A regular expression I just wrote today (and a wonderful tool I just digged)