-
-
Notifications
You must be signed in to change notification settings - Fork 415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add missed dialogs to qtbot
in test_qt_notifications
to prevent segfaults
#5171
Conversation
Codecov Report
@@ Coverage Diff @@
## main #5171 +/- ##
=======================================
Coverage 88.78% 88.78%
=======================================
Files 572 573 +1
Lines 48810 48892 +82
=======================================
+ Hits 43336 43410 +74
- Misses 5474 5482 +8
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
qtbot
in test_qt_notifications
to prevent segfaults
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I almost want to rewrite these tests from scratch, but there's nothing from with this changes as far as I can see, so I'm approving.
Which dialog was not being added to qtbot
?
qtbot.add_widget(widget) | ||
show_count = 0 | ||
|
||
def mock_show_dialog(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional: might be nice to either define a fixture for this to be consistent with NapariQtNotification
, or just use a plain function instead of a callable and pass the class for which you want to mock show
(i.e. NapariQtNotification
or TracebackDialog
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put comments where NapariQtNotification
are created without using qtbot
.
@@ -125,17 +147,16 @@ def run(self): | |||
res = NapariQtNotification.show_notification(notif) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This created here.
@@ -162,9 +183,9 @@ def test_notification_display( | |||
notif = Notification('hi', severity, actions=[('click', lambda x: None)]) | |||
NapariQtNotification.show_notification(notif) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This created here
|
||
def mock_show_dialog(self): | ||
stat.show_count += 1 | ||
qtbot.add_widget(self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only adds the widget on each call of show
. If there are no calls that means it won't be added, which I guess is why we also have the other calls to add_widget
in the tests. Could we patch __init__
so that we add it exactly once instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you check now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I recall correctly, all the tests were passing before this change, but now the flaky windows 3.8 pyside2 test is failing again due to test_qt_notifications
. We might have just got lucky before this change and I don't see any reason why the new changes are worse than the previous ones, but just wondered if you had any thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found 2 places..
But they are failing only if run all tests, not when running individual tests.
Thanks for clarifying. Added an optional question/suggestion, but still looks fine to me. |
1b928a3
to
869f969
Compare
qtbot
in test_qt_notifications
to prevent segfaultsqtbot
in test_qt_notifications
to prevent segfaults
old_traceback_init(self, *args, **kwargs) | ||
qtbot.add_widget(self) | ||
|
||
monkeypatch.setattr(NapariQtNotification, "__init__", mock_notif_init) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will the class definition (e.g. NapariQtNotification
) be imported fresh for each test function? Or is there a risk that old_notif_init
may be the definition from the last test function run?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pytest monkeypatch, restore previous value on test end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found 2 calls of show functions that also start animations, that may be reason of faliture.
@pytest.fixture(autouse=True) | ||
def raise_on_show(monkeypatch, qtbot): | ||
def _raise_on_show(self, *args, **kwargs): | ||
raise RuntimeError('error!') | ||
|
||
monkeypatch.setattr(NapariQtNotification, 'show', _raise_on_show) | ||
monkeypatch.setattr(TracebackDialog, 'show', _raise_on_show) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixture raises an exception on the show call if another fixture does not mock it.
old_traceback_init(self, *args, **kwargs) | ||
qtbot.add_widget(self) | ||
|
||
monkeypatch.setattr(NapariQtNotification, "__init__", mock_notif_init) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pytest monkeypatch, restore previous value on test end
monkeypatch.setattr( | ||
NapariQtNotification, "show_notification", lambda x: None | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, it is only a workaround, but I do not have any idea how to do this better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏼
monkeypatch.setattr( | ||
NapariQtNotification, "show_notification", lambda x: None | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me, it is only a workaround, but I do not have any idea how to do this better.
Still fails... |
|
||
bttn = dialog.row2_widget.findChild(QPushButton) | ||
assert bttn.text() == 'View Traceback' | ||
mock_show.assert_not_called() | ||
assert count_show.show_traceback_count == 0 | ||
bttn.click() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks like I found a source of the problem. The click of this button is called close_with_fade
which starts a timer.
And just after this test, there is a segfault.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good @Czaki ! thanks for working on this
I'll merge this after 24 hours unless there are any objections. |
…egfaults (#5171) * check another approach to collect items * guard other dialogs * mock __init__ for add to qtbot * test to find show calls * disable show_notifications * put monkeypatch in better place * close with fade
…egfaults (#5171) * check another approach to collect items * guard other dialogs * mock __init__ for add to qtbot * test to find show calls * disable show_notifications * put monkeypatch in better place * close with fade
…egfaults (#5171) * check another approach to collect items * guard other dialogs * mock __init__ for add to qtbot * test to find show calls * disable show_notifications * put monkeypatch in better place * close with fade
…egfaults (#5171) * check another approach to collect items * guard other dialogs * mock __init__ for add to qtbot * test to find show calls * disable show_notifications * put monkeypatch in better place * close with fade
…egfaults (#5171) * check another approach to collect items * guard other dialogs * mock __init__ for add to qtbot * test to find show calls * disable show_notifications * put monkeypatch in better place * close with fade
…egfaults (#5171) * check another approach to collect items * guard other dialogs * mock __init__ for add to qtbot * test to find show calls * disable show_notifications * put monkeypatch in better place * close with fade
…egfaults (#5171) * check another approach to collect items * guard other dialogs * mock __init__ for add to qtbot * test to find show calls * disable show_notifications * put monkeypatch in better place * close with fade
Description
update of
test_qt_notifications.py
to better guard Qt object.Type of change
References
How has this been tested?
as there are small differences between the two Qt bindings.
Final checklist:
trans.
to make them localizable.For more information see our translations guide.