pytest-qt icon indicating copy to clipboard operation
pytest-qt copied to clipboard

QApplication.quit breaks following tests

Open rdevries-thoughtworks opened this issue 4 years ago • 6 comments

I have a test that uses waitCallback, which succeeds when run in isolation, but fails if a QApplication.quit is run from my code somewhere before. In that case, it fails immediately (not after the timeout), with a TimeoutError.

(Sorry I don't have time (now) to give more details, might that be necessary)

rdevries-thoughtworks avatar Oct 30 '20 13:10 rdevries-thoughtworks

I don't think this is pytest-qt's fault - if you run QApplication.quit but then later run tests which require a QApplication (and anything relying on the Qt mainloop, including singlas, do), all bets are off.

The-Compiler avatar Oct 30 '20 13:10 The-Compiler

Hi @The-Compiler , I don't want to blame anyone. ;-) If you'd create a separate QApplication for every test, though, that would fix this issue, right? I'm not sure if there's any (performance) issues with that, but otherwise having isolated tests is super valuable, and shared state between tests generally a huge pain to deal with.

rdevries-thoughtworks avatar Oct 30 '20 14:10 rdevries-thoughtworks

As far as I'm aware, a QApplication object can't be reliably destroyed/recreated. You'd probably need to run every test in a separate process with something like pytest-forked.

The-Compiler avatar Oct 30 '20 14:10 The-Compiler

Ouch! I see. Would it make sense (and be possible) to just crash the tests or fail with a clear message if the QApplication has been quit? Then at least debugging becomes easier.

rdevries-thoughtworks avatar Oct 30 '20 16:10 rdevries-thoughtworks

Perhaps it'd be possible to connect to the aboutToQuit signal and somehow exit/fail in that case - I'm not entirely sure, though. Certainly worth to try.

The-Compiler avatar Oct 30 '20 16:10 The-Compiler

There is an undocumented shutdown method that can be used, before creating another QCoreApplication. You can try it out with this:

#!/usr/bin/env python3
from PySide2.QtCore import QCoreApplication as Application
Application().shutdown()
Application().shutdown()

An example of this in unit tests. Making this work in more cases is... fiddly to say the least. I have to stress again that it is undocumented though. (Also be warned that, if you try to make this work, there seems to be some QCoreApplication inheritance issue in Python 3.9, causing my QTestApplication to crash in Debian.)

BoniLindsley avatar Dec 10 '20 01:12 BoniLindsley