瀏覽代碼

Add unittests for new tests / add coverage

omassot 6 年之前
父節點
當前提交
3e5677ada7

+ 1 - 0
.gitignore

@@ -2,6 +2,7 @@
 .project
 .project
 .pydevproject
 .pydevproject
 .settings/
 .settings/
+coverage/
 
 
 # logs
 # logs
 *.log
 *.log

+ 2 - 0
core/constants.py

@@ -22,3 +22,5 @@ USER_DIR.mkdir_p()
 
 
 LOGDIR = USER_DIR
 LOGDIR = USER_DIR
 USER_DATA = USER_DIR / 'user.yaml'
 USER_DATA = USER_DIR / 'user.yaml'
+
+COVERAGE_DIR = Path(MAIN / "coverage")

+ 1 - 3
schemas/mn1_rec.py

@@ -504,8 +504,6 @@ class Mn1Checker(BaseChecker):
         arteres_full_buffer = Artere.full_buffer(TOLERANCE)
         arteres_full_buffer = Artere.full_buffer(TOLERANCE)
         
         
         for cable in self.cables:
         for cable in self.cables:
-            if cable.CA_NUMERO == "079AF012C03":
-                logger.info(">>> %s", arteres_full_buffer.contains(cable.geom))
             if "baguette" in cable.CA_COMMENT.lower() or not cable.is_geometry_valid():
             if "baguette" in cable.CA_COMMENT.lower() or not cable.is_geometry_valid():
                 continue
                 continue
             if not arteres_full_buffer.contains(cable.geom):
             if not arteres_full_buffer.contains(cable.geom):
@@ -647,7 +645,7 @@ class Mn1Checker(BaseChecker):
                 continue
                 continue
             
             
     def test_comments(self):
     def test_comments(self):
-        """ Commentaires
+        """ Présence de commentaires
         Vérifie la présence de commentaires là où ils sont attendus
         Vérifie la présence de commentaires là où ils sont attendus
         """
         """
         for equipement in self.equipements:
         for equipement in self.equipements:

+ 6 - 6
schemas/mn2_rec.py

@@ -510,8 +510,8 @@ class Mn2Checker(BaseChecker):
         for equipement in self.equipements:
         for equipement in self.equipements:
             if equipement.EQ_TYPE == "BAI":
             if equipement.EQ_TYPE == "BAI":
                 continue
                 continue
-            if not equipement.EQ_NOM in equipements_b:
-                self.log_error(f"L'equipement '{equipement.EQ_NOM}' n'est l'équipement B d'aucun cable et n'est pas un PM", item=equipement)
+            if not equipement.EQ_CODE in equipements_b:
+                self.log_error(f"L'equipement '{equipement.EQ_CODE}' n'est l'équipement B d'aucun cable et n'est pas un PM", item=equipement)
 
 
     def test_constraints_equipements_noeuds(self):
     def test_constraints_equipements_noeuds(self):
         """ Application des contraintes: Noeuds / Equipements
         """ Application des contraintes: Noeuds / Equipements
@@ -643,10 +643,10 @@ class Mn2Checker(BaseChecker):
                 elif getattr(equipement, field) == "":
                 elif getattr(equipement, field) == "":
                     self.log_error("Le champs doit être renseigné: {}".format(field), item=equipement)
                     self.log_error("Le champs doit être renseigné: {}".format(field), item=equipement)
     
     
-            if equipement.EQ_TYPE == "BPE" and equipement.NO_TYPE_PH == "POTEAU":
+            if equipement.EQ_TYPE == "BPE" and equipement.noeud.NO_TYPE_PH == "POTEAU":
                 self.log_error("Une BPE ne peut pas être sur un poteau", item=equipement)
                 self.log_error("Une BPE ne peut pas être sur un poteau", item=equipement)
                 
                 
-            if equipement.EQ_TYPE == "PBO" and equipement.NO_TYPE_PH == "POTEAU":
+            if equipement.EQ_TYPE == "PBO" and equipement.noeud.NO_TYPE_PH == "POTEAU":
                 try:
                 try:
                     if not 2.4 <= float(equipement.EQ_HAUT) <= 4.0:
                     if not 2.4 <= float(equipement.EQ_HAUT) <= 4.0:
                         self.log_error("PBO sur poteau: La hauteur doit être comprise entre 2.40m et 4.00m", item=equipement)
                         self.log_error("PBO sur poteau: La hauteur doit être comprise entre 2.40m et 4.00m", item=equipement)
@@ -770,7 +770,7 @@ class Mn2Checker(BaseChecker):
             # On se base sur le nom pour trouver la zapbo correspondante
             # On se base sur le nom pour trouver la zapbo correspondante
             equipement.zapbo = next((z for z in candidates if equipement.EQ_CODE in z.ID_ZAPBO), None)
             equipement.zapbo = next((z for z in candidates if equipement.EQ_CODE in z.ID_ZAPBO), None)
             if not equipement.zapbo:
             if not equipement.zapbo:
-                self.log_error("Le nom du PBO ne coincide avec le nom d'aucune des ZAPBO qui le contiennent", item=equipement)
+                self.log_error("Le nom de la PBO ne coincide avec le nom d'aucune des ZAPBO qui le contiennent", item=equipement)
                 continue
                 continue
             
             
             if equipement.EQ_STATUT != equipement.zapbo.STATUT:
             if equipement.EQ_STATUT != equipement.zapbo.STATUT:
@@ -778,7 +778,7 @@ class Mn2Checker(BaseChecker):
                 continue
                 continue
                 
                 
     def test_comments(self):
     def test_comments(self):
-        """ Commentaires
+        """ Présence de commentaires
         Vérifie la présence de commentaires là où ils sont attendus
         Vérifie la présence de commentaires là où ils sont attendus
         """
         """
         for equipement in self.equipements:
         for equipement in self.equipements:

二進制
test/projects/mn1_rec/1_valid/1_valid.qgz


二進制
test/projects/mn1_rec/1_valid/ARTERE_GEO.dbf


二進制
test/projects/mn1_rec/1_valid/EQUIPEMENT_PASSIF.dbf


二進制
test/projects/mn1_rec/1_valid/NOEUD_GEO.dbf


二進制
test/projects/mn1_rec/1_valid/ZAPBO_GEO.dbf


二進制
test/projects/mn2_rec/1_valid/1_valid.qgz


二進制
test/projects/mn2_rec/1_valid/ARTERE_GEO.dbf


二進制
test/projects/mn2_rec/1_valid/EQUIPEMENT_PASSIF.dbf


二進制
test/projects/mn2_rec/1_valid/NOEUD_GEO.dbf


二進制
test/projects/mn2_rec/1_valid/ZAPBO_GEO.dbf


+ 88 - 3
test/test_mn1_rec.py

@@ -47,7 +47,6 @@ class Test(SchemaTest):
     
     
     def assertErrorLogged(self, result, err_msg):
     def assertErrorLogged(self, result, err_msg):
         if not any((re.fullmatch(err_msg, err.message) for err in result.errors)):
         if not any((re.fullmatch(err_msg, err.message) for err in result.errors)):
-            print(result.errors)
             raise AssertionError("Error was not logged: {}".format(err_msg))
             raise AssertionError("Error was not logged: {}".format(err_msg))
     
     
     def test_load_layers(self):
     def test_load_layers(self):
@@ -398,6 +397,92 @@ class Test(SchemaTest):
         self.assertFailure(r)
         self.assertFailure(r)
         self.assertErrorLogged(r, "Artère ou portion d'artère sans cable")
         self.assertErrorLogged(r, "Artère ou portion d'artère sans cable")
         
         
+    def test_arteres_enterrees(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_arteres_enterrees")
+
+        self.assertEqual(r.title, 'Données des artères enterrées')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.arteres[0].AR_TYPE_FO = "PVC"
+        
+        del self.checker.arteres[0].__dict__["AR_NB_FOUR"]
+        self.checker.arteres[0].AR_FOU_DIS = ""
+        
+        r = self.run_test("test_arteres_enterrees", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "Le champs est obligatoire: AR_NB_FOUR")
+        self.assertErrorLogged(r, "Le champs doit être renseigné: AR_FOU_DIS")
+
+    def test_dates_install(self): 
+        """ Dates d'installation 
+        Vérifie que les dates d'installation sont renseignées pour les équipements en service """ 
+
+        # cas initial: valide
+        r = self.run_test("test_dates_install")
+
+        self.assertEqual(r.title, "Dates d'installation")
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.cables[0].CA_STATUT = "REC"
+        self.checker.cables[0].CA_DATE_IN = ""
+        
+        r = self.run_test("test_dates_install", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "Date d'installation \(CA_DATE_IN\) manquante")
+
+    def test_largeur_tranchees(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_largeur_tranchees")
+
+        self.assertEqual(r.title, "Tranchées: Dimensions")
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.tranchees[0].TR_MOD_POS = "TRANCHEE"
+        self.checker.tranchees[0].TR_LARG = 0
+        
+        r = self.run_test("test_largeur_tranchees", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "La largeur de la tranchée doit être supérieure à 0")
+        
+    def test_prop_gest(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_prop_gest")
+
+        self.assertEqual(r.title, "Propriétaires / Gestionnaires")
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.arteres[0].AR_PRO_FOU = "ORANGE"
+        self.checker.arteres[0].AR_GEST_FO = "ERDF"
+        
+        r = self.run_test("test_prop_gest", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "Propriétaire: ORANGE, gestionnaire\(s\) possible\(s\): ORANGE \(renseigné: ERDF\)")
+        
+        
+    def test_comments(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_comments")
+
+        self.assertEqual(r.title, "Présence de commentaires")
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.equipements[0].EQ_STATUT = "APD"
+        self.checker.equipements[0].EQ_COMMENT = ""
+        
+        r = self.run_test("test_comments", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "L'equipement n'est pas en REC, un commentaire devrait en préciser la raison")
+        
     def test_dimensions_fourreaux(self):
     def test_dimensions_fourreaux(self):
         
         
         # cas initial: valide
         # cas initial: valide
@@ -441,10 +526,10 @@ class Test(SchemaTest):
         # noms equipement / zapbo incoherents
         # noms equipement / zapbo incoherents
         eq = next(e for e in self.checker.equipements if e.EQ_TYPE == "PBO")
         eq = next(e for e in self.checker.equipements if e.EQ_TYPE == "PBO")
         
         
-        eq.EQ_NOM = "%__#123456789#__%"
+        eq.EQ_NOM = "babidiboo"
         r = self.run_test("test_pbos", True)
         r = self.run_test("test_pbos", True)
         self.assertFailure(r)
         self.assertFailure(r)
-        self.assertErrorLogged(r, "Le nom du PBO ne coincide avec le nom d'aucune des ZAPBO qui le contiennent")
+        self.assertErrorLogged(r, "Le nom de la PBO ne coincide avec le nom d'aucune des ZAPBO qui le contiennent")
         
         
         # equipement hors zapbo
         # equipement hors zapbo
         _ini_geom = eq.noeud._feature.geometry()
         _ini_geom = eq.noeud._feature.geometry()

+ 126 - 1
test/test_mn2_rec.py

@@ -397,6 +397,131 @@ class Test(SchemaTest):
         r = self.run_test("test_artere_cable", True)
         r = self.run_test("test_artere_cable", True)
         self.assertFailure(r)
         self.assertFailure(r)
         self.assertErrorLogged(r, "Artère ou portion d'artère sans cable")
         self.assertErrorLogged(r, "Artère ou portion d'artère sans cable")
+
+    def test_boites(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_boites")
+
+        self.assertEqual(r.title, 'Données des boites')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+    
+        # erreur topo
+        self.checker.equipements[0].EQ_TYPE = "PBO"
+        self.checker.equipements[0].EQ_DATE_IN = "01/01/2019"
+        
+        del self.checker.equipements[0].__dict__["EQ_CAPFO"]
+        self.checker.equipements[0].EQ_NBMXEQ = ""
+        
+        r = self.run_test("test_boites", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "Le champs est obligatoire: EQ_CAPFO")
+        self.assertErrorLogged(r, "Le champs doit être renseigné: EQ_NBMXEQ")
+
+        self.checker.equipements[0].EQ_CAPFO = 1
+        self.checker.equipements[0].EQ_NBMXEQ = 1
+        
+        self.checker.equipements[0].EQ_TYPE = "BPE"
+        self.checker.equipements[0].noeud.NO_TYPE_PH = "POTEAU"
+        
+        r = self.run_test("test_boites", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "Une BPE ne peut pas être sur un poteau")
+        
+        self.checker.equipements[0].EQ_TYPE = "PBO"
+        self.checker.equipements[0].noeud.NO_TYPE_PH = "POTEAU"
+        self.checker.equipements[0].EQ_HAUT = 1
+        
+        r = self.run_test("test_boites", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "PBO sur poteau: La hauteur doit être comprise entre 2.40m et 4.00m")
+
+    def test_arteres_enterrees(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_arteres_enterrees")
+
+        self.assertEqual(r.title, 'Données des artères enterrées')
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.arteres[0].AR_TYPE_FO = "PVC"
+        
+        del self.checker.arteres[0].__dict__["AR_NB_FOUR"]
+        self.checker.arteres[0].AR_FOU_DIS = ""
+        
+        r = self.run_test("test_arteres_enterrees", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "Le champs est obligatoire: AR_NB_FOUR")
+        self.assertErrorLogged(r, "Le champs doit être renseigné: AR_FOU_DIS")
+
+    def test_dates_install(self): 
+        """ Dates d'installation 
+        Vérifie que les dates d'installation sont renseignées pour les équipements en service """ 
+
+        # cas initial: valide
+        r = self.run_test("test_dates_install")
+
+        self.assertEqual(r.title, "Dates d'installation")
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.cables[0].CA_STATUT = "EN SERVICE"
+        self.checker.cables[0].CA_DATE_IN = ""
+        
+        r = self.run_test("test_dates_install", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "Date d'installation \(CA_DATE_IN\) manquante")
+
+    def test_largeur_tranchees(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_largeur_tranchees")
+
+        self.assertEqual(r.title, "Tranchées: Dimensions")
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.tranchees[0].TR_MOD_POS = "TRANCHEE"
+        self.checker.tranchees[0].TR_LARG = 0
+        
+        r = self.run_test("test_largeur_tranchees", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "La largeur de la tranchée doit être supérieure à 0")
+        
+    def test_prop_gest(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_prop_gest")
+
+        self.assertEqual(r.title, "Propriétaires / Gestionnaires")
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.arteres[0].AR_PRO_FOU = "ORANGE"
+        self.checker.arteres[0].AR_GEST_FO = "ERDF"
+        
+        r = self.run_test("test_prop_gest", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "Propriétaire: ORANGE, gestionnaire\(s\) possible\(s\): ORANGE \(renseigné: ERDF\)")
+        
+        
+    def test_comments(self):
+        
+        # cas initial: valide
+        r = self.run_test("test_comments")
+
+        self.assertEqual(r.title, "Présence de commentaires")
+        self.assertSuccess(r)
+        self.assertEqual(len(r.errors), 0)
+        
+        self.checker.equipements[0].EQ_STATUT = "EN ETUDE"
+        self.checker.equipements[0].EQ_COMMENT = ""
+        
+        r = self.run_test("test_comments", True)
+        self.assertFailure(r)
+        self.assertErrorLogged(r, "L'equipement n'est pas en REC, un commentaire devrait en préciser la raison")
         
         
     def test_dimensions_fourreaux(self):
     def test_dimensions_fourreaux(self):
         
         
@@ -430,7 +555,7 @@ class Test(SchemaTest):
         eq.EQ_CODE = "%__#123456789#__%"
         eq.EQ_CODE = "%__#123456789#__%"
         r = self.run_test("test_pbos", True)
         r = self.run_test("test_pbos", True)
         self.assertFailure(r)
         self.assertFailure(r)
-        self.assertErrorLogged(r, "Le nom du PBO ne coincide avec le nom d'aucune des ZAPBO qui le contiennent")
+        self.assertErrorLogged(r, "Le nom de la PBO ne coincide avec le nom d'aucune des ZAPBO qui le contiennent")
         
         
         # equipement hors zapbo
         # equipement hors zapbo
         _ini_geom = eq.noeud._feature.geometry()
         _ini_geom = eq.noeud._feature.geometry()

+ 11 - 1
ui/dlg_contact.py

@@ -12,8 +12,9 @@ from PyQt5 import uic
 from PyQt5.QtCore import Qt
 from PyQt5.QtCore import Qt
 from PyQt5.QtGui import QIcon, QPixmap
 from PyQt5.QtGui import QIcon, QPixmap
 from PyQt5.QtWidgets import QTextBrowser, QApplication
 from PyQt5.QtWidgets import QTextBrowser, QApplication
+import coverage
 
 
-from core.constants import MAIN, LOGDIR, RSCDIR, CONTACT, TESTDIR
+from core.constants import MAIN, LOGDIR, RSCDIR, CONTACT, TESTDIR, COVERAGE_DIR
 from path import Path
 from path import Path
 
 
 
 
@@ -60,6 +61,10 @@ class DlgContact(QtWidgets.QDialog):
             subprocess.Popen(["open", path])
             subprocess.Popen(["open", path])
 
 
     def run_tests(self):
     def run_tests(self):
+        
+        cov = coverage.Coverage()
+        cov.start()
+       
         _initial_project = QgsProject.instance().absoluteFilePath()
         _initial_project = QgsProject.instance().absoluteFilePath()
         if _initial_project:
         if _initial_project:
             QgsProject.instance().write(_initial_project)
             QgsProject.instance().write(_initial_project)
@@ -73,6 +78,11 @@ class DlgContact(QtWidgets.QDialog):
             runner = unittest.TextTestRunner(stream=f)
             runner = unittest.TextTestRunner(stream=f)
             runner.run(tests)
             runner.run(tests)
 
 
+        cov.stop()
+        cov.save()
+        COVERAGE_DIR.mkdir_p()   
+        cov.html_report(directory=COVERAGE_DIR)
+
         if _initial_project:
         if _initial_project:
             QgsProject.instance().clear()
             QgsProject.instance().clear()
             QgsProject.instance().read(_initial_project)
             QgsProject.instance().read(_initial_project)