From e8d6dd19d45018f0e37352d2ee3011e3416ac384 Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 16 Apr 2022 14:20:47 -0600 Subject: [PATCH 01/27] feat: allow user to pick a different python for running tests --- spyder_unittest/backend/pytestworker.py | 12 +++----- spyder_unittest/backend/runnerbase.py | 2 +- spyder_unittest/widgets/configdialog.py | 39 +++++++++++++++++++++---- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/spyder_unittest/backend/pytestworker.py b/spyder_unittest/backend/pytestworker.py index 7e65023d..faf7bf88 100644 --- a/spyder_unittest/backend/pytestworker.py +++ b/spyder_unittest/backend/pytestworker.py @@ -18,14 +18,10 @@ import pytest # Local imports -from spyder.config.base import get_translation -from spyder_unittest.backend.zmqstream import ZmqStreamWriter - -try: - _ = get_translation('spyder_unittest') -except KeyError: # pragma: no cover - import gettext - _ = gettext.gettext +from zmqstream import ZmqStreamWriter + +import gettext +_ = gettext.gettext class FileStub(): diff --git a/spyder_unittest/backend/runnerbase.py b/spyder_unittest/backend/runnerbase.py index 25e1abc8..04de20d0 100644 --- a/spyder_unittest/backend/runnerbase.py +++ b/spyder_unittest/backend/runnerbase.py @@ -212,7 +212,7 @@ def start(self, config, pythonpath): If process failed to start. """ self.process = self._prepare_process(config, pythonpath) - executable = get_python_executable() + executable = config.pyexec or get_python_executable() p_args = self.create_argument_list() try: os.remove(self.resultfilename) diff --git a/spyder_unittest/widgets/configdialog.py b/spyder_unittest/widgets/configdialog.py index 9ea724dd..787fd6fc 100644 --- a/spyder_unittest/widgets/configdialog.py +++ b/spyder_unittest/widgets/configdialog.py @@ -14,7 +14,7 @@ import os.path as osp # Third party imports -from qtpy.compat import getexistingdirectory +from qtpy.compat import getexistingdirectory, getopenfilename from qtpy.QtCore import Slot from qtpy.QtWidgets import (QApplication, QComboBox, QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QLineEdit, QPushButton, @@ -22,6 +22,7 @@ from spyder.config.base import get_translation from spyder.py3compat import getcwd, to_text_string from spyder.utils import icon_manager as ima +from spyder.utils.misc import getcwd_or_home try: _ = get_translation('spyder_unittest') @@ -29,8 +30,8 @@ import gettext _ = gettext.gettext -Config = namedtuple('Config', ['framework', 'wdir']) -Config.__new__.__defaults__ = (None, '') +Config = namedtuple('Config', ['framework', 'wdir', 'pyexec']) +Config.__new__.__defaults__ = (None, '', None) class ConfigDialog(QDialog): @@ -93,6 +94,20 @@ def __init__(self, frameworks, config, parent=None): layout.addSpacing(20) + pyexec_label = QLabel(_('Use the following Python interpreter:')) + layout.addWidget(pyexec_label) + pyexec_layout = QHBoxLayout() + self.pyexec_lineedit = QLineEdit(self) + pyexec_layout.addWidget(self.pyexec_lineedit) + self.pyexec_button = QPushButton(ima.icon('DirOpenIcon'), '', self) + self.pyexec_button.setToolTip(_("Select interpreter")) + self.pyexec_button.clicked.connect( + lambda: self.select_file(self.pyexec_lineedit)) + pyexec_layout.addWidget(self.pyexec_button) + layout.addLayout(pyexec_layout) + + layout.addSpacing(20) + self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) layout.addWidget(self.buttons) @@ -110,6 +125,7 @@ def __init__(self, frameworks, config, parent=None): if index != -1: self.framework_combobox.setCurrentIndex(index) self.wdir_lineedit.setText(config.wdir) + self.pyexec_lineedit.setText(config.pyexec) @Slot(int) def framework_changed(self, index): @@ -127,6 +143,18 @@ def select_directory(self): if directory: self.wdir_lineedit.setText(directory) + def select_file(self, edit, filters=None): + """Select File""" + basedir = osp.dirname(to_text_string(edit.text())) + if not osp.isdir(basedir): + basedir = getcwd_or_home() + if filters is None: + filters = _("All files (*)") + title = _("Select file") + filename, _selfilter = getopenfilename(self, title, basedir, filters) + if filename: + edit.setText(filename) + def get_config(self): """ Return the test configuration specified by the user. @@ -139,7 +167,8 @@ def get_config(self): framework = self.framework_combobox.currentText() if framework == '': framework = None - return Config(framework=framework, wdir=self.wdir_lineedit.text()) + return Config(framework=framework, wdir=self.wdir_lineedit.text(), + pyexec=self.pyexec_lineedit.text()) def ask_for_config(frameworks, config, parent=None): @@ -158,5 +187,5 @@ def ask_for_config(frameworks, config, parent=None): if __name__ == '__main__': app = QApplication([]) frameworks = ['nose', 'pytest', 'unittest'] - config = Config(framework=None, wdir=getcwd()) + config = Config(framework=None, wdir=getcwd(), pyexec=None) print(ask_for_config(frameworks, config)) From e54857ce2cfa98ad8c12d8b59e4cbdeb947ec1f9 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 17 Apr 2022 14:56:00 -0600 Subject: [PATCH 02/27] feat: validate chosen python executable --- spyder_unittest/widgets/configdialog.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spyder_unittest/widgets/configdialog.py b/spyder_unittest/widgets/configdialog.py index 787fd6fc..e6eaf5c1 100644 --- a/spyder_unittest/widgets/configdialog.py +++ b/spyder_unittest/widgets/configdialog.py @@ -21,7 +21,7 @@ QVBoxLayout) from spyder.config.base import get_translation from spyder.py3compat import getcwd, to_text_string -from spyder.utils import icon_manager as ima +from spyder.utils import icon_manager as ima, programs from spyder.utils.misc import getcwd_or_home try: @@ -102,7 +102,9 @@ def __init__(self, frameworks, config, parent=None): self.pyexec_button = QPushButton(ima.icon('DirOpenIcon'), '', self) self.pyexec_button.setToolTip(_("Select interpreter")) self.pyexec_button.clicked.connect( - lambda: self.select_file(self.pyexec_lineedit)) + lambda: self.select_file(self.pyexec_lineedit, + "Python (python*)" + )) pyexec_layout.addWidget(self.pyexec_button) layout.addLayout(pyexec_layout) @@ -152,7 +154,7 @@ def select_file(self, edit, filters=None): filters = _("All files (*)") title = _("Select file") filename, _selfilter = getopenfilename(self, title, basedir, filters) - if filename: + if filename and programs.is_python_interpreter(filename): edit.setText(filename) def get_config(self): From fa4a74ceb9060951596fab68c77465a89ee4db39 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 20 Apr 2022 08:40:22 -0600 Subject: [PATCH 03/27] fix: try spyder get_translation import, then fall back to gettext --- spyder_unittest/backend/pytestworker.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/spyder_unittest/backend/pytestworker.py b/spyder_unittest/backend/pytestworker.py index faf7bf88..e6ba39cd 100644 --- a/spyder_unittest/backend/pytestworker.py +++ b/spyder_unittest/backend/pytestworker.py @@ -17,12 +17,18 @@ # Third party imports import pytest -# Local imports +# Local imports, needs to not be absolute otherwise it will fail if trying +# to execute in a different env with only spyder-kernel installed from zmqstream import ZmqStreamWriter -import gettext -_ = gettext.gettext - +try: + # if only spyder kernels are installed in the desired env, + # then this import will fail + from spyder.config.base import get_translation + _ = get_translation('spyder_unittest') +except (KeyError, ModuleNotFoundError): # pragma: no cover + import gettext + _ = gettext.gettext class FileStub(): """Stub for ZmqStreamWriter which instead writes to a file.""" From 11529305d6e26e8daf718e61e6f4f4698f384a5f Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 23 Apr 2022 10:30:42 -0600 Subject: [PATCH 04/27] fix: relative import of ZmqStreamWriter --- spyder_unittest/backend/pytestworker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spyder_unittest/backend/pytestworker.py b/spyder_unittest/backend/pytestworker.py index e6ba39cd..ccf13a96 100644 --- a/spyder_unittest/backend/pytestworker.py +++ b/spyder_unittest/backend/pytestworker.py @@ -19,7 +19,7 @@ # Local imports, needs to not be absolute otherwise it will fail if trying # to execute in a different env with only spyder-kernel installed -from zmqstream import ZmqStreamWriter +from .zmqstream import ZmqStreamWriter try: # if only spyder kernels are installed in the desired env, From b060203be14a8dd48fd5541628e7134c68020691 Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 23 Apr 2022 10:44:13 -0600 Subject: [PATCH 05/27] fix: config dialog test fix --- spyder_unittest/widgets/configdialog.py | 5 ++++- spyder_unittest/widgets/tests/test_configdialog.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/spyder_unittest/widgets/configdialog.py b/spyder_unittest/widgets/configdialog.py index e6eaf5c1..18daac79 100644 --- a/spyder_unittest/widgets/configdialog.py +++ b/spyder_unittest/widgets/configdialog.py @@ -169,8 +169,11 @@ def get_config(self): framework = self.framework_combobox.currentText() if framework == '': framework = None + pyexec = self.pyexec_lineedit.text() + if pyexec == '': + pyexec = None return Config(framework=framework, wdir=self.wdir_lineedit.text(), - pyexec=self.pyexec_lineedit.text()) + pyexec=pyexec) def ask_for_config(frameworks, config, parent=None): diff --git a/spyder_unittest/widgets/tests/test_configdialog.py b/spyder_unittest/widgets/tests/test_configdialog.py index 2e1044fa..2a24dc53 100644 --- a/spyder_unittest/widgets/tests/test_configdialog.py +++ b/spyder_unittest/widgets/tests/test_configdialog.py @@ -43,7 +43,7 @@ def is_installed(cls): def default_config(): - return Config(framework=None, wdir=os.getcwd()) + return Config(framework=None, wdir=os.getcwd(), pyexec=None) def test_configdialog_uses_frameworks(qtbot): From 7ae8b3b4a768ed973dfb3714c90c8a8864b75dd6 Mon Sep 17 00:00:00 2001 From: Steve Date: Sat, 23 Apr 2022 10:45:22 -0600 Subject: [PATCH 06/27] fix: more issues with zmq --- spyder_unittest/backend/pytestworker.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/spyder_unittest/backend/pytestworker.py b/spyder_unittest/backend/pytestworker.py index ccf13a96..45d06408 100644 --- a/spyder_unittest/backend/pytestworker.py +++ b/spyder_unittest/backend/pytestworker.py @@ -19,7 +19,12 @@ # Local imports, needs to not be absolute otherwise it will fail if trying # to execute in a different env with only spyder-kernel installed -from .zmqstream import ZmqStreamWriter +try: + # this line is needed for the pytests to succeed + from .zmqstream import ZmqStreamWriter +except: + # this line is needed for the plugin to work + from zmqstream import ZmqStreamWriter try: # if only spyder kernels are installed in the desired env, From af7bb84566d18a97af83f287c694b49aa6d2537c Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 25 Apr 2022 08:55:51 -0600 Subject: [PATCH 07/27] new tests for config dialog --- .../widgets/tests/test_configdialog.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/spyder_unittest/widgets/tests/test_configdialog.py b/spyder_unittest/widgets/tests/test_configdialog.py index 2a24dc53..72251938 100644 --- a/spyder_unittest/widgets/tests/test_configdialog.py +++ b/spyder_unittest/widgets/tests/test_configdialog.py @@ -7,6 +7,7 @@ # Standard library imports import os +import sys # Third party imports from qtpy.QtWidgets import QDialogButtonBox @@ -117,3 +118,22 @@ def test_configdialog_wdir_button(qtbot, monkeypatch): lambda parent, caption, basedir: wdir) configdialog.wdir_button.click() assert configdialog.get_config().wdir == wdir + + +def test_configdialog_pyexec_lineedit(qtbot): + configdialog = ConfigDialog(frameworks, default_config()) + qtbot.addWidget(configdialog) + pyexec = sys.executable + configdialog.pyexec_lineedit.setText(pyexec) + assert configdialog.get_config().pyexec == pyexec + + +def test_configdialog_pyexec_button(qtbot, monkeypatch): + configdialog = ConfigDialog(frameworks, default_config()) + qtbot.addWidget(configdialog) + pyexec = sys.executable + monkeypatch.setattr( + 'spyder_unittest.widgets.configdialog.getopenfilename', + lambda parent, caption, basedir, filters: (pyexec, None)) + configdialog.pyexec_button.click() + assert configdialog.get_config().pyexec == pyexec From 5b58ef619e302fc650ec766116a297d14e09b43d Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 25 Apr 2022 09:11:03 -0600 Subject: [PATCH 08/27] removed text translation code --- spyder_unittest/backend/pytestworker.py | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/spyder_unittest/backend/pytestworker.py b/spyder_unittest/backend/pytestworker.py index 45d06408..ebfb5d86 100644 --- a/spyder_unittest/backend/pytestworker.py +++ b/spyder_unittest/backend/pytestworker.py @@ -26,15 +26,6 @@ # this line is needed for the plugin to work from zmqstream import ZmqStreamWriter -try: - # if only spyder kernels are installed in the desired env, - # then this import will fail - from spyder.config.base import get_translation - _ = get_translation('spyder_unittest') -except (KeyError, ModuleNotFoundError): # pragma: no cover - import gettext - _ = gettext.gettext - class FileStub(): """Stub for ZmqStreamWriter which instead writes to a file.""" @@ -111,8 +102,8 @@ def pytest_runtest_logreport(self, report): self.was_skipped = True if hasattr(report, 'wasxfail'): self.was_xfail = True - self.longrepr.append(report.wasxfail if report.wasxfail else _( - 'WAS EXPECTED TO FAIL')) + self.longrepr.append(report.wasxfail if report.wasxfail else + 'WAS EXPECTED TO FAIL') self.sections = report.sections # already accumulated over phases if report.longrepr: first_msg_idx = len(self.longrepr) @@ -127,7 +118,7 @@ def pytest_runtest_logreport(self, report): if report.outcome == 'failed' and report.when in ( 'setup', 'teardown'): self.longrepr[first_msg_idx] = '{} {}: {}'.format( - _('ERROR at'), report.when, self.longrepr[first_msg_idx]) + 'ERROR at', report.when, self.longrepr[first_msg_idx]) def pytest_runtest_logfinish(self, nodeid, location): """Called by pytest when the entire test is completed.""" From 0411d390bcf6802e359aa29e9d6f0a307c461a69 Mon Sep 17 00:00:00 2001 From: Steve Date: Mon, 25 Apr 2022 15:05:20 -0600 Subject: [PATCH 09/27] fix: store pyexec in config file --- spyder_unittest/unittestplugin.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/spyder_unittest/unittestplugin.py b/spyder_unittest/unittestplugin.py index 0275493b..ed4dc046 100644 --- a/spyder_unittest/unittestplugin.py +++ b/spyder_unittest/unittestplugin.py @@ -38,8 +38,9 @@ class UnitTestPlugin(SpyderDockablePlugin): WIDGET_CLASS = UnitTestWidget CONF_SECTION = NAME - CONF_DEFAULTS = [(CONF_SECTION, {'framework': '', 'wdir': ''})] - CONF_NAMEMAP = {CONF_SECTION: [(CONF_SECTION, ['framework', 'wdir'])]} + CONF_DEFAULTS = [(CONF_SECTION, {'framework': '', 'wdir': '', 'pyexec': ''})] + CONF_NAMEMAP = {CONF_SECTION: [(CONF_SECTION, + ['framework', 'wdir', 'pyexec'])]} CONF_FILE = True CONF_VERSION = '0.1.0' @@ -263,7 +264,8 @@ def load_config(self): new_config = Config( framework=project.get_option('framework', self.CONF_SECTION), - wdir=project.get_option('wdir', self.CONF_SECTION)) + wdir=project.get_option('wdir', self.CONF_SECTION), + pyexec=project.get_option('pyexec', self.CONF_SECTION)) if not widget.config_is_valid(new_config): new_config = None widget.set_config_without_emit(new_config) @@ -283,6 +285,7 @@ def save_config(self, test_config): project.set_option('framework', test_config.framework, self.CONF_SECTION) project.set_option('wdir', test_config.wdir, self.CONF_SECTION) + project.set_option('pyexec', test_config.pyexec, self.CONF_SECTION) def goto_in_editor(self, filename, lineno): """ From c70b410acd5420487e811e196b333bc7ee017f52 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Thu, 28 Apr 2022 19:09:19 +0100 Subject: [PATCH 10/27] Use Python interpreter from Spyder preferences by default The user may override it in the testing configuration. --- spyder_unittest/backend/pytestrunner.py | 4 ++-- spyder_unittest/backend/runnerbase.py | 7 ++++--- .../backend/tests/test_pytestrunner.py | 7 ++++--- .../backend/tests/test_runnerbase.py | 8 ++------ spyder_unittest/unittestplugin.py | 18 ++++++++++++++++++ spyder_unittest/widgets/unittestgui.py | 5 ++++- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/spyder_unittest/backend/pytestrunner.py b/spyder_unittest/backend/pytestrunner.py index dbc45596..59a34837 100644 --- a/spyder_unittest/backend/pytestrunner.py +++ b/spyder_unittest/backend/pytestrunner.py @@ -45,12 +45,12 @@ def create_argument_list(self): pyfile = os.path.join(os.path.dirname(__file__), 'pytestworker.py') return [pyfile, str(self.reader.port)] - def start(self, config, pythonpath): + def start(self, config, executable, pythonpath): """Start process which will run the unit test suite.""" self.config = config self.reader = ZmqStreamReader() self.reader.sig_received.connect(self.process_output) - RunnerBase.start(self, config, pythonpath) + RunnerBase.start(self, config, executable, pythonpath) def process_output(self, output): """ diff --git a/spyder_unittest/backend/runnerbase.py b/spyder_unittest/backend/runnerbase.py index 04de20d0..0c104422 100644 --- a/spyder_unittest/backend/runnerbase.py +++ b/spyder_unittest/backend/runnerbase.py @@ -13,7 +13,6 @@ from qtpy.QtCore import (QObject, QProcess, QProcessEnvironment, QTextCodec, Signal) from spyder.py3compat import to_text_string -from spyder.utils.misc import get_python_executable try: from importlib.util import find_spec as find_spec_or_loader @@ -189,7 +188,7 @@ def _prepare_process(self, config, pythonpath): process.setProcessEnvironment(env) return process - def start(self, config, pythonpath): + def start(self, config, executable, pythonpath): """ Start process which will run the unit test suite. @@ -203,6 +202,8 @@ def start(self, config, pythonpath): ---------- config : TestConfig Unit test configuration. + executable : str + Path to Python executable (may be overridden by `config`) pythonpath : list of str List of directories to be added to the Python path @@ -212,7 +213,7 @@ def start(self, config, pythonpath): If process failed to start. """ self.process = self._prepare_process(config, pythonpath) - executable = config.pyexec or get_python_executable() + executable = config.pyexec or executable p_args = self.create_argument_list() try: os.remove(self.resultfilename) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index 2c063e12..6658a8d8 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -8,10 +8,10 @@ # Standard library imports import os import os.path as osp +import sys # Third party imports import pytest -from qtpy.QtCore import QByteArray # Local imports from spyder_unittest.backend.pytestrunner import (PyTestRunner, @@ -58,12 +58,13 @@ def test_pytestrunner_start(monkeypatch): runner = PyTestRunner(None, 'results') config = Config() - runner.start(config, ['pythondir']) + runner.start(config, sys.executable, ['pythondir']) assert runner.config is config assert runner.reader is mock_reader runner.reader.sig_received.connect.assert_called_once_with( runner.process_output) - MockRunnerBase.start.assert_called_once_with(runner, config, ['pythondir']) + MockRunnerBase.start.assert_called_once_with( + runner, config, sys.executable, ['pythondir']) def test_pytestrunner_process_output_with_collected(qtbot): diff --git a/spyder_unittest/backend/tests/test_runnerbase.py b/spyder_unittest/backend/tests/test_runnerbase.py index 728fe84c..0fc18a40 100644 --- a/spyder_unittest/backend/tests/test_runnerbase.py +++ b/spyder_unittest/backend/tests/test_runnerbase.py @@ -76,17 +76,13 @@ def test_runnerbase_start(monkeypatch): monkeypatch.setattr('spyder_unittest.backend.runnerbase.os.remove', mock_remove) - monkeypatch.setattr( - 'spyder_unittest.backend.runnerbase.get_python_executable', - lambda: 'python') - runner = RunnerBase(None, 'results') runner._prepare_process = lambda c, p: mock_process runner.create_argument_list = lambda: ['arg1', 'arg2'] config = Config('pytest', 'wdir') mock_process.waitForStarted = lambda: False with pytest.raises(RuntimeError): - runner.start(config, ['pythondir']) + runner.start(config, 'python_exec', ['pythondir']) - mock_process.start.assert_called_once_with('python', ['arg1', 'arg2']) + mock_process.start.assert_called_once_with('python_exec', ['arg1', 'arg2']) mock_remove.assert_called_once_with('results') diff --git a/spyder_unittest/unittestplugin.py b/spyder_unittest/unittestplugin.py index ed4dc046..3a70f5de 100644 --- a/spyder_unittest/unittestplugin.py +++ b/spyder_unittest/unittestplugin.py @@ -9,12 +9,14 @@ import os.path as osp # Third party imports +from spyder.api.config.decorators import on_conf_change from spyder.api.plugins import Plugins, SpyderDockablePlugin from spyder.api.plugin_registration.decorators import on_plugin_available from spyder.config.base import get_translation from spyder.config.gui import is_dark_interface from spyder.plugins.mainmenu.api import ApplicationMenus from spyder.py3compat import PY2, getcwd +from spyder.utils.misc import get_python_executable # Local imports from spyder_unittest.widgets.configdialog import Config @@ -184,6 +186,22 @@ def on_working_directory_available(self): self.update_default_wdir) self.update_default_wdir() + @on_conf_change(section='main_interpreter', + option=['default', 'custom_interpreter']) + def on_interpreter_config_change(self, option, value): + """ + Handle changes of interpreter configuration. + + Retrieve the Python interpreter in the Spyder preferences and + communicate this to the unittest widget. + """ + if self.get_conf(section='main_interpreter', option='default'): + executable = get_python_executable() + else: + executable = self.get_conf(section='main_interpreter', + option='custom_interpreter') + self.get_widget().python_executable = executable + # --- UnitTestPlugin methods ---------------------------------------------- def update_pythonpath(self): diff --git a/spyder_unittest/widgets/unittestgui.py b/spyder_unittest/widgets/unittestgui.py index 70f9d3c4..c9c365db 100644 --- a/spyder_unittest/widgets/unittestgui.py +++ b/spyder_unittest/widgets/unittestgui.py @@ -83,6 +83,8 @@ class UnitTestWidget(PluginMainWidget): pre_test_hook : function returning bool or None If set, contains function to run before running tests; abort the test run if hook returns False. + python_executable : str + Path to Python executable for running tests. pythonpath : list of str Directories to be added to the Python path when running tests. testrunner : TestRunner or None @@ -110,6 +112,7 @@ def __init__(self, name, plugin, parent): self.config = None self.pythonpath = None + self.python_executable = sys.executable self.default_wdir = None self.pre_test_hook = None self.testrunner = None @@ -342,7 +345,7 @@ def run_tests(self, config=None): self.testrunner.sig_stop.connect(self.tests_stopped) try: - self.testrunner.start(config, pythonpath) + self.testrunner.start(config, self.python_executable, pythonpath) except RuntimeError: QMessageBox.critical(self, _("Error"), _("Process failed to start")) From 6dda2b8dda2b49d34d7e56b67b16cafeafda9213 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 1 May 2022 16:41:18 -0600 Subject: [PATCH 11/27] fix: store empty string in project config if no pyexec chosen When using projects and no pyexec is set, then the value None is store in the project config file. When opened, this is interpreted as a string "None" rather than the python None Another option could be to change the default value of pyexec to '' instead of None --- spyder_unittest/unittestplugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spyder_unittest/unittestplugin.py b/spyder_unittest/unittestplugin.py index 3a70f5de..e05ef611 100644 --- a/spyder_unittest/unittestplugin.py +++ b/spyder_unittest/unittestplugin.py @@ -303,7 +303,8 @@ def save_config(self, test_config): project.set_option('framework', test_config.framework, self.CONF_SECTION) project.set_option('wdir', test_config.wdir, self.CONF_SECTION) - project.set_option('pyexec', test_config.pyexec, self.CONF_SECTION) + project.set_option('pyexec', test_config.pyexec or '', + self.CONF_SECTION) def goto_in_editor(self, filename, lineno): """ From 97a22f587f4bf0f7195d6e979e8295c681fb9248 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 15 May 2022 08:03:39 -0600 Subject: [PATCH 12/27] moved on_interpreter_config_change to UnitTestWidget --- spyder_unittest/unittestplugin.py | 18 ------------------ spyder_unittest/widgets/unittestgui.py | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/spyder_unittest/unittestplugin.py b/spyder_unittest/unittestplugin.py index e05ef611..c0e813e1 100644 --- a/spyder_unittest/unittestplugin.py +++ b/spyder_unittest/unittestplugin.py @@ -9,14 +9,12 @@ import os.path as osp # Third party imports -from spyder.api.config.decorators import on_conf_change from spyder.api.plugins import Plugins, SpyderDockablePlugin from spyder.api.plugin_registration.decorators import on_plugin_available from spyder.config.base import get_translation from spyder.config.gui import is_dark_interface from spyder.plugins.mainmenu.api import ApplicationMenus from spyder.py3compat import PY2, getcwd -from spyder.utils.misc import get_python_executable # Local imports from spyder_unittest.widgets.configdialog import Config @@ -186,22 +184,6 @@ def on_working_directory_available(self): self.update_default_wdir) self.update_default_wdir() - @on_conf_change(section='main_interpreter', - option=['default', 'custom_interpreter']) - def on_interpreter_config_change(self, option, value): - """ - Handle changes of interpreter configuration. - - Retrieve the Python interpreter in the Spyder preferences and - communicate this to the unittest widget. - """ - if self.get_conf(section='main_interpreter', option='default'): - executable = get_python_executable() - else: - executable = self.get_conf(section='main_interpreter', - option='custom_interpreter') - self.get_widget().python_executable = executable - # --- UnitTestPlugin methods ---------------------------------------------- def update_pythonpath(self): diff --git a/spyder_unittest/widgets/unittestgui.py b/spyder_unittest/widgets/unittestgui.py index c9c365db..23387800 100644 --- a/spyder_unittest/widgets/unittestgui.py +++ b/spyder_unittest/widgets/unittestgui.py @@ -15,11 +15,13 @@ # Third party imports from qtpy.QtCore import Signal from qtpy.QtWidgets import QLabel, QMessageBox, QVBoxLayout +from spyder.api.config.decorators import on_conf_change from spyder.api.widgets.main_widget import PluginMainWidget from spyder.config.base import get_conf_path, get_translation from spyder.utils import icon_manager as ima from spyder.plugins.variableexplorer.widgets.texteditor import TextEditor from spyder.py3compat import PY3 +from spyder.utils.misc import get_python_executable # Local imports from spyder_unittest.backend.frameworkregistry import FrameworkRegistry @@ -225,6 +227,22 @@ def get_focus_widget(self): """ return self.testdataview + @on_conf_change(section='main_interpreter', + option=['default', 'custom_interpreter']) + def on_interpreter_config_change(self, option, value): + """ + Handle changes of interpreter configuration. + + Retrieve the Python interpreter in the Spyder preferences and + communicate this to the unittest widget. + """ + if self.get_conf(section='main_interpreter', option='default'): + executable = get_python_executable() + else: + executable = self.get_conf(section='main_interpreter', + option='custom_interpreter') + self.python_executable = executable + # --- UnitTestWidget methods ---------------------------------------------- @property From 466798dc6414058e001418441b2b5b66d8c963a3 Mon Sep 17 00:00:00 2001 From: Steve Date: Sun, 15 May 2022 08:20:54 -0600 Subject: [PATCH 13/27] removed manual pyexec config option --- spyder_unittest/backend/runnerbase.py | 3 +- spyder_unittest/unittestplugin.py | 10 ++-- spyder_unittest/widgets/configdialog.py | 46 +++---------------- .../widgets/tests/test_configdialog.py | 22 +-------- 4 files changed, 11 insertions(+), 70 deletions(-) diff --git a/spyder_unittest/backend/runnerbase.py b/spyder_unittest/backend/runnerbase.py index 0c104422..22fff189 100644 --- a/spyder_unittest/backend/runnerbase.py +++ b/spyder_unittest/backend/runnerbase.py @@ -203,7 +203,7 @@ def start(self, config, executable, pythonpath): config : TestConfig Unit test configuration. executable : str - Path to Python executable (may be overridden by `config`) + Path to Python executable pythonpath : list of str List of directories to be added to the Python path @@ -213,7 +213,6 @@ def start(self, config, executable, pythonpath): If process failed to start. """ self.process = self._prepare_process(config, pythonpath) - executable = config.pyexec or executable p_args = self.create_argument_list() try: os.remove(self.resultfilename) diff --git a/spyder_unittest/unittestplugin.py b/spyder_unittest/unittestplugin.py index c0e813e1..0275493b 100644 --- a/spyder_unittest/unittestplugin.py +++ b/spyder_unittest/unittestplugin.py @@ -38,9 +38,8 @@ class UnitTestPlugin(SpyderDockablePlugin): WIDGET_CLASS = UnitTestWidget CONF_SECTION = NAME - CONF_DEFAULTS = [(CONF_SECTION, {'framework': '', 'wdir': '', 'pyexec': ''})] - CONF_NAMEMAP = {CONF_SECTION: [(CONF_SECTION, - ['framework', 'wdir', 'pyexec'])]} + CONF_DEFAULTS = [(CONF_SECTION, {'framework': '', 'wdir': ''})] + CONF_NAMEMAP = {CONF_SECTION: [(CONF_SECTION, ['framework', 'wdir'])]} CONF_FILE = True CONF_VERSION = '0.1.0' @@ -264,8 +263,7 @@ def load_config(self): new_config = Config( framework=project.get_option('framework', self.CONF_SECTION), - wdir=project.get_option('wdir', self.CONF_SECTION), - pyexec=project.get_option('pyexec', self.CONF_SECTION)) + wdir=project.get_option('wdir', self.CONF_SECTION)) if not widget.config_is_valid(new_config): new_config = None widget.set_config_without_emit(new_config) @@ -285,8 +283,6 @@ def save_config(self, test_config): project.set_option('framework', test_config.framework, self.CONF_SECTION) project.set_option('wdir', test_config.wdir, self.CONF_SECTION) - project.set_option('pyexec', test_config.pyexec or '', - self.CONF_SECTION) def goto_in_editor(self, filename, lineno): """ diff --git a/spyder_unittest/widgets/configdialog.py b/spyder_unittest/widgets/configdialog.py index 18daac79..9ea724dd 100644 --- a/spyder_unittest/widgets/configdialog.py +++ b/spyder_unittest/widgets/configdialog.py @@ -14,15 +14,14 @@ import os.path as osp # Third party imports -from qtpy.compat import getexistingdirectory, getopenfilename +from qtpy.compat import getexistingdirectory from qtpy.QtCore import Slot from qtpy.QtWidgets import (QApplication, QComboBox, QDialog, QDialogButtonBox, QHBoxLayout, QLabel, QLineEdit, QPushButton, QVBoxLayout) from spyder.config.base import get_translation from spyder.py3compat import getcwd, to_text_string -from spyder.utils import icon_manager as ima, programs -from spyder.utils.misc import getcwd_or_home +from spyder.utils import icon_manager as ima try: _ = get_translation('spyder_unittest') @@ -30,8 +29,8 @@ import gettext _ = gettext.gettext -Config = namedtuple('Config', ['framework', 'wdir', 'pyexec']) -Config.__new__.__defaults__ = (None, '', None) +Config = namedtuple('Config', ['framework', 'wdir']) +Config.__new__.__defaults__ = (None, '') class ConfigDialog(QDialog): @@ -94,22 +93,6 @@ def __init__(self, frameworks, config, parent=None): layout.addSpacing(20) - pyexec_label = QLabel(_('Use the following Python interpreter:')) - layout.addWidget(pyexec_label) - pyexec_layout = QHBoxLayout() - self.pyexec_lineedit = QLineEdit(self) - pyexec_layout.addWidget(self.pyexec_lineedit) - self.pyexec_button = QPushButton(ima.icon('DirOpenIcon'), '', self) - self.pyexec_button.setToolTip(_("Select interpreter")) - self.pyexec_button.clicked.connect( - lambda: self.select_file(self.pyexec_lineedit, - "Python (python*)" - )) - pyexec_layout.addWidget(self.pyexec_button) - layout.addLayout(pyexec_layout) - - layout.addSpacing(20) - self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) layout.addWidget(self.buttons) @@ -127,7 +110,6 @@ def __init__(self, frameworks, config, parent=None): if index != -1: self.framework_combobox.setCurrentIndex(index) self.wdir_lineedit.setText(config.wdir) - self.pyexec_lineedit.setText(config.pyexec) @Slot(int) def framework_changed(self, index): @@ -145,18 +127,6 @@ def select_directory(self): if directory: self.wdir_lineedit.setText(directory) - def select_file(self, edit, filters=None): - """Select File""" - basedir = osp.dirname(to_text_string(edit.text())) - if not osp.isdir(basedir): - basedir = getcwd_or_home() - if filters is None: - filters = _("All files (*)") - title = _("Select file") - filename, _selfilter = getopenfilename(self, title, basedir, filters) - if filename and programs.is_python_interpreter(filename): - edit.setText(filename) - def get_config(self): """ Return the test configuration specified by the user. @@ -169,11 +139,7 @@ def get_config(self): framework = self.framework_combobox.currentText() if framework == '': framework = None - pyexec = self.pyexec_lineedit.text() - if pyexec == '': - pyexec = None - return Config(framework=framework, wdir=self.wdir_lineedit.text(), - pyexec=pyexec) + return Config(framework=framework, wdir=self.wdir_lineedit.text()) def ask_for_config(frameworks, config, parent=None): @@ -192,5 +158,5 @@ def ask_for_config(frameworks, config, parent=None): if __name__ == '__main__': app = QApplication([]) frameworks = ['nose', 'pytest', 'unittest'] - config = Config(framework=None, wdir=getcwd(), pyexec=None) + config = Config(framework=None, wdir=getcwd()) print(ask_for_config(frameworks, config)) diff --git a/spyder_unittest/widgets/tests/test_configdialog.py b/spyder_unittest/widgets/tests/test_configdialog.py index 72251938..2e1044fa 100644 --- a/spyder_unittest/widgets/tests/test_configdialog.py +++ b/spyder_unittest/widgets/tests/test_configdialog.py @@ -7,7 +7,6 @@ # Standard library imports import os -import sys # Third party imports from qtpy.QtWidgets import QDialogButtonBox @@ -44,7 +43,7 @@ def is_installed(cls): def default_config(): - return Config(framework=None, wdir=os.getcwd(), pyexec=None) + return Config(framework=None, wdir=os.getcwd()) def test_configdialog_uses_frameworks(qtbot): @@ -118,22 +117,3 @@ def test_configdialog_wdir_button(qtbot, monkeypatch): lambda parent, caption, basedir: wdir) configdialog.wdir_button.click() assert configdialog.get_config().wdir == wdir - - -def test_configdialog_pyexec_lineedit(qtbot): - configdialog = ConfigDialog(frameworks, default_config()) - qtbot.addWidget(configdialog) - pyexec = sys.executable - configdialog.pyexec_lineedit.setText(pyexec) - assert configdialog.get_config().pyexec == pyexec - - -def test_configdialog_pyexec_button(qtbot, monkeypatch): - configdialog = ConfigDialog(frameworks, default_config()) - qtbot.addWidget(configdialog) - pyexec = sys.executable - monkeypatch.setattr( - 'spyder_unittest.widgets.configdialog.getopenfilename', - lambda parent, caption, basedir, filters: (pyexec, None)) - configdialog.pyexec_button.click() - assert configdialog.get_config().pyexec == pyexec From 85097374714619778731a7c33ca0404dcbe1cbc4 Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 31 May 2022 15:51:59 -0600 Subject: [PATCH 14/27] upgraded to spyder 5.3.1 for get_conf --- requirements/conda.txt | 2 +- setup.py | 2 +- spyder_unittest/widgets/unittestgui.py | 25 ++----------------------- 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/requirements/conda.txt b/requirements/conda.txt index 94d0ae01..cb8205f8 100644 --- a/requirements/conda.txt +++ b/requirements/conda.txt @@ -1,2 +1,2 @@ lxml -spyder>=5.2,<6 +spyder>=5.3.1,<6 diff --git a/setup.py b/setup.py index 3a87b1e9..8931c86c 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,7 @@ def get_package_data(name, extlist): # Requirements -REQUIREMENTS = ['lxml', 'spyder>=5.2,<6', 'pyzmq'] +REQUIREMENTS = ['lxml', 'spyder>=5.3.1,<6', 'pyzmq'] EXTLIST = ['.jpg', '.png', '.json', '.mo', '.ini'] LIBNAME = 'spyder_unittest' diff --git a/spyder_unittest/widgets/unittestgui.py b/spyder_unittest/widgets/unittestgui.py index 23387800..28614666 100644 --- a/spyder_unittest/widgets/unittestgui.py +++ b/spyder_unittest/widgets/unittestgui.py @@ -15,13 +15,11 @@ # Third party imports from qtpy.QtCore import Signal from qtpy.QtWidgets import QLabel, QMessageBox, QVBoxLayout -from spyder.api.config.decorators import on_conf_change from spyder.api.widgets.main_widget import PluginMainWidget from spyder.config.base import get_conf_path, get_translation from spyder.utils import icon_manager as ima from spyder.plugins.variableexplorer.widgets.texteditor import TextEditor from spyder.py3compat import PY3 -from spyder.utils.misc import get_python_executable # Local imports from spyder_unittest.backend.frameworkregistry import FrameworkRegistry @@ -85,8 +83,6 @@ class UnitTestWidget(PluginMainWidget): pre_test_hook : function returning bool or None If set, contains function to run before running tests; abort the test run if hook returns False. - python_executable : str - Path to Python executable for running tests. pythonpath : list of str Directories to be added to the Python path when running tests. testrunner : TestRunner or None @@ -114,7 +110,6 @@ def __init__(self, name, plugin, parent): self.config = None self.pythonpath = None - self.python_executable = sys.executable self.default_wdir = None self.pre_test_hook = None self.testrunner = None @@ -227,22 +222,6 @@ def get_focus_widget(self): """ return self.testdataview - @on_conf_change(section='main_interpreter', - option=['default', 'custom_interpreter']) - def on_interpreter_config_change(self, option, value): - """ - Handle changes of interpreter configuration. - - Retrieve the Python interpreter in the Spyder preferences and - communicate this to the unittest widget. - """ - if self.get_conf(section='main_interpreter', option='default'): - executable = get_python_executable() - else: - executable = self.get_conf(section='main_interpreter', - option='custom_interpreter') - self.python_executable = executable - # --- UnitTestWidget methods ---------------------------------------------- @property @@ -361,9 +340,9 @@ def run_tests(self, config=None): self.testrunner.sig_starttest.connect(self.tests_started) self.testrunner.sig_testresult.connect(self.tests_yield_result) self.testrunner.sig_stop.connect(self.tests_stopped) - + executable = self.get_conf('executable', section='main_interpreter') try: - self.testrunner.start(config, self.python_executable, pythonpath) + self.testrunner.start(config, executable, pythonpath) except RuntimeError: QMessageBox.critical(self, _("Error"), _("Process failed to start")) From e2ab7a2cfbf81860196a8c0e9fa146d7c5590210 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 1 Jun 2022 09:22:02 -0600 Subject: [PATCH 15/27] fixed testing issues --- spyder_unittest/backend/tests/test_pytestrunner.py | 1 + spyder_unittest/widgets/tests/test_unittestgui.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index 6658a8d8..f905a009 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -67,6 +67,7 @@ def test_pytestrunner_start(monkeypatch): runner, config, sys.executable, ['pythondir']) +@pytest.mark.skip("segfaulting for some reason") def test_pytestrunner_process_output_with_collected(qtbot): runner = PyTestRunner(None) output = [{'event': 'collected', 'nodeid': 'spam.py::ham'}, diff --git a/spyder_unittest/widgets/tests/test_unittestgui.py b/spyder_unittest/widgets/tests/test_unittestgui.py index 292ba68d..764d2a39 100644 --- a/spyder_unittest/widgets/tests/test_unittestgui.py +++ b/spyder_unittest/widgets/tests/test_unittestgui.py @@ -7,6 +7,7 @@ # Standard library imports import os +import sys # Third party imports from qtpy.QtCore import Qt, QProcess @@ -26,6 +27,10 @@ @pytest.fixture def widget(qtbot): unittest_widget = UnitTestWidget('testwidget', None, None) + unittest_widget.get_conf( + 'executable', + section='main_interpreter', + default=sys.executable) unittest_widget.setup() qtbot.addWidget(unittest_widget) return unittest_widget From d349c7ce510dc997b6926016b71d0f855d05bafc Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 1 Jun 2022 09:34:54 -0600 Subject: [PATCH 16/27] another test skipped --- spyder_unittest/backend/tests/test_pytestrunner.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index f905a009..efb399de 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -77,6 +77,8 @@ def test_pytestrunner_process_output_with_collected(qtbot): expected = ['spam.ham', 'eggs.bacon'] assert blocker.args == [expected] + +@pytest.mark.skip("segfaulting for some reason") def test_pytestrunner_process_output_with_collecterror(qtbot): runner = PyTestRunner(None) output = [{ From 9ba80c6dc64fbd5c73b5c8d2ae1eed7530f66a51 Mon Sep 17 00:00:00 2001 From: Steve Date: Wed, 1 Jun 2022 16:55:50 -0600 Subject: [PATCH 17/27] skipping another test --- spyder_unittest/backend/tests/test_pytestrunner.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index efb399de..deededb0 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -91,6 +91,8 @@ def test_pytestrunner_process_output_with_collecterror(qtbot): expected = [('ham.spam', 'msg')] assert blocker.args == [expected] + +@pytest.mark.skip("segfaulting for some reason") def test_pytestrunner_process_output_with_starttest(qtbot): runner = PyTestRunner(None) output = [{'event': 'starttest', 'nodeid': 'ham/spam.py::ham'}, From c07ea16a69faa0b1be59feeaa82264a3722945a8 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 07:06:43 -0600 Subject: [PATCH 18/27] attempt newer pytest-qt for testing --- requirements/tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/tests.txt b/requirements/tests.txt index 92191942..0074d60f 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -4,4 +4,4 @@ nose pytest pytest-cov pytest-mock -pytest-qt +pytest-qt>=4 From 01b73c9669f8916d451a164929e9effa139b21c6 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 09:47:53 -0600 Subject: [PATCH 19/27] skipping all qtbot tests --- spyder_unittest/backend/tests/test_pytestrunner.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index deededb0..63b20a58 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -103,6 +103,7 @@ def test_pytestrunner_process_output_with_starttest(qtbot): assert blocker.args == [expected] +@pytest.mark.skip("segfaulting for some reason") @pytest.mark.parametrize('output,results', [ ('== 1 passed in 0.10s ==', None), ('== no tests ran 0.01s ==', []) @@ -129,6 +130,8 @@ def standard_logreport_output(): 'duration': 42 } + +@pytest.mark.skip("segfaulting for some reason") def test_pytestrunner_process_output_with_logreport_passed(qtbot): runner = PyTestRunner(None) runner.rootdir = 'ham' From c2bbe2b67b6cc47794bb5de8eba0c7af13d98f60 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 11:21:09 -0600 Subject: [PATCH 20/27] attempt to fix segfaults on linux tests --- .github/workflows/linux-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linux-tests.yml b/.github/workflows/linux-tests.yml index f2acae52..05b9c6e4 100644 --- a/.github/workflows/linux-tests.yml +++ b/.github/workflows/linux-tests.yml @@ -25,8 +25,8 @@ jobs: uses: actions/checkout@v2 - name: Install System Packages run: | - sudo apt-get update - sudo apt-get install libegl1-mesa + sudo apt-get update --fix-missing + sudo apt-get install -qq pyqt5-dev-tools libxcb-xinerama0 xterm --fix-missing - name: Install Conda uses: conda-incubator/setup-miniconda@v2 with: From c7abea1a73f2509d7e35008ade5fcaa3d47d7d82 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 11:42:11 -0600 Subject: [PATCH 21/27] Revert "skipping all qtbot tests" This reverts commit 01b73c9669f8916d451a164929e9effa139b21c6. --- spyder_unittest/backend/tests/test_pytestrunner.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index 63b20a58..deededb0 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -103,7 +103,6 @@ def test_pytestrunner_process_output_with_starttest(qtbot): assert blocker.args == [expected] -@pytest.mark.skip("segfaulting for some reason") @pytest.mark.parametrize('output,results', [ ('== 1 passed in 0.10s ==', None), ('== no tests ran 0.01s ==', []) @@ -130,8 +129,6 @@ def standard_logreport_output(): 'duration': 42 } - -@pytest.mark.skip("segfaulting for some reason") def test_pytestrunner_process_output_with_logreport_passed(qtbot): runner = PyTestRunner(None) runner.rootdir = 'ham' From 323617b5874b9917281b69c93f93d5ffe72cc8d3 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 11:42:18 -0600 Subject: [PATCH 22/27] Revert "attempt newer pytest-qt for testing" This reverts commit c07ea16a69faa0b1be59feeaa82264a3722945a8. --- requirements/tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/tests.txt b/requirements/tests.txt index 0074d60f..92191942 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -4,4 +4,4 @@ nose pytest pytest-cov pytest-mock -pytest-qt>=4 +pytest-qt From 9b05ea6ca9a2ad171a419e1eda958a4dd848be79 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 11:42:19 -0600 Subject: [PATCH 23/27] Revert "skipping another test" This reverts commit 9ba80c6dc64fbd5c73b5c8d2ae1eed7530f66a51. --- spyder_unittest/backend/tests/test_pytestrunner.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index deededb0..efb399de 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -91,8 +91,6 @@ def test_pytestrunner_process_output_with_collecterror(qtbot): expected = [('ham.spam', 'msg')] assert blocker.args == [expected] - -@pytest.mark.skip("segfaulting for some reason") def test_pytestrunner_process_output_with_starttest(qtbot): runner = PyTestRunner(None) output = [{'event': 'starttest', 'nodeid': 'ham/spam.py::ham'}, From f9ea870e6d477aacb1c8087ea3ccb30491528891 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 11:42:19 -0600 Subject: [PATCH 24/27] Revert "another test skipped" This reverts commit d349c7ce510dc997b6926016b71d0f855d05bafc. --- spyder_unittest/backend/tests/test_pytestrunner.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index efb399de..f905a009 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -77,8 +77,6 @@ def test_pytestrunner_process_output_with_collected(qtbot): expected = ['spam.ham', 'eggs.bacon'] assert blocker.args == [expected] - -@pytest.mark.skip("segfaulting for some reason") def test_pytestrunner_process_output_with_collecterror(qtbot): runner = PyTestRunner(None) output = [{ From c4bb6820a7587271a78d96756b733d05f3502c24 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 11:45:30 -0600 Subject: [PATCH 25/27] fixed segfaults, no longer need to skip qtbot tests --- spyder_unittest/backend/tests/test_pytestrunner.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spyder_unittest/backend/tests/test_pytestrunner.py b/spyder_unittest/backend/tests/test_pytestrunner.py index f905a009..e3e9191f 100644 --- a/spyder_unittest/backend/tests/test_pytestrunner.py +++ b/spyder_unittest/backend/tests/test_pytestrunner.py @@ -67,7 +67,6 @@ def test_pytestrunner_start(monkeypatch): runner, config, sys.executable, ['pythondir']) -@pytest.mark.skip("segfaulting for some reason") def test_pytestrunner_process_output_with_collected(qtbot): runner = PyTestRunner(None) output = [{'event': 'collected', 'nodeid': 'spam.py::ham'}, @@ -77,6 +76,7 @@ def test_pytestrunner_process_output_with_collected(qtbot): expected = ['spam.ham', 'eggs.bacon'] assert blocker.args == [expected] + def test_pytestrunner_process_output_with_collecterror(qtbot): runner = PyTestRunner(None) output = [{ @@ -89,6 +89,7 @@ def test_pytestrunner_process_output_with_collecterror(qtbot): expected = [('ham.spam', 'msg')] assert blocker.args == [expected] + def test_pytestrunner_process_output_with_starttest(qtbot): runner = PyTestRunner(None) output = [{'event': 'starttest', 'nodeid': 'ham/spam.py::ham'}, From c3102c19bd3a2e77086c8aa4abbfe61acb0f5df4 Mon Sep 17 00:00:00 2001 From: Steve Date: Thu, 2 Jun 2022 11:46:37 -0600 Subject: [PATCH 26/27] bumped pytest requirements to version 5 --- requirements/tests.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements/tests.txt b/requirements/tests.txt index 92191942..4a80c451 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -1,7 +1,7 @@ codecov flaky nose -pytest +pytest>=5 pytest-cov pytest-mock pytest-qt From 6642de05caec95574311b4e70915511e47e990ac Mon Sep 17 00:00:00 2001 From: Steve Date: Tue, 7 Jun 2022 08:51:22 -0600 Subject: [PATCH 27/27] fixed some comments --- spyder_unittest/backend/pytestworker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spyder_unittest/backend/pytestworker.py b/spyder_unittest/backend/pytestworker.py index ebfb5d86..ea74ec9b 100644 --- a/spyder_unittest/backend/pytestworker.py +++ b/spyder_unittest/backend/pytestworker.py @@ -17,10 +17,10 @@ # Third party imports import pytest -# Local imports, needs to not be absolute otherwise it will fail if trying +# Local imports, needs to be relative otherwise it will fail if trying # to execute in a different env with only spyder-kernel installed try: - # this line is needed for the pytests to succeed + # this line is needed for the tests to succeed from .zmqstream import ZmqStreamWriter except: # this line is needed for the plugin to work