2

I want to test a module in my project, but I have a some problem with it. I don't know how I can check the correct opening of the window after the button click.

I have the windows SelectAddingBookTypeWindow and AddSchoolBookWindow. I want to check that AddSchoolBookWindow will open after I have clicked on the button called selectBtn.

My current test (I have a problem with the last string because I don't know which method I must use):

@pytest.fixture
def open_window(qtbot):
    def _press_button(window):
        widget = window()
        qtbot.addWidget(widget)
        widget.show()
        qtbot.wait_for_window_shown(widget)
        sleep(3)
        return widget
    return _press_button


class TestSelectAddingBookTypeWindow:
    def test_select_schoolbook(self, open_window, qtbot):
        widget = open_window(SelectAddingBookTypeWindow)
        qtbot.mouseClick(widget.schoolbookSelector, QtCore.Qt.LeftButton)
        qtbot.mouseClick(widget.selectBtn, QtCore.Qt.LeftButton)
        assert widget.close()
        assert AddSchoolBookWindow.isActiveWindow()

My classes: A. SelectAddingBookTypeWindow

class SelectBookTypeWindow(QDialog, Ui_selectBookTypeWindow):
    @logger.catch
    def __init__(self, widget1, widget2):
        super().__init__()
        self.setupUi(self)
        self.selectBtn.clicked.connect(lambda x: self.open_new_window(widget1, widget2))

    @logger.catch
    def open_new_window(self, schoolbook_widget, fictionbook_widget):
        if self.schoolbookSelector.isChecked():
            widget = schoolbook_widget()
        elif self.fictionbookSelector.isChecked():
            widget = fictionbook_widget()
        widget.show()
        self.close()


class SelectAddingBookTypeWindow(SelectBookTypeWindow):
    @logger.catch
    def __init__(self):
        super().__init__(AddSchoolBookWindow, AddFictionBookWindow)

B. AddSchoolBookWindow

class AddSchoolBookWindow(QDialog, Ui_AddSchoolbookWindow):
    @logger.catch
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.widgets = [
            self.schoolbookAuthor, self.schoolbookTitle, self.schoolbookPublishHouse,
            self.schoolbookPublishYear, self.schoolbookInvoiceNum, self.schoolbookInvoiceDate, self.schoolbookClass,
            self.schoolbookCount, self.schoolbookPrice
        ]
        self.schoolbookSaveBtn.clicked.connect(lambda _: self.save_book())
        self.schoolbookClearBtn.clicked.connect(lambda _: Utils.clear_fields(self.widgets, self.schoolbookInvoiceDate))
        self.schoolbookCancelBtn.clicked.connect(lambda _: self.close())

    @logger.catch
    def save_book(self):
        field_names = Config.COLUMNS['SchoolBook']
        user_data = list(map(lambda x: x.text(), self.widgets))
        book_sum = Utils.calculate_book_sum(user_data)
        user_data.append(str(book_sum))
        book = dict(zip(field_names[1:], user_data))
        db = DatabaseManager(Config.PATHES['TO_DATABASE']['PROD'])
        model = Schoolbook('SchoolBook', db.connection)
        model.insert_book(book)
        logger.success(f'The {book} success add in the database')
        model.model.select()

This is a little part of full code but full code doesn't solve with this problem.

dgonkaries
  • 23
  • 5
  • 1
    share SelectAddingBookTypeWindow and AddSchoolBookWindow class, provide a [mre] – eyllanesc Jul 16 '19 at 21:46
  • I hoped that I can the response in (https://stackoverflow.com/questions/13850240/pyqt-how-to-check-is-qdialog-is-visible/13850761)[this] and using method isVisible() I can solve my problem. I tried to add a string `return widget` in the method called open_new_window in the class SelectBookTypeWindow but my test string `qtbot.mouseClick(widget.selectBtn, QtCore.Qt.LeftButton)` returns None. – dgonkaries Jul 16 '19 at 22:14

1 Answers1

2

The problem in your case is that the widget is not accessible since it is a local variable, I also doubt that the window will be shown as it should be removed a moment later, so to access it I will create a property:

class SelectBookTypeWindow(QtWidgets.QDialog, Ui_selectBookTypeWindow):
    def __init__(self, widget1, widget2):
        super().__init__()
        self.setupUi(self)
        self.selectBtn.clicked.connect(lambda x: self.open_new_window(widget1, widget2))

        self._selected_window = None

    @property
    def selected_window(self):
        return self._selected_window

    def open_new_window(self, schoolbook_widget, fictionbook_widget):
        if self.schoolbookSelector.isChecked():
            self._selected_window = schoolbook_widget()
        elif self.fictionbookSelector.isChecked():
            self._selected_window = fictionbook_widget()
        if self.selected_window is not None:
            self.selected_window.show()
            self.close()

And then in the test you should verify that selected_window is not None and its base class is AddSchoolBookWindow, also avoid using time.sleep(), in the case of the tests use QTest.qWait()

import pytest
from PyQt5 import QtCore, QtTest

from your_package import AddSchoolBookWindow, SelectAddingBookTypeWindow


@pytest.fixture
def open_window(qtbot):
    def callback(window):
        widget = window()
        qtbot.addWidget(widget)
        widget.show()
        qtbot.wait_for_window_shown(widget)
        QtTest.QTest.qWait(3 * 1000)
        return widget

    return callback


class TestSelectAddingBookTypeWindow:
    def test_select_schoolbook(self, open_window, qtbot):
        widget = open_window(SelectAddingBookTypeWindow)
        assert widget.isVisible()
        qtbot.mouseClick(widget.schoolbookSelector, QtCore.Qt.LeftButton)
        qtbot.mouseClick(widget.selectBtn, QtCore.Qt.LeftButton)
        assert widget.isHidden()
        assert widget.selected_window is not None
        assert isinstance(widget.selected_window, AddSchoolBookWindow)
        assert widget.selected_window.isVisible()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241