I created a GUI that accepts input arguments when starting this is a minimum working example that I am currently using for testing.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
import os
import argparse
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import QCoreApplication, QObject, Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *
def erase_data(argv):
# print(args)
if argv.erase_data:
folders = ["scratch"]
for folder in folders:
try:
os.unlink(folder + os.sep + "file1.pkl")
os.unlink(folder + os.sep + "file2.txt")
except FileNotFoundError:
print(f"no file found in {folder} to delete")
return None
return True
return False
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)
print(args)
erase_data(args)
# 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 _str_to_bool(s):
"""Convert string to bool (in argparse context)."""
if s.lower() not in ["true", "false"]:
raise ValueError("Need bool; got %r" % s)
return {"true": True, "false": False}[s.lower()]
def add_boolean_argument(parser, name, default=False):
"""Add a boolean argument to an ArgumentParser instance."""
group = parser.add_mutually_exclusive_group()
group.add_argument(
"--" + name, nargs="?", default=default, const=True, type=_str_to_bool
)
def set_argparse():
parser = argparse.ArgumentParser(description="Run CORMAT_py")
add_boolean_argument(parser, "erase_data")
args = parser.parse_args(sys.argv[1:])
return args
def main():
app = QApplication(sys.argv)
imageViewer = Example()
return app, imageViewer
if __name__ == "__main__":
args = set_argparse()
app, imageViewer = main()
imageViewer.show()
rc = app.exec_()
print("App end is exit code {}".format(rc))
sys.exit(rc)
now I am trying to unittest a function that uses one of the passed arguments following this question and I wrote this unit test
import logging
import os
import pathlib
import sys
import pytest
from GUI import erase_data
from unittest import mock
logger = logging.getLogger(__name__)
sys.path.append(os.getcwd())
src_dir = pathlib.Path(__file__).parents[1].absolute()
print(src_dir)
sys.path.append(src_dir.as_posix())
from GUI import main
logger = logging.getLogger(__name__)
@pytest.mark.parametrize("argv, called, response", [
([], True, False),
(['--erase_data'], True, None),
(['--noerase_data'], True, False),
])
def test_erase_data_nodata(argv, called, response):
global erase_data
original_erase_data = erase_data
erase_data = mock.Mock(return_value=response)
with mock.patch('sys.argv', [''] + argv):
main()
assert erase_data.called == called
erase_data = original_erase_data
pytest.main('-x tests/test_args.py'.split())
that gets me a NameError as 'args' in the test is not defined and also a seg fault.
how to solve it?