From 365e2676fba7a75aa398378edef580216efd5a36 Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Sat, 19 Sep 2020 13:06:58 +0200 Subject: [PATCH] Add test for the main error handler --- .github/workflows/pytest_cov.yml | 6 ++-- .gitignore | 1 + nw/error.py | 5 ++- nw/guimain.py | 3 ++ pytest.ini | 1 + tests/nwtools.py | 1 + tests/test_error.py | 58 ++++++++++++++++++++++++++++++++ 7 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 tests/test_error.py diff --git a/.github/workflows/pytest_cov.yml b/.github/workflows/pytest_cov.yml index 45c51c0d..fab3162f 100644 --- a/.github/workflows/pytest_cov.yml +++ b/.github/workflows/pytest_cov.yml @@ -26,12 +26,13 @@ jobs: pip install --upgrade pip pip install -r requirements.txt pip install PyVirtualDisplay + pip install pytest-timeout pip install pytest-cov pip install pytest-xvfb pip install pytest-qt pip install codecov - name: Run Tests - run: xvfb-run pytest -v --cov=nw + run: xvfb-run pytest -v --cov=nw --timeout=90 - name: Upload to Codecov uses: codecov/codecov-action@v1 @@ -58,7 +59,8 @@ jobs: pip install --upgrade pip pip install -r requirements.txt pip install PyVirtualDisplay + pip install pytest-timeout pip install pytest-xvfb pip install pytest-qt - name: Run Tests - run: xvfb-run pytest -v + run: xvfb-run pytest -v --timeout=90 diff --git a/.gitignore b/.gitignore index a515c603..fdfe7e87 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ __pycache__ # PyTest /prof/ +/htmlcov/ /tests/temp /tests/lipsum/cache /tests/lipsum/meta diff --git a/nw/error.py b/nw/error.py index 7788508f..8ee03ced 100644 --- a/nw/error.py +++ b/nw/error.py @@ -35,6 +35,7 @@ class NWErrorMessage(QDialog): def __init__(self, parent): QDialog.__init__(self, parent=parent) + self.setObjectName("NWErrorMessage") # Widgets self.msgIcon = QLabel() @@ -146,9 +147,6 @@ def exceptionHandler(exType, exValue, exTrace): logger.critical("%s: %s" % (exType.__name__, str(exValue))) print_tb(exTrace) - if not CONFIG.showGUI: - return - try: nwGUI = None for qWin in qApp.topLevelWidgets(): @@ -161,6 +159,7 @@ def exceptionHandler(exType, exValue, exTrace): return errMsg = NWErrorMessage(nwGUI) + nwGUI.activeDialog = errMsg errMsg.setMessage(exType, exValue, exTrace) errMsg.exec_() diff --git a/nw/guimain.py b/nw/guimain.py index de340304..7c54f048 100644 --- a/nw/guimain.py +++ b/nw/guimain.py @@ -74,6 +74,9 @@ class GuiMain(QMainWindow): self.mainConf.verPyString, self.mainConf.verPyHexVal) ) + # Debug Tools + self.activeDialog = None + # Core Classes and settings self.theTheme = GuiTheme(self) self.theProject = NWProject(self) diff --git a/pytest.ini b/pytest.ini index f266d081..cf748fc2 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,7 @@ [pytest] markers = project: Project classes tests + error: Thest various error handling scenarios core: Core functionality tests gui: Qt5 GUI tests serial diff --git a/tests/nwtools.py b/tests/nwtools.py index a92047ca..0a9516aa 100644 --- a/tests/nwtools.py +++ b/tests/nwtools.py @@ -67,3 +67,4 @@ def getGuiItem(theName): for qWidget in qApp.topLevelWidgets(): if qWidget.objectName() == theName: return qWidget + return None diff --git a/tests/test_error.py b/tests/test_error.py new file mode 100644 index 00000000..2306d72a --- /dev/null +++ b/tests/test_error.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +"""novelWriter Error Tester +""" + +import nw +import sys +import pytest + +from nwtools import getGuiItem + +from PyQt5.QtCore import Qt, QTimer +from PyQt5.QtWidgets import qApp, QDialogButtonBox + +from nw.error import NWErrorMessage, exceptionHandler + +@pytest.mark.error +def testErrorDialog(qtbot, nwFuncTemp, nwTemp): + nwGUI = nw.main(["--testmode", "--config=%s" % nwFuncTemp, "--data=%s" % nwTemp]) + qtbot.addWidget(nwGUI) + nwGUI.show() + qtbot.waitForWindowShown(nwGUI) + + nwErr = NWErrorMessage(nwGUI) + nwErr.show() + + # Invalid Error + nwErr.setMessage(Exception, "Faulty Error", 123) + assert nwErr.msgBody.toPlainText() == "Failed to generate error report ..." + + # Valid Error + nwErr.setMessage(Exception, "First Error", sys.last_traceback) + theMessage = nwErr.msgBody.toPlainText() + assert theMessage + assert "First Error" in theMessage + assert "Exception" in theMessage + nwErr._doClose() + nwErr.close() + del nwErr + + # Exception Handler + def handleDialog(): + while not isinstance(nwGUI.activeDialog, NWErrorMessage): + qApp.processEvents() + + nwErr = nwGUI.activeDialog + theMessage = nwErr.msgBody.toPlainText() + assert theMessage + assert "Second Error" in theMessage + assert "Exception" in theMessage + btnClose = nwErr.btnBox.button(QDialogButtonBox.Close) + qtbot.mouseClick(btnClose, Qt.LeftButton, delay=1) + + QTimer.singleShot(0, handleDialog) + exceptionHandler(Exception, "Second Error", sys.last_traceback) + + nwGUI.closeMain() + + # qtbot.stopForInteraction()