[PyQt] unit testing pyqt app components

oliver oliver.schoenborn at gmail.com
Thu Sep 3 14:41:52 BST 2015


Thanks I'll check it out, if anything I can use some of the techniques. But
if I were to switch some tests over to pytest+qt plugin, basically the
first test would create the QApplication, and once the exec is entered in
first test, it never returns until the whole test suite is done? How does
the test driver ever regain control to start the next test (which will
presumably just create a widget and not call exec())?

With nose, we use a class that allows us to schedule "actions" (like
clicking a button, verifying the state of some object, etc). A test
basically schedules a bunch of actions (callbacks defined in the test) then
enters a custom exec() that adds a "quit" action to exit the event loop
once all actions are done, and calls the app exec(). Then control goes back
to nose and the process repeats. I don't think QApplication ever gets
destroyed, but its exec() is therefore called multiple times. Isn't this
how QTestLib.exec() is meant to be used?

On Tue, Sep 1, 2015 at 12:19 AM, Florian Bruhin <me at the-compiler.org> wrote:

> * oliver <oliver.schoenborn at gmail.com> [2015-08-31 23:38:31 -0400]:
> > We have a large pyqt-based application, PyQt works awesome. We use python
> > nose for unit tests of business logic, and we have a set of unit tests
> for
> > the GUI components.
>
> I'd recommend switching to pytest[1] with its excellent pytest-qt[2]
> plugin which solves those problems for you ;)
>
> It can even run nose tests, so you can gradually switch over.
>
> It also has a way[3] to wait until a signal is emitted (with a
> timeout) where it spins a QEventLoop.
>
> (disclaimer: I'm a contributor to both pytest and the plugin)
>
> [1] https://github.com/pytest-dev/pytest
> [2] https://github.com/pytest-dev/pytest-qt
> [3] https://pytest-qt.readthedocs.org/en/1.5.1/signals.html
>
> > However, sometimes it appears that resources are not properly cleaned up
> > between tests: a test will crash, or will not start unless we have put a
> > "del some_qwidget_instance" in the teardown. Is it safe to re-use the
> same
> > QApplication instance after its exec() has returned? I.e. can we do this:
> >
> > app = QApplication([])
> > my_gui_obj = MyGuiObj()  # derives from QWidget
> > # other stuff
> > app.exec()
> > my_gui_obj2 = MyGuiObj()  # derives from QWidget
> > # other stuff
> > app.exec()
> > my_gui_obj3 = MyGuiObj()  # derives from QWidget
> > # other stuff
> > app.exec()
> >
> > Is there anything we should do to QApplication instance between tests
> > (clear some caches, reset things like styles etc) so that each tests
> starts
> > with a "fresh" QApplication? What is the recommended way to test multiple
> > PyQt components independently of each other?
>
> I don't think you should reuse a QApplication after you (I guess)
> called QApplication::quit.
>
> pytest-qt runs QApplication::processEvents before and after each test
> - it's not ideal, but it's the best we could come up with so far.
>
> Another solution might be to run a dedicated QEventLoop every time,
> like the waitSignal thing in [3].
>
> Florian
>
> --
> http://www.the-compiler.org | me at the-compiler.org (Mail/XMPP)
>    GPG: 916E B0C8 FD55 A072 | http://the-compiler.org/pubkey.asc
>          I love long mails! | http://email.is-not-s.ms/
>
> _______________________________________________
> PyQt mailing list    PyQt at riverbankcomputing.com
> https://www.riverbankcomputing.com/mailman/listinfo/pyqt
>



-- 
Oliver
Author of these Open Source: PyPubSub <http://pubsub.sf.net>, Lua-iCxx
<http://lua-icxx.sf.net>, iof <http://iof.sf.net>
Regular contributor on StackOverflow
<http://stackoverflow.com/users/869951/schollii>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20150903/b6d686db/attachment.html>


More information about the PyQt mailing list