I'm writing a functional test for the QGIS plugin I'm developing. There's a button in the plugin that is enabled only if there is a valid vector layer present. The thing I'm bumping into is the layer event handling from a standard lib unittest isn't triggering the button enable as expected. When I test manually, the button is enabled fine, but from the test it isn't.
My test setup is pretty straightforward:
import unittest
from qgis.core import QgsApplication, QgsVectorLayer
from namari_dockwidget import NamariDockWidget
app = QgsApplication(argv=[], GUIenabled=True)
app.initQgis()
class NamariDockWidgetTest(unittest.TestCase):
def setUp(self) -> None:
self.dock_widget = NamariDockWidget()
def test_dockwidget_layer_selector(self) -> None:
with self.subTest('When we start the widget, there is no layer set'):
self.assertTrue(self.dock_widget.isEnabled())
layer = self.dock_widget.mMapLayerComboBox.currentLayer()
self.assertEqual(layer, None)
with self.subTest('So the "Build model" button is disabled'):
enabled = self.dock_widget.pushButtonBuildModel.isEnabled()
self.assertFalse(enabled)
with self.subTest('But when we load a vector data source'):
layer = QgsVectorLayer(
path='test/data/amersfoort-centre.gpkg',
baseName='amersfoort-centre',
providerLib='ogr')
self.assertEqual(len(layer.fields()), 10)
# Load the vector layer
self.dock_widget.iface.addMapLayer(layer)
with self.subTest('Then the build button is enabled'):
enabled = self.dock_widget.pushButtonBuildModel.isEnabled()
self.assertTrue(enabled)
However the last assertion fails: the button is not enabled once the layer is added through the iface object (that I learned from this excellent question). Any idea on what I'm missing?
To reproduce: the current state of the plugin is in https://github.com/reinvantveer/namari/tree/button_test_issue-alpha2. There's a very helpful Dockerile that can help you get up and running the test within minutes: just run docker build ., but there's also the output of the associated GitHub action build at https://github.com/reinvantveer/namari/runs/2208580233.
EDIT: I now see that I only loaded the UI elements from the NamariDockWidget, but this does not include the Namari class I wrote for the logic. Somehow, I need access to the QGIS iface object from within my unit test, but how does this work?
The plugin logic class begins like
# ...
class Namari:
def __init__(self, iface: QgisInterface) -> None:
So a lot of the logic depends on the iface object being available. But I have currently no way of strapping a class instance to my test.
ifaceobject either: https://github.com/reinvantveer/namari/runs/2208580233#step:3:176 but now I'm faced with the question how to enable this – Rein Apr 02 '21 at 12:56