Estou criando alguns testes de unidade para um PyQtaplicativo com pytest-qt. E eu gostaria de criar, abrir a janela gráfica, fazer alguns testes e fechar a janela, ao invés de abrir uma nova janela para cada teste, ou seja. use uma fixação do módulo para a própria janela. Consegui fazer esta parte, chamando em uma função local a em QtBotvez de usar o acessório padrão e removendo os mocker. Portanto, estou muito perto do meu objetivo.
Porém, mas não consigo fechar a janela (e testar o QMessageBoxevento de fechamento).
Eu li exemplos como como lidar com o diálogo modal e sua discussão git , ou a questão qmessage ; que parecem estar perto da minha pergunta. Sugere-se usar um cronômetro para esperar QMessageBoxque apareça o e clicar em uma opção de botão, mas visivelmente não consigo aplicá-los corretamente. Na minha tentativa, pytestrecebo a solicitação de fechamento, mas não o clique na dialogcaixa. Então, tenho que clicar em mim mesmo para terminar o teste.
Aqui está um pequeno exemplo, com arquivo GUI.py:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QCoreApplication, Qt, QObject
from PyQt5.QtGui import QIcon
class Example(QMainWindow):
def __init__(self, parent = None):
super().__init__()
self.initUI(self)
def initUI(self, MainWindow):
# centralwidget
MainWindow.resize(346, 193)
self.centralwidget = QtWidgets.QWidget(MainWindow)
# The Action to quit
self.toolb_action_Exit = QAction(QIcon('exit.png'), 'Exit', self)
self.toolb_action_Exit.setShortcut('Ctrl+Q')
self.toolb_action_Exit.triggered.connect(self.close)
# The Button
self.btn_prt = QtWidgets.QPushButton(self.centralwidget)
self.btn_prt.setGeometry(QtCore.QRect(120, 20, 89, 25))
self.btn_prt.clicked.connect(lambda: self.doPrint() )
self.btn_quit = QtWidgets.QPushButton(self.centralwidget)
self.btn_quit.setGeometry(QtCore.QRect(220, 20, 89, 25))
self.btn_quit.clicked.connect(lambda: self.close() )
# The textEdit
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setGeometry(QtCore.QRect(10, 60, 321, 81))
# Show the frame
MainWindow.setCentralWidget(self.centralwidget)
self.show()
def doPrint(self):
print('TEST doPrint')
def closeEvent(self, event):
# Ask a question before to quit.
self.replyClosing = QMessageBox.question(self, 'Message',
"Are you sure to quit?", QMessageBox.Yes |
QMessageBox.No, QMessageBox.No)
if self.replyClosing == QMessageBox.Yes:
event.accept()
else:
event.ignore()
def main_GUI():
app = QApplication(sys.argv)
imageViewer = Example()
return app, imageViewer
if __name__ == '__main__':
app, imageViewer =main_GUI()
rc= app.exec_()
print('App end is exit code {}'.format(rc))
sys.exit(rc)
e o pytestarquivo denominado test_GUI.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os, sys
import pytest
from PyQt5 import QtGui, QtCore, QtWidgets, QtTest
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QCoreApplication, Qt, QObject
from pytestqt.plugin import QtBot
GUI = __import__('GUI')
@pytest.yield_fixture(scope="module")
def qtbot_session(qapp, request):
print(" SETUP qtbot")
result = QtBot(qapp)
with capture_exceptions() as exceptions:
yield result
print(" TEARDOWN qtbot")
@pytest.fixture(scope="module")
def Viewer(request):
print(" SETUP GUI")
app, imageViewer = GUI.main_GUI()
qtbotbis = QtBot(app)
# qtbotbis.addWidget(imageViewer)
# qtbotbis.wait_for_window_shown(imageViewer)
QtTest.QTest.qWait(0.5 *1000)
yield app, imageViewer, qtbotbis
# EXIT
# mocker.patch.object(QMessageBox, 'question', return_value=QMessageBox.Yes)
# imageViewer.toolb_action_Exit.trigger()
def handle_dialog():
# while not imageViewer.replyClosing.isVisible():
# app.processEvents()
box = QMessageBox()
box.setStandardButtons(QMessageBox.Yes)
button = box.button(QMessageBox.Yes)
qtbotbis.mouseClick(button, QtCore.Qt.LeftButton)
QtCore.QTimer.singleShot(100, handle_dialog)
qtbotbis.mouseClick(imageViewer.btn_quit, QtCore.Qt.LeftButton, delay=1)
assert imageViewer.close()
print(" TEARDOWN GUI")
class Test_GUI() :
def test_interface(self, Viewer):
print(" beginning ")
app, imageViewer, qtbot = Viewer
qtbot.mouseClick( imageViewer.btn_prt, QtCore.Qt.LeftButton )
QtTest.QTest.qWait(0.5 *1000)
assert True
print(" Test passed")
Alguma ideia do que estou perdendo? Qualquer outra ideia ou sugestão também seria apreciada.
Em sua tentativa, você está criando um novo QMessageBoxque é diferente daquele criado com o método estático, QMessageBox::question()portanto, mesmo que você clique, ele não funcionará.
A ideia é obter o QMessageBoxmostrado, e neste caso tiraremos vantagem disso já que é a janela ativa para que possamos obtê-lo usando QApplication::activeWindow(). Outra maneira de obter o QMessageBox é usar o relacionamento entre o imageViewer e o QMessageBox por meio de findChild():
@pytest.fixture(scope="module")
def Viewer(request):
print(" SETUP GUI")
app, imageViewer = GUI.main_GUI()
qtbotbis = QtBot(app)
QtTest.QTest.qWait(0.5 * 1000)
yield app, imageViewer, qtbotbis
def handle_dialog():
messagebox = QtWidgets.QApplication.activeWindow()
# or
# messagebox = imageViewer.findChild(QtWidgets.QMessageBox)
yes_button = messagebox.button(QtWidgets.QMessageBox.Yes)
qtbotbis.mouseClick(yes_button, QtCore.Qt.LeftButton, delay=1)
QtCore.QTimer.singleShot(100, handle_dialog)
qtbotbis.mouseClick(imageViewer.btn_quit, QtCore.Qt.LeftButton, delay=1)
assert imageViewer.isHidden()
Jana Duggar foi aberta sobre sua busca pelo amor. Aqui está tudo o que ela disse sobre o assunto e sua janela de cinco anos para o casamento.
O astro de 'Outlander', Sam Heughan, revelou recentemente o que vai levar do set para relembrar Jamie Fraser, o papel que o tornou uma estrela.
'She Loves You' foi escrita em uma hora, gravada em um dia, e foi a música dos Beatles com uma de suas melhores apresentações de sua carreira.
Dolly Parton e sua avó Bessie tiveram um relacionamento especial. Vovó Parton estava muito doente, mas isso não impediu Dolly de pregar uma peça nela.
Você pode achar que o carvalho ou a nogueira são madeiras resistentes, mas quando se trata da madeira mais dura do mundo, elas nem chegam perto.
O oceano é repleto de beleza, mas também esconde algumas das criaturas marinhas mais assustadoras do planeta. Muitos desses animais espreitam nas profundezas do oceano, no mundo escuro e de alta pressão do fundo do mar.
Se você está enfrentando criaturas hostis ou se preparando para cenários PvP, conhecer os melhores encantamentos de espada no Minecraft pode te dar uma grande vantagem. Encantar espadas permite causar mais dano, aumentar a quantidade de itens obtidos de criaturas e prolongar a durabilidade da sua espada.
Quando as pessoas falam sobre países socialistas, geralmente imaginam o controle total do governo e a ausência de propriedade privada. Mas, na prática, as economias socialistas variam muito.
“Children” traz uma participação especial de grande nome e algumas notícias devastadoras
Este RAV4 está em excelentes condições e está preparado para um jogo de cadeiras musicais.
Imagens de drone capturaram bombeiros parecendo lutar para apagar o incêndio.
Eyes of Wakanda está diretamente relacionado ao MCU, além de atualizações sobre X-Men '97, What If..., Demolidor e muito mais.
O anel de noivado de Kate Middleton pertenceu à Princesa Diana antes do Príncipe William pedi-la em casamento. Descubra tudo o que há para saber sobre a peça histórica aqui.
John Cleese se casou com sua esposa, Jennifer Wade, em 2012. Aqui está tudo o que você precisa saber sobre a esposa de John Cleese, Jennifer Wade.
Patton Oswalt se casou com sua esposa, a também atriz Meredith Salenger, em 2017. Aqui está tudo o que você precisa saber sobre a esposa de Patton Oswalt, Meredith Salenger.
Mena Suvari é casada com o marido Michael Hope desde 2018. Aqui está tudo o que você precisa saber sobre o marido de Mena Suvari.
Isso me atinge De repente, como tantas vezes acontece É o meio do caminho tudo de novo <Não, não aquele no Pacífico, seu marrom, aquele no carnaval> Todas as manchetes em voz alta…..
Em 2022, com o lançamento do GPT-3, a habilidade de escrita parece se tornar menos importante. Com a IA, pessoas com redação ruim também podem gerar funcionários de qualidade.
No mundo acelerado e competitivo de hoje, a carreira desempenha um papel significativo no crescimento pessoal, na estabilidade financeira e na satisfação geral com a vida. No entanto, muitos indivíduos encontram-se presos em um ciclo implacável de estagnação e insatisfação, definhando gradualmente em suas vidas profissionais.
Na semana passada, notei um comunicado de imprensa, enviado via PressGazette (um site de notícias da mídia britânica). O artigo anunciava que a Acast, a empresa de publicidade e hospedagem de podcast Scandi, lideraria um consórcio de "provavelmente os editores mais influentes" em podcasting.