omassot преди 7 години
родител
ревизия
9faf730925
променени са 7 файла, в които са добавени 436 реда и са изтрити 67 реда
  1. 10 4
      core/checking.py
  2. 7 13
      schemas/mn1_rec.py
  3. 2 4
      schemas/mn2_rec.py
  4. 17 11
      test/_base.py
  5. 371 28
      test/test_mn1_rec.py
  6. 16 7
      ui/dlg_contact.py
  7. 13 0
      ui/dlg_contact.ui

+ 10 - 4
core/checking.py

@@ -110,13 +110,17 @@ class BaseChecker():
     def log_critical(self, message, **info):
         self._test_running.log_error(f"[CRITIQUE] {message}", info, critical=True)
     
-    def run(self, rxfilter_=""):
+    def run(self, rxfilter="", dry=False):
+        
+        # 'rxfilter' allow to filter the tests to run with a regex
+        # if 'dry' is set to True, setUp and tearDown are skipped
+        # both are used for testing purpose
         
         tests_results = []
         
         for test in self.tests:
             
-            if rxfilter_ and not re.fullmatch(rxfilter_, test.__name__, re.IGNORECASE):     #@UndefinedVariable
+            if rxfilter and not re.fullmatch(rxfilter, test.__name__, re.IGNORECASE):     #@UndefinedVariable
                 continue
                 
             result = TestResult(test)
@@ -124,14 +128,16 @@ class BaseChecker():
             self._test_running = result
             self.comlink._started_test(result)
             
-            self.setUp()
+            if not dry:
+                self.setUp()
             
             try:
                 test()
             except:
                 result.handle_exception(sys.exc_info())
             
-            self.tearDown()
+            if not dry:
+                self.tearDown()
 
             tests_results.append(result)
             

+ 7 - 13
schemas/mn1_rec.py

@@ -187,16 +187,14 @@ models = [Artere, Cable, Equipement, Noeud, Tranchee, Zapbo]
 ####### Validateur
 
 class Mn1Checker(BaseChecker):
-    def __init__(self):
-        super().__init__()
+
+    def setUp(self):
         
         self.dataset = {}
         for model in models:
             model.layer = next((l for l in QgsProject.instance().mapLayers().values() \
                           if l.name().lower() == model.layername.lower()), None)
             self.dataset[model] = [model(f) for f in model.layer.getFeatures()]
-            
-    def setUp(self):
         
         self.arteres = self.dataset.get(Artere, [])
         self.cables = self.dataset.get(Cable, [])
@@ -220,7 +218,6 @@ class Mn1Checker(BaseChecker):
         """ Chargement des données
             Contrôle la présence des couches attendues
         """
-        
         for model in models:
             if model.layer is None:
                 self.log_critical("Couche manquante", model=model)
@@ -229,7 +226,6 @@ class Mn1Checker(BaseChecker):
             if model.pk:
                 if not model.pk.lower() in [f.name().lower() for f in model.layer.fields()]:
                     self.log_critical(f"Clef primaire manquante ({model.pk})", model=model)
-                    continue
             
     def test_scr(self):
         """ Contrôle des projections 
@@ -312,7 +308,6 @@ class Mn1Checker(BaseChecker):
         """ Contrôle des emprises 
         Vérifie que les objets sont dans le périmètre attendu
         """
-        
         for model in models:
             xmin, ymin, xmax, ymax = model.bounding_box
             
@@ -328,7 +323,6 @@ class Mn1Checker(BaseChecker):
         """ Recherche de doublons 
         Recherche d'éventuels doublons dans des champs qui supposent l'unicité
         """
-        
         tmp = []
         for noeud in self.noeuds:
             if not noeud.NO_NOM:
@@ -401,27 +395,27 @@ class Mn1Checker(BaseChecker):
             
         for i, tranchee in enumerate(self.tranchees):
             for other in self.tranchees[i+1:]:
-                if tranchee.geom == other.geom:
+                if tranchee.geom.asLine() == other.geom.asLine():
                     self.log_error("Une entité graphique est dupliquée", item=tranchee)
                     
         for i, artere in enumerate(self.arteres):
             for other in self.arteres[i+1:]:
-                if artere.geom == other.geom:
+                if artere.geom.asLine() == other.geom.asLine():
                     self.log_error("Une entité graphique est dupliquée", item=artere)
 
         for i, cable in enumerate(self.cables):
             for other in self.cables[i+1:]:
-                if cable.geom == other.geom and cable.CA_EQ_A == other.CA_EQ_A and cable.CA_EQ_B == other.CA_EQ_B:
+                if cable.geom.asLine() == other.geom.asLine() and cable.CA_EQ_A == other.CA_EQ_A and cable.CA_EQ_B == other.CA_EQ_B:
                     self.log_error("Une entité graphique est dupliquée", item=cable)
         
         for i, noeud in enumerate(self.noeuds):
             for other in self.noeuds[i+1:]:
-                if noeud.geom == other.geom:
+                if noeud.geom.asPoint() == other.geom.asPoint():
                     self.log_error("Une entité graphique est dupliquée", item=noeud)
         
         for i, zapbo in enumerate(self.zapbos):
             for other in self.zapbos[i+1:]:
-                if zapbo.geom == other.geom:
+                if zapbo.geom.asPoint() == other.geom.asPoint():
                     self.log_error("Une entité graphique est dupliquée", item=zapbo)
         
     def test_positions_noeuds(self):

+ 2 - 4
schemas/mn2_rec.py

@@ -208,16 +208,14 @@ models = [Artere, Cable, Equipement, Noeud, Tranchee, Zapbo]
 
 
 class Mn2Checker(BaseChecker):
-    def __init__(self):
-        super().__init__()
+            
+    def setUp(self):
         
         self.dataset = {}
         for model in models:
             model.layer = next((l for l in QgsProject.instance().mapLayers().values() \
                           if l.name().lower() == model.layername.lower()), None)
             self.dataset[model] = [model(f) for f in model.layer.getFeatures()]
-            
-    def setUp(self):
         
         self.arteres = self.dataset.get(Artere, [])
         self.cables = self.dataset.get(Cable, [])

+ 17 - 11
test/_base.py

@@ -11,17 +11,23 @@ class SchemaTest(unittest.TestCase):
     SCHEMA_NAME = ""
     PROJECT_FILE = ""
     
-    def _open_qgs_project(self, filename):
+    @classmethod
+    def setUpClass(cls):
+        if cls.PROJECT_FILE:
+            cls._open_qgs_project(cls.PROJECT_FILE)
+            
+    @classmethod
+    def tearDownClass(cls):
+        if cls.PROJECT_FILE:
+            cls._close_qgs_project()
+            
+    @classmethod
+    def _open_qgs_project(cls, filename):
         QgsProject.instance().clear()
-        QgsProject.instance().read(filename)
+        ok = QgsProject.instance().read(filename)
+        if not ok:
+            raise IOError("Error while loading the qgis project {}: {}".format(cls.PROJECT_FILE, QgsProject.instance().error()))
 
-    def _close_qgs_project(self):
+    @classmethod
+    def _close_qgs_project(cls):
         QgsProject.instance().clear()
-        
-    def setUp(self):
-        
-        if self.PROJECT_FILE:
-            self._open_qgs_project(self.PROJECT_FILE)
-            
-        if self.SCHEMA_NAME:
-            self.schema = mncheck.get_schema(self.SCHEMA_NAME)

+ 371 - 28
test/test_mn1_rec.py

@@ -2,86 +2,429 @@
 
 @author: olivier.massot, janv. 2019
 '''
+from core import mncheck
 import logging
 
+from qgis.core import QgsCoordinateReferenceSystem, QgsGeometry, QgsPointXY
+
+from core.checking import SUCCESS, FAILURE
 from path import Path
 from test._base import SchemaTest
 
+
 logger = logging.getLogger("mncheck")
 
 class Test(SchemaTest):
     SCHEMA_NAME = "mn1_rec"
-    PROJECT_FILE = Path(__file__).parent / 'projects' / 'mn1_rec' / '01_valid' / '01_valid.qgs'
+    PROJECT_FILE = Path(__file__).parent / 'projects' / 'mn1_rec' / '1_valid' / '1_valid.qgz'
+
+    def setUp(self):
+        SchemaTest.setUp(self)
+        self.schema = mncheck.get_schema(self.SCHEMA_NAME)
+        if not self.schema.checkers:
+            raise AttributeError("Aucun testeur trouvé dans le schéma")
+        self.checker = self.schema.checkers[0]()
 
+    def run_test(self, test_name, dry=False):
+        results = self.checker.run(test_name, dry)
+        if len(results) == 0:
+            raise Exception("No result for test")
+        elif len(results) > 1:
+            raise Exception("More than one result from test")
+        return results[0]
+    
+    def assertSuccess(self, r):
+        if not r.status == SUCCESS:
+            raise AssertionError("Le test a échoué")
+    
+    def assertFailure(self, r):
+        if not r.status == FAILURE:
+            raise AssertionError("Le test n'aurait pas dû réussir")
+    
+    def assertErrorLogged(self, result, err_msg):
+        if not any((err.message == err_msg for err in result.errors)):
+            raise AssertionError("Error was not logged: {}".format(err_msg))
+    
     def test_load_layers(self):
-        pass
         
+        # cas initial: valide
+        r = self.run_test("test_load_layers")
+
+        self.assertEqual(r.title, 'Chargement des données')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # une couche manquante et une pk manquante
+        _pk_ini = self.schema.Cable.pk
+        try:
+            self.schema.Artere.layer = None
+            self.schema.Cable.pk = "not_a_qgis_field"
+    
+            r = self.run_test("test_load_layers", True)
+            
+            self.assertFailure(r)
+            self.assertErrorLogged(r, "[CRITIQUE] Couche manquante")
+            self.assertErrorLogged(r, "[CRITIQUE] Clef primaire manquante (not_a_qgis_field)")
+        except:
+            raise
+        finally:
+            self.schema.Cable.pk = _pk_ini
+            
+            
     def test_scr(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_scr")
+
+        self.assertEqual(r.title, 'Contrôle des projections')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
     
-    def test_structure_arteres(self):
-        pass
+        # mauvaise projection
+        self.schema.Artere.layer.setCrs(QgsCoordinateReferenceSystem())
+        r = self.run_test("test_scr", True)
+        self.assertFailure(r)
     
+    def test_structure_arteres(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_structure_arteres")
+
+        self.assertEqual(r.title, 'Structure des données: Artères')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # valeur non autorisée
+        self.checker.arteres[0].AR_ID_INSE = "invalid"
+        r = self.run_test("test_structure_arteres", True)
+        self.assertFailure(r)
+        
     def test_structure_cables(self):
-        pass
-    
+        
+        # cas initial: valide
+        r = self.run_test("test_structure_cables")
+
+        self.assertEqual(r.title, 'Structure des données: Cables')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # valeur non autorisée
+        self.checker.cables[0].CA_TYPE = "invalid"
+        r = self.run_test("test_structure_cables", True)
+        self.assertFailure(r)
+        
     def test_structure_equipements(self):
-        pass
         
+        # cas initial: valide
+        r = self.run_test("test_structure_equipements")
+
+        self.assertEqual(r.title, 'Structure des données: Equipements')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # valeur non autorisée
+        self.checker.equipements[0].EQ_TYPE = "invalid"
+        r = self.run_test("test_structure_equipements", True)
+        self.assertFailure(r)
+            
     def test_structure_noeuds(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_structure_noeuds")
 
+        self.assertEqual(r.title, 'Structure des données: Noeuds')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # valeur non autorisée
+        self.checker.noeuds[0].NO_ID_INSE = "invalid"
+        r = self.run_test("test_structure_noeuds", True)
+        self.assertFailure(r)
+    
     def test_structure_tranchees(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_structure_tranchees")
 
+        self.assertEqual(r.title, 'Structure des données: Tranchées')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # valeur non autorisée
+        self.checker.tranchees[0].TR_REVET = "invalid"
+        r = self.run_test("test_structure_tranchees", True)
+        self.assertFailure(r)
+    
     def test_structure_zapbos(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_structure_zapbos")
 
+        self.assertEqual(r.title, 'Structure des données: Zapbos')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # valeur non autorisée
+        self.checker.zapbos[0].STATUT = "invalid"
+        r = self.run_test("test_structure_zapbos", True)
+        self.assertFailure(r)
+    
     def test_geometry_validity(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_geometry_validity")
 
+        self.assertEqual(r.title, 'Contrôle de la validité des géométries')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # géométrie invalide
+        self.checker.arteres[0]._feature.setGeometry(QgsGeometry())
+        r = self.run_test("test_geometry_validity", True)
+        self.assertFailure(r)
+    
     def test_geometry_type(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_geometry_type")
+
+        self.assertEqual(r.title, 'Contrôle des types de géométries')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+
+        # type de géométrie invalide
+        self.checker.arteres[0]._feature.setGeometry(QgsGeometry())
+        r = self.run_test("test_geometry_type", True)
+        self.assertFailure(r)
 
     def test_bounding_box(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_bounding_box")
 
+        self.assertEqual(r.title, 'Contrôle des emprises')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # hors de l'emprise
+        self.checker.noeuds[0]._feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0,0)))
+        r = self.run_test("test_bounding_box", True)
+        self.assertFailure(r)
+    
     def test_duplicates(self):
-        pass
         
+        # cas initial: valide
+        r = self.run_test("test_duplicates")
+
+        self.assertEqual(r.title, 'Recherche de doublons')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+            
+        # cas de doublon
+        self.checker.noeuds[0].NO_NOM = self.checker.noeuds[1].NO_NOM
+        r = self.run_test("test_duplicates", True)
+        self.assertFailure(r)
+            
     def test_constraints_arteres_noeuds(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_constraints_arteres_noeuds")
 
+        self.assertEqual(r.title, 'Application des contraintes: Artères / Noeuds')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # contrainte invalide
+        self.checker.arteres[0].noeud_a = None
+        r = self.run_test("test_constraints_arteres_noeuds", True)
+        self.assertFailure(r)
+    
     def test_constraints_cables_equipements(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_constraints_cables_equipements")
 
+        self.assertEqual(r.title, 'Application des contraintes: Equipements / Cables')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # contrainte invalide
+        self.checker.cables[0].equipement_a = None
+        r = self.run_test("test_constraints_cables_equipements", True)
+        self.assertFailure(r)
+    
     def test_constraints_cables_equipements_b(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_constraints_cables_equipements_b")
 
+        self.assertEqual(r.title, 'Application des contraintes: Equipements B')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # contrainte invalide
+        for cable in self.checker.cables:
+            cable.CA_EQ_B = ""
+        r = self.run_test("test_constraints_cables_equipements_b", True)
+        self.assertFailure(r)
+    
     def test_constraints_equipements_noeuds(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_constraints_equipements_noeuds")
 
+        self.assertEqual(r.title, 'Application des contraintes: Noeuds / Equipements')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # contrainte invalide
+        self.checker.equipements[0].noeud = None
+        r = self.run_test("test_constraints_equipements_noeuds", True)
+        self.assertFailure(r)
+    
     def test_graphic_duplicates(self):
-        pass
         
+        # cas initial: valide
+        r = self.run_test("test_graphic_duplicates")
+
+        self.assertEqual(r.title, 'Recherche de doublons graphiques')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # doublon graphique
+        self.checker.noeuds[0]._feature.setGeometry(self.checker.noeuds[1]._feature.geometry())
+        r = self.run_test("test_graphic_duplicates", True)
+        self.assertFailure(r)
+            
     def test_positions_noeuds(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_positions_noeuds")
 
+        self.assertEqual(r.title, 'Topologie: Noeuds / Artères')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # erreur topo
+        self.checker.noeuds[0]._feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0,0)))
+        r = self.run_test("test_positions_noeuds", True)
+        self.assertFailure(r)
+    
     def test_positions_equipements(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_positions_equipements")
+
+        self.assertEqual(r.title, 'Topologie: Equipements / Cables')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
     
+        # erreur topo
+        self.checker.cables[0].equipement_b.noeud._feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0,0)))
+        r = self.run_test("test_positions_equipements", True)
+        self.assertFailure(r)
+        
     def test_tranchee_artere(self):
-        pass
         
+        # cas initial: valide
+        r = self.run_test("test_tranchee_artere")
+
+        self.assertEqual(r.title, 'Topologie: Tranchées / Artères')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # erreur topo
+        new_geom = self.checker.tranchees[0]._feature.geometry()
+        new_geom.translate(10000, 10000)
+        self.checker.tranchees[0]._feature.setGeometry(new_geom)
+        
+        r = self.run_test("test_tranchee_artere", True)
+        self.assertFailure(r)
+            
     def test_cable_artere(self):
-        pass
         
+        # cas initial: valide
+        r = self.run_test("test_cable_artere")
+
+        self.assertEqual(r.title, 'Topologie: Cables / Artères')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # erreur topo
+        self.checker.cables[0].CA_COMMENT = ""
+        new_geom = self.checker.cables[0]._feature.geometry()
+        new_geom.translate(10000, 10000)
+        self.checker.cables[0]._feature.setGeometry(new_geom)
+        
+        r = self.run_test("test_cable_artere", True)
+        self.assertFailure(r)
+            
     def test_artere_cable(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_artere_cable")
+
+        self.assertEqual(r.title, 'Topologie: Artères / Cables')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
     
+        # erreur topo
+        self.checker.arteres[0].AR_COMMENT = ""
+        new_geom = self.checker.arteres[0]._feature.geometry()
+        new_geom.translate(10000, 10000)
+        self.checker.arteres[0]._feature.setGeometry(new_geom)
+        
+        r = self.run_test("test_artere_cable", True)
+        self.assertFailure(r)
+        
     def test_dimensions_fourreaux(self):
-        pass
-         
+        
+        # cas initial: valide
+        r = self.run_test("test_dimensions_fourreaux")
+
+        self.assertEqual(r.title, 'Dimensions logiques: fourreaux')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # nombre de fourreaux incohérent
+        self.checker.arteres[0].AR_FOU_DIS = 1000
+        r = self.run_test("test_dimensions_fourreaux", True)
+        self.assertFailure(r)
+        
+        self.checker.arteres[0].AR_FOU_DIS = 0
+        
+        # nombre de fourreaux incohérent
+        self.checker.cables[0].CA_NB_FO_U = 1000
+        r = self.run_test("test_dimensions_fourreaux", True)
+        self.assertFailure(r)
+        
+        self.checker.cables[0].CA_NB_FO_U = 0
+        
+        # nombre de fourreaux incohérent
+        self.checker.cables[0].CA_NB_FO_D = 1000
+        r = self.run_test("test_dimensions_fourreaux", True)
+        self.assertFailure(r)
+             
     def test_pbos(self):
-        pass
+        
+        # cas initial: valide
+        r = self.run_test("test_pbos")
+
+        self.assertEqual(r.title, 'Topologie: PBO / ZAPBO')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        # equipement hors zapbo
+        _ini_geom = self.checker.equipements[0]._feature.geometry()
+        self.checker.equipements[0]._feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0,0)))
+        
+        r = self.run_test("test_pbos", True)
+        self.assertFailure(r)
+        
+        self.checker.equipements[0]._feature.setGeometry(_ini_geom)
+        
+        # noms equipement / zapbo incoherents
+        self.checker.equipements[0].EQ_NOM = "%__#123456789#__%"
+        r = self.run_test("test_pbos", True)
+        self.assertFailure(r)
         

+ 16 - 7
ui/dlg_contact.py

@@ -11,11 +11,10 @@ from PyQt5 import QtWidgets
 from PyQt5 import uic
 from PyQt5.QtCore import Qt, QFileInfo
 from PyQt5.QtGui import QIcon, QPixmap
-from PyQt5.QtWidgets import QTextBrowser
+from PyQt5.QtWidgets import QTextBrowser, QDialog, QApplication
 
 from core.constants import MAIN, LOGDIR, RSCDIR, CONTACT, TESTDIR, DEBUG
 from path import Path
-from test._stream import TestStream
 
 
 logger = logging.getLogger("mncheck")
@@ -26,6 +25,7 @@ Ui_Contact, _ = uic.loadUiType(MAIN / 'ui'/ 'dlg_contact.ui')
 class DlgContact(QtWidgets.QDialog):
     def __init__(self, parent=None):
         super().__init__(parent)
+        
         self.createWidgets()
 
     def createWidgets(self):
@@ -48,6 +48,10 @@ class DlgContact(QtWidgets.QDialog):
         self.ui.btn_test.setVisible(DEBUG)
         self.ui.btn_test.clicked.connect(self.run_tests)
     
+        self._chk_dlg = QTextBrowser()
+        self._chk_dlg.setMinimumSize(500, 400)
+        self._chk_dlg.setWindowTitle("Checkup: Résultats")
+    
     def open_log_dir(self):
         path = Path(LOGDIR).abspath()
         if platform.system() == "Windows":
@@ -58,7 +62,9 @@ class DlgContact(QtWidgets.QDialog):
     def run_tests(self):
         _initial_project = QgsProject.instance().absoluteFilePath()
         if _initial_project:
-            QgsProject.instance().write(QFileInfo(_initial_project))
+            QgsProject.instance().write(_initial_project)
+        
+        QApplication.setOverrideCursor(Qt.WaitCursor)
         
         loader = unittest.TestLoader()
         tests = loader.discover(Path(TESTDIR).abspath())
@@ -69,9 +75,12 @@ class DlgContact(QtWidgets.QDialog):
 
         if _initial_project:
             QgsProject.instance().clear()
-            QgsProject.read(QFileInfo(_initial_project))
+            QgsProject.instance().read(_initial_project)
+
+        QApplication.restoreOverrideCursor()
 
         with open(LOGDIR / "checkup.txt", "r") as f:
-            dlg = QTextBrowser()
-            dlg.setText(f.read())
-            dlg.show()
+            self._chk_dlg.setText(f.read())
+            self._chk_dlg.show()
+            
+        

+ 13 - 0
ui/dlg_contact.ui

@@ -248,6 +248,19 @@
     </property>
    </widget>
   </widget>
+  <widget class="QPushButton" name="btn_test">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>260</y>
+     <width>151</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Tester les schémas</string>
+   </property>
+  </widget>
  </widget>
  <resources/>
  <connections/>