diff --git a/continuous_integration/appveyor/run_test.bat b/continuous_integration/appveyor/run_test.bat index e5aec45ac3f..730e68fea07 100644 --- a/continuous_integration/appveyor/run_test.bat +++ b/continuous_integration/appveyor/run_test.bat @@ -17,12 +17,6 @@ conda install -q -y --use-local spyder-dev :: Install extra packages conda install -q -y %EXTRA_PACKAGES% -:: Test that the app starts correctly -echo ------- Testing the app --------- -echo. -echo %time% -:: skipping spyder || exit 1 -echo Success! -echo %time% -echo. -echo --------------------------------- +:: NOTE: We don't run Spyder here because it times out +:: most of the time. However, the whole window is now +:: run as part of our pytest's. diff --git a/runtests.py b/runtests.py index fa751a13128..1147a8b2067 100644 --- a/runtests.py +++ b/runtests.py @@ -10,7 +10,6 @@ # Standard library imports import os -import sys # Third party imports import qtpy # to ensure that Qt4 uses API v2 @@ -27,7 +26,13 @@ def main(): """ errno = pytest.main(['-x', 'spyder', '-v', '-rw', '--durations=10', '--cov=spyder', '--cov-report=term-missing']) - sys.exit(errno) + + # sys.exit doesn't work here because some things could be running + # in the background (e.g. closing the main window) when this point + # is reached. And if that's the case, sys.exit does't stop the + # script (as you would expected). + if errno != 0: + raise SystemExit(errno) if __name__ == '__main__': main() diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py index ba6aa056bf1..ab554d02aaa 100644 --- a/spyder/app/mainwindow.py +++ b/spyder/app/mainwindow.py @@ -1129,7 +1129,10 @@ def add_ipm_action(text, path): # Menu about to show for child in self.menuBar().children(): if isinstance(child, QMenu): - child.aboutToShow.connect(self.update_edit_menu) + try: + child.aboutToShow.connect(self.update_edit_menu) + except TypeError: + pass self.debug_print("*** End of MainWindow setup ***") self.is_starting_up = False diff --git a/spyder/app/tests/test_mainwindow.py b/spyder/app/tests/test_mainwindow.py index 635fab6bd6a..abc60c22087 100644 --- a/spyder/app/tests/test_mainwindow.py +++ b/spyder/app/tests/test_mainwindow.py @@ -25,8 +25,17 @@ #============================================================================== # Constants #============================================================================== +# Location of this file LOCATION = osp.realpath(osp.join(os.getcwd(), osp.dirname(__file__))) +# Time to wait until the IPython console is ready to receive input +# (in miliseconds) +SHELL_TIMEOUT = 30000 + +# Time to wait for the IPython console to evaluate something (in +# miliseconds) +EVAL_TIMEOUT = 3000 + #============================================================================== # Utility functions @@ -46,7 +55,7 @@ def open_file_in_editor(main_window, fname, directory=None): def reset_run_code(qtbot, shell, code_editor, nsb): """Reset state after a run code test""" shell.execute('%reset -f') - qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=1500) + qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=EVAL_TIMEOUT) code_editor.setFocus() qtbot.keyClick(code_editor, Qt.Key_Home, modifier=Qt.ControlModifier) @@ -70,7 +79,7 @@ def test_run_code(main_window, qtbot): # ---- Setup ---- # Wait until the window is fully up shell = main_window.ipyconsole.get_current_shellwidget() - qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000) + qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT) # Load test file main_window.editor.load(osp.join(LOCATION, 'script.py')) @@ -87,7 +96,7 @@ def test_run_code(main_window, qtbot): qtbot.keyClick(code_editor, Qt.Key_F5) # Wait until all objects have appeared in the variable explorer - qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=1500) + qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=EVAL_TIMEOUT) # Verify result assert shell.get_value('a') == 10 @@ -103,7 +112,7 @@ def test_run_code(main_window, qtbot): qtbot.wait(100) # Wait until all objects have appeared in the variable explorer - qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=1500) + qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=EVAL_TIMEOUT) # Verify result assert shell.get_value('a') == 10 @@ -119,7 +128,7 @@ def test_run_code(main_window, qtbot): qtbot.wait(100) # Wait until all objects have appeared in the variable explorer - qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=1500) + qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=EVAL_TIMEOUT) # Verify result assert shell.get_value('a') == 10 @@ -133,7 +142,7 @@ def test_run_code(main_window, qtbot): qtbot.keyClick(code_editor, Qt.Key_Return, modifier=Qt.ControlModifier) # Wait until the object has appeared in the variable explorer - qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 1, timeout=1500) + qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 1, timeout=EVAL_TIMEOUT) # Verify result assert shell.get_value('a') == 10 @@ -146,7 +155,7 @@ def test_run_code(main_window, qtbot): main_window.close() -@pytest.mark.skipif(os.name == 'nt', reason="It's timing out sometimes on Windows") +@pytest.mark.skipif(os.name == 'nt', reason="It times out sometimes on Windows") def test_open_files_in_new_editor_window(main_window, qtbot): """ This tests that opening files in a new editor window @@ -156,7 +165,7 @@ def test_open_files_in_new_editor_window(main_window, qtbot): """ # Wait until the window is fully up shell = main_window.ipyconsole.get_current_shellwidget() - qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000) + qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT) # Set a timer to manipulate the open dialog while it's running QTimer.singleShot(2000, lambda: open_file_in_editor(main_window, @@ -180,7 +189,7 @@ def test_maximize_minimize_plugins(main_window, qtbot): """Test that the maximize button is working correctly.""" # Wait until the window is fully up shell = main_window.ipyconsole.get_current_shellwidget() - qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000) + qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT) # Set focus to the Editor main_window.editor.get_focus_widget().setFocus() @@ -200,6 +209,7 @@ def test_maximize_minimize_plugins(main_window, qtbot): main_window.close() +@pytest.mark.skipif(os.name == 'nt', reason="It times out sometimes on Windows") def test_issue_4066(main_window, qtbot): """ Test for a segfault when these steps are followed: @@ -211,12 +221,12 @@ def test_issue_4066(main_window, qtbot): """ # Create the object shell = main_window.ipyconsole.get_current_shellwidget() - qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000) + qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT) shell.execute('myobj = [1, 2, 3]') # Open editor associated with that object and get a reference to it nsb = main_window.variableexplorer.get_focus_widget() - qtbot.waitUntil(lambda: nsb.editor.model.rowCount() > 0, timeout=1500) + qtbot.waitUntil(lambda: nsb.editor.model.rowCount() > 0, timeout=EVAL_TIMEOUT) nsb.editor.setFocus() nsb.editor.edit_item() obj_editor_id = list(nsb.editor.delegate._editors.keys())[0] @@ -225,13 +235,14 @@ def test_issue_4066(main_window, qtbot): # Move to the IPython console and delete that object main_window.ipyconsole.get_focus_widget().setFocus() shell.execute('del myobj') - qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=1500) + qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=EVAL_TIMEOUT) # Close editor ok_widget = obj_editor.bbox.button(obj_editor.bbox.Ok) qtbot.mouseClick(ok_widget, Qt.LeftButton) +@pytest.mark.skipif(os.name == 'nt', reason="It times out sometimes on Windows") def test_varexp_edit_inline(main_window, qtbot): """ Test for errors when editing inline values in the Variable Explorer @@ -243,13 +254,13 @@ def test_varexp_edit_inline(main_window, qtbot): """ # Create object shell = main_window.ipyconsole.get_current_shellwidget() - qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000) + qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT) shell.execute('a = 10') # Edit object main_window.variableexplorer.visibility_changed(True) nsb = main_window.variableexplorer.get_focus_widget() - qtbot.waitUntil(lambda: nsb.editor.model.rowCount() > 0, timeout=1500) + qtbot.waitUntil(lambda: nsb.editor.model.rowCount() > 0, timeout=EVAL_TIMEOUT) nsb.editor.setFocus() nsb.editor.edit_item()