test_mn2_rec.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. '''
  2. @author: olivier.massot, janv. 2019
  3. '''
  4. import logging
  5. import re
  6. from path import Path
  7. from MnCheck.core import mncheck
  8. from MnCheck.core.checking import SUCCESS, FAILURE, ERROR
  9. from qgis.core import QgsCoordinateReferenceSystem, QgsGeometry, QgsPointXY #@UnresolvedImport
  10. from MnCheck.test._base import SchemaTest
  11. logger = logging.getLogger("mncheck")
  12. class Test(SchemaTest):
  13. SCHEMA_NAME = "mn2_rec"
  14. PROJECT_FILE = Path(__file__).parent / 'projects' / 'mn2_rec' / '1_valid' / '1_valid.qgz'
  15. def setUp(self):
  16. SchemaTest.setUp(self)
  17. self.schema = mncheck.get_schema(self.SCHEMA_NAME)
  18. if not self.schema.checkers:
  19. raise AttributeError("Aucun testeur trouvé dans le schéma")
  20. self.checker = self.schema.checkers[0]()
  21. def run_test(self, test_name, dry=False):
  22. results = self.checker.run(test_name, dry)
  23. if len(results) == 0:
  24. raise Exception("No result for test")
  25. elif len(results) > 1:
  26. raise Exception("More than one result from test")
  27. return results[0]
  28. def assertSuccess(self, r):
  29. if not r.status == SUCCESS:
  30. raise AssertionError("Le test a échoué")
  31. def assertFailure(self, r):
  32. if not r.status == FAILURE:
  33. raise AssertionError("Le test n'aurait pas dû réussir")
  34. def assertError(self, r):
  35. if not r.status == ERROR:
  36. raise AssertionError("Le test n'a pas levé d'erreur")
  37. def assertErrorLogged(self, result, err_msg):
  38. if not any((re.fullmatch(err_msg, err.message) for err in result.errors)):
  39. print(result.errors)
  40. raise AssertionError("Error was not logged: {}".format(err_msg))
  41. def test_load_layers(self):
  42. # cas initial: valide
  43. r = self.run_test("test_load_layers")
  44. self.assertEqual(r.title, 'Chargement des données')
  45. self.assertSuccess(r)
  46. self.assertEqual(len(r.errors), 0)
  47. # une couche manquante et une pk manquante
  48. _pk_ini = self.schema.Cable.pk
  49. try:
  50. self.schema.Artere.layer = None
  51. self.schema.Cable.pk = "not_a_qgis_field"
  52. r = self.run_test("test_load_layers", True)
  53. self.assertFailure(r)
  54. self.assertErrorLogged(r, ".*Couche manquante.*")
  55. self.assertErrorLogged(r, ".*Clef primaire manquante.*")
  56. finally:
  57. self.schema.Cable.pk = _pk_ini
  58. def test_scr(self):
  59. # cas initial: valide
  60. r = self.run_test("test_scr")
  61. self.assertEqual(r.title, 'Contrôle des projections')
  62. self.assertSuccess(r)
  63. self.assertEqual(len(r.errors), 0)
  64. # mauvaise projection
  65. crs = QgsCoordinateReferenceSystem()
  66. crs.createFromSrid(4473)
  67. self.schema.Artere.layer.setCrs(crs)
  68. r = self.run_test("test_scr", True)
  69. self.assertFailure(r)
  70. self.assertErrorLogged(r, f"Mauvaise projection.*")
  71. def test_structure_arteres(self):
  72. # cas initial: valide
  73. r = self.run_test("test_structure_arteres")
  74. self.assertEqual(r.title, 'Structure des données: Artères')
  75. self.assertSuccess(r)
  76. self.assertEqual(len(r.errors), 0)
  77. # valeur non autorisée
  78. self.checker.arteres[0].AR_ID_INSE = "invalid"
  79. r = self.run_test("test_structure_arteres", True)
  80. self.assertFailure(r)
  81. def test_structure_cables(self):
  82. # cas initial: valide
  83. r = self.run_test("test_structure_cables")
  84. self.assertEqual(r.title, 'Structure des données: Cables')
  85. self.assertSuccess(r)
  86. self.assertEqual(len(r.errors), 0)
  87. # valeur non autorisée
  88. self.checker.cables[0].CA_TYPE = "invalid"
  89. r = self.run_test("test_structure_cables", True)
  90. self.assertFailure(r)
  91. def test_structure_equipements(self):
  92. # cas initial: valide
  93. r = self.run_test("test_structure_equipements")
  94. self.assertEqual(r.title, 'Structure des données: Equipements')
  95. self.assertSuccess(r)
  96. self.assertEqual(len(r.errors), 0)
  97. # valeur non autorisée
  98. self.checker.equipements[0].EQ_TYPE = "invalid"
  99. r = self.run_test("test_structure_equipements", True)
  100. self.assertFailure(r)
  101. def test_structure_noeuds(self):
  102. # cas initial: valide
  103. r = self.run_test("test_structure_noeuds")
  104. self.assertEqual(r.title, 'Structure des données: Noeuds')
  105. self.assertSuccess(r)
  106. self.assertEqual(len(r.errors), 0)
  107. # valeur non autorisée
  108. self.checker.noeuds[0].NO_ID_INSE = "invalid"
  109. r = self.run_test("test_structure_noeuds", True)
  110. self.assertFailure(r)
  111. def test_structure_tranchees(self):
  112. # cas initial: valide
  113. r = self.run_test("test_structure_tranchees")
  114. self.assertEqual(r.title, 'Structure des données: Tranchées')
  115. self.assertSuccess(r)
  116. self.assertEqual(len(r.errors), 0)
  117. # valeur non autorisée
  118. self.checker.tranchees[0].TR_REVET = "invalid"
  119. r = self.run_test("test_structure_tranchees", True)
  120. self.assertFailure(r)
  121. def test_structure_zapbos(self):
  122. # cas initial: valide
  123. r = self.run_test("test_structure_zapbos")
  124. self.assertEqual(r.title, 'Structure des données: Zapbos')
  125. self.assertSuccess(r)
  126. self.assertEqual(len(r.errors), 0)
  127. # valeur non autorisée
  128. self.checker.zapbos[0].STATUT = "invalid"
  129. r = self.run_test("test_structure_zapbos", True)
  130. self.assertFailure(r)
  131. def test_geometry_validity(self):
  132. # cas initial: valide
  133. r = self.run_test("test_geometry_validity")
  134. self.assertEqual(r.title, 'Contrôle de la validité des géométries')
  135. self.assertSuccess(r)
  136. self.assertEqual(len(r.errors), 0)
  137. # géométrie invalide
  138. self.checker.arteres[0]._feature.setGeometry(QgsGeometry())
  139. r = self.run_test("test_geometry_validity", True)
  140. self.assertFailure(r)
  141. self.assertErrorLogged(r, "La géométrie de l'objet est invalide")
  142. def test_geometry_type(self):
  143. # cas initial: valide
  144. r = self.run_test("test_geometry_type")
  145. self.assertEqual(r.title, 'Contrôle des types de géométries')
  146. self.assertSuccess(r)
  147. self.assertEqual(len(r.errors), 0)
  148. # type de géométrie invalide
  149. self.checker.arteres[0]._feature.setGeometry(QgsGeometry())
  150. r = self.run_test("test_geometry_type", True)
  151. self.assertFailure(r)
  152. self.assertErrorLogged(r, "Type de géométrie invalide.*")
  153. def test_bounding_box(self):
  154. # cas initial: valide
  155. r = self.run_test("test_bounding_box")
  156. self.assertEqual(r.title, 'Contrôle des emprises')
  157. self.assertSuccess(r)
  158. self.assertEqual(len(r.errors), 0)
  159. # hors de l'emprise
  160. self.checker.noeuds[0]._feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0,0)))
  161. r = self.run_test("test_bounding_box", True)
  162. self.assertFailure(r)
  163. self.assertErrorLogged(r, "Hors de l'emprise autorisée")
  164. def test_duplicates(self):
  165. # cas initial: valide
  166. r = self.run_test("test_duplicates")
  167. self.assertEqual(r.title, 'Recherche de doublons')
  168. self.assertSuccess(r)
  169. self.assertEqual(len(r.errors), 0)
  170. # cas de doublon
  171. self.checker.noeuds[0].NO_NOM = self.checker.noeuds[1].NO_NOM
  172. r = self.run_test("test_duplicates", True)
  173. self.assertFailure(r)
  174. self.assertErrorLogged(r, "Doublons dans le champs NO_NOM")
  175. def test_constraints_arteres_noeuds(self):
  176. # cas initial: valide
  177. r = self.run_test("test_constraints_arteres_noeuds")
  178. self.assertEqual(r.title, 'Application des contraintes: Artères / Noeuds')
  179. self.assertSuccess(r)
  180. self.assertEqual(len(r.errors), 0)
  181. # contrainte invalide
  182. self.checker.arteres[0].noeud_a = None
  183. r = self.run_test("test_constraints_arteres_noeuds", True)
  184. self.assertFailure(r)
  185. self.assertErrorLogged(r, "Le noeud lié '.+' n'existe pas")
  186. def test_constraints_cables_equipements(self):
  187. # cas initial: valide
  188. r = self.run_test("test_constraints_cables_equipements")
  189. self.assertEqual(r.title, 'Application des contraintes: Equipements / Cables')
  190. self.assertSuccess(r)
  191. self.assertEqual(len(r.errors), 0)
  192. # contrainte invalide
  193. self.checker.cables[0].equipement_a = None
  194. r = self.run_test("test_constraints_cables_equipements", True)
  195. self.assertFailure(r)
  196. self.assertErrorLogged(r, "L'équipement lié '.+' n'existe pas*")
  197. def test_constraints_cables_equipements_b(self):
  198. # cas initial: valide
  199. r = self.run_test("test_constraints_cables_equipements_b")
  200. self.assertEqual(r.title, 'Application des contraintes: Equipements B')
  201. self.assertSuccess(r)
  202. self.assertEqual(len(r.errors), 0)
  203. # contrainte invalide
  204. for cable in self.checker.cables:
  205. cable.CA_EQ_B = ""
  206. r = self.run_test("test_constraints_cables_equipements_b", True)
  207. self.assertFailure(r)
  208. self.assertErrorLogged(r, "L'equipement '.+' n'est l'équipement B d'aucun cable.+")
  209. def test_constraints_equipements_noeuds(self):
  210. # cas initial: valide
  211. r = self.run_test("test_constraints_equipements_noeuds")
  212. self.assertEqual(r.title, 'Application des contraintes: Noeuds / Equipements')
  213. self.assertSuccess(r)
  214. self.assertEqual(len(r.errors), 0)
  215. # contrainte invalide
  216. self.checker.equipements[0].noeud = None
  217. r = self.run_test("test_constraints_equipements_noeuds", True)
  218. self.assertFailure(r)
  219. self.assertErrorLogged(r, "Le noeud lié '.+' n'existe pas")
  220. def test_graphic_duplicates(self):
  221. # cas initial: valide
  222. r = self.run_test("test_graphic_duplicates")
  223. self.assertEqual(r.title, 'Recherche de doublons graphiques')
  224. self.assertSuccess(r)
  225. self.assertEqual(len(r.errors), 0)
  226. # doublon graphique
  227. self.checker.noeuds[0]._feature.setGeometry(self.checker.noeuds[1]._feature.geometry())
  228. r = self.run_test("test_graphic_duplicates", True)
  229. self.assertFailure(r)
  230. self.assertErrorLogged(r, "Une entité graphique est dupliquée")
  231. def test_positions_noeuds(self):
  232. # cas initial: valide
  233. r = self.run_test("test_positions_noeuds")
  234. self.assertEqual(r.title, 'Topologie: Noeuds / Artères')
  235. self.assertSuccess(r)
  236. self.assertEqual(len(r.errors), 0)
  237. # erreur topo
  238. self.checker.arteres[0].noeud_b._feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0,0)))
  239. r = self.run_test("test_positions_noeuds", True)
  240. self.assertFailure(r)
  241. self.assertErrorLogged(r, "Le noeud B n'est pas aux coordonnées attendues.*")
  242. def test_positions_equipements(self):
  243. # cas initial: valide
  244. r = self.run_test("test_positions_equipements")
  245. self.assertEqual(r.title, 'Topologie: Equipements / Cables')
  246. self.assertSuccess(r)
  247. self.assertEqual(len(r.errors), 0)
  248. # erreur topo
  249. self.checker.cables[0].equipement_b.noeud._feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0,0)))
  250. r = self.run_test("test_positions_equipements", True)
  251. self.assertFailure(r)
  252. self.assertErrorLogged(r, "L'équipement B n'est pas aux coordonnées attendues.*")
  253. def test_tranchee_artere(self):
  254. # cas initial: valide
  255. r = self.run_test("test_tranchee_artere")
  256. self.assertEqual(r.title, 'Topologie: Tranchées / Artères')
  257. self.assertSuccess(r)
  258. self.assertEqual(len(r.errors), 0)
  259. # erreur topo
  260. new_geom = self.checker.tranchees[0]._feature.geometry()
  261. new_geom.translate(10000, 10000)
  262. self.checker.tranchees[0]._feature.setGeometry(new_geom)
  263. r = self.run_test("test_tranchee_artere", True)
  264. self.assertFailure(r)
  265. self.assertErrorLogged(r, "Tranchée ou portion de tranchée sans artère")
  266. def test_cable_artere(self):
  267. # cas initial: valide
  268. r = self.run_test("test_cable_artere")
  269. self.assertEqual(r.title, 'Topologie: Cables / Artères')
  270. self.assertSuccess(r)
  271. self.assertEqual(len(r.errors), 0)
  272. # erreur topo
  273. self.checker.cables[0].CA_COMMENT = ""
  274. new_geom = self.checker.cables[0]._feature.geometry()
  275. new_geom.translate(10000, 10000)
  276. self.checker.cables[0]._feature.setGeometry(new_geom)
  277. r = self.run_test("test_cable_artere", True)
  278. self.assertFailure(r)
  279. self.assertErrorLogged(r, "Cable ou portion de cable sans artère")
  280. def test_artere_cable(self):
  281. # cas initial: valide
  282. r = self.run_test("test_artere_cable")
  283. self.assertEqual(r.title, 'Topologie: Artères / Cables')
  284. self.assertSuccess(r)
  285. self.assertEqual(len(r.errors), 0)
  286. # erreur topo
  287. self.checker.arteres[0].AR_COMMENT = ""
  288. new_geom = self.checker.arteres[0]._feature.geometry()
  289. new_geom.translate(10000, 10000)
  290. self.checker.arteres[0]._feature.setGeometry(new_geom)
  291. r = self.run_test("test_artere_cable", True)
  292. self.assertFailure(r)
  293. self.assertErrorLogged(r, "Artère ou portion d'artère sans cable")
  294. def test_boites(self):
  295. # cas initial: valide
  296. r = self.run_test("test_boites")
  297. self.assertEqual(r.title, 'Données des boites')
  298. self.assertSuccess(r)
  299. self.assertEqual(len(r.errors), 0)
  300. # erreur topo
  301. self.checker.equipements[0].EQ_TYPE = "PBO"
  302. self.checker.equipements[0].EQ_DATE_IN = "01/01/2019"
  303. del self.checker.equipements[0].__dict__["EQ_CAPFO"]
  304. self.checker.equipements[0].EQ_NBMXEQ = ""
  305. r = self.run_test("test_boites", True)
  306. self.assertFailure(r)
  307. self.assertErrorLogged(r, "Le champs est obligatoire: EQ_CAPFO")
  308. self.assertErrorLogged(r, "Le champs doit être renseigné: EQ_NBMXEQ")
  309. self.checker.equipements[0].EQ_CAPFO = 1
  310. self.checker.equipements[0].EQ_NBMXEQ = 1
  311. self.checker.equipements[0].EQ_TYPE = "BPE"
  312. self.checker.equipements[0].noeud.NO_TYPE_PH = "POTEAU"
  313. r = self.run_test("test_boites", True)
  314. self.assertFailure(r)
  315. self.assertErrorLogged(r, "Une BPE ne peut pas être sur un poteau")
  316. self.checker.equipements[0].EQ_TYPE = "PBO"
  317. self.checker.equipements[0].noeud.NO_TYPE_PH = "POTEAU"
  318. self.checker.equipements[0].EQ_HAUT = 1
  319. r = self.run_test("test_boites", True)
  320. self.assertFailure(r)
  321. self.assertErrorLogged(r, "PBO sur poteau: La hauteur doit être comprise entre 2.40m et 4.00m")
  322. def test_arteres_enterrees(self):
  323. # cas initial: valide
  324. r = self.run_test("test_arteres_enterrees")
  325. self.assertEqual(r.title, 'Données des artères enterrées')
  326. self.assertSuccess(r)
  327. self.assertEqual(len(r.errors), 0)
  328. self.checker.arteres[0].AR_TYPE_FO = "PVC"
  329. del self.checker.arteres[0].__dict__["AR_NB_FOUR"]
  330. self.checker.arteres[0].AR_FOU_DIS = ""
  331. r = self.run_test("test_arteres_enterrees", True)
  332. self.assertFailure(r)
  333. self.assertErrorLogged(r, "Le champs est obligatoire: AR_NB_FOUR")
  334. self.assertErrorLogged(r, "Le champs doit être renseigné: AR_FOU_DIS")
  335. def test_dates_install(self):
  336. """ Dates d'installation
  337. Vérifie que les dates d'installation sont renseignées pour les équipements en service """
  338. # cas initial: valide
  339. r = self.run_test("test_dates_install")
  340. self.assertEqual(r.title, "Dates d'installation")
  341. self.assertSuccess(r)
  342. self.assertEqual(len(r.errors), 0)
  343. self.checker.cables[0].CA_STATUT = "EN SERVICE"
  344. self.checker.cables[0].CA_DATE_IN = ""
  345. r = self.run_test("test_dates_install", True)
  346. self.assertFailure(r)
  347. self.assertErrorLogged(r, "Date d'installation \(CA_DATE_IN\) manquante")
  348. def test_largeur_tranchees(self):
  349. # cas initial: valide
  350. r = self.run_test("test_largeur_tranchees")
  351. self.assertEqual(r.title, "Tranchées: Dimensions")
  352. self.assertSuccess(r)
  353. self.assertEqual(len(r.errors), 0)
  354. self.checker.tranchees[0].TR_MOD_POS = "TRANCHEE"
  355. self.checker.tranchees[0].TR_LARG = 0
  356. r = self.run_test("test_largeur_tranchees", True)
  357. self.assertFailure(r)
  358. self.assertErrorLogged(r, "La largeur de la tranchée doit être supérieure à 0")
  359. def test_prop_gest(self):
  360. # cas initial: valide
  361. r = self.run_test("test_prop_gest")
  362. self.assertEqual(r.title, "Propriétaires / Gestionnaires")
  363. self.assertSuccess(r)
  364. self.assertEqual(len(r.errors), 0)
  365. self.checker.arteres[0].AR_PRO_FOU = "ORANGE"
  366. self.checker.arteres[0].AR_GEST_FO = "ERDF"
  367. r = self.run_test("test_prop_gest", True)
  368. self.assertFailure(r)
  369. self.assertErrorLogged(r, "Propriétaire: ORANGE, gestionnaire\(s\) possible\(s\): ORANGE \(renseigné: ERDF\)")
  370. def test_comments(self):
  371. # cas initial: valide
  372. r = self.run_test("test_comments")
  373. self.assertEqual(r.title, "Présence de commentaires")
  374. self.assertSuccess(r)
  375. self.assertEqual(len(r.errors), 0)
  376. self.checker.equipements[0].EQ_STATUT = "EN ETUDE"
  377. self.checker.equipements[0].EQ_COMMENT = ""
  378. r = self.run_test("test_comments", True)
  379. self.assertFailure(r)
  380. self.assertErrorLogged(r, "L'equipement n'est pas en REC, un commentaire devrait en préciser la raison")
  381. def test_dimensions_fourreaux(self):
  382. # cas initial: valide
  383. r = self.run_test("test_dimensions_fourreaux")
  384. self.assertEqual(r.title, 'Dimensions logiques: fourreaux')
  385. self.assertSuccess(r)
  386. self.assertEqual(len(r.errors), 0)
  387. # nombre de fourreaux incohérent
  388. self.checker.arteres[0].AR_FOU_DIS = 1000
  389. r = self.run_test("test_dimensions_fourreaux", True)
  390. self.assertFailure(r)
  391. self.assertErrorLogged(r, "Le nombre de fourreaux disponibles \(AR_FOU_DIS\) doit être inférieur au nombre total \(AR_NB_FOUR\)")
  392. self.checker.arteres[0].AR_FOU_DIS = 0
  393. def test_statuts(self):
  394. self.checker.cables[0].CA_STATUT = "EN SERVICE"
  395. self.checker.cables[0].equipement_a.EQ_STATUT = "EN ETUDE"
  396. r = self.run_test("test_statuts", True)
  397. self.assertFailure(r)
  398. self.assertErrorLogged(r, "Incohérence de statut entre le cable et son équipement A")
  399. def test_pbos(self):
  400. # cas initial: valide
  401. r = self.run_test("test_pbos")
  402. self.assertEqual(r.title, 'Topologie: PBO / ZAPBO')
  403. self.assertSuccess(r)
  404. self.assertEqual(len(r.errors), 0)
  405. # noms equipement / zapbo incoherents
  406. eq = next(e for e in self.checker.equipements if e.EQ_TYPE == "PBO")
  407. eq.EQ_CODE = "%__#123456789#__%"
  408. r = self.run_test("test_pbos", True)
  409. self.assertFailure(r)
  410. self.assertErrorLogged(r, "Le nom de la PBO ne coincide avec le nom d'aucune des ZAPBO qui le contiennent")
  411. # equipement hors zapbo
  412. _ini_geom = eq.noeud._feature.geometry()
  413. eq.noeud._feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(0,0)))
  414. r = self.run_test("test_pbos", True)
  415. self.assertFailure(r)
  416. self.assertErrorLogged(r, "Le PBO n'est contenu dans aucune ZAPBO")
  417. def test_zapbos_prises(self):
  418. # cas initial: valide
  419. r = self.run_test("test_zapbos_prises")
  420. self.assertEqual(r.title, 'Topologie: Zapbos / Prises')
  421. self.assertSuccess(r)
  422. self.assertEqual(len(r.errors), 0)
  423. # pas de prise dans la zapbo
  424. self.checker.prises = []
  425. new_geom = self.checker.zapbos[0]._feature.geometry()
  426. new_geom.translate(1000,1000)
  427. self.checker.zapbos[0]._feature.setGeometry(new_geom)
  428. r = self.run_test("test_zapbos_prises", True)
  429. self.assertFailure(r)
  430. self.assertErrorLogged(r, "La Zapbo ne contient aucune prise")
  431. # couche non chargée
  432. self.checker.prises = []
  433. self.schema.Prise.layer = None
  434. r = self.run_test("test_zapbos_prises", True)
  435. self.assertError(r)
  436. self.assertErrorLogged(r, "La couche des prises n'est pas chargée")
  437. def test_pbo_dimension(self):
  438. # cas initial: valide
  439. r = self.run_test("test_pbo_dimension")
  440. self.assertEqual(r.title, 'Dimensionnement des PBO')
  441. self.assertSuccess(r)
  442. self.assertEqual(len(r.errors), 0)
  443. # couche non chargée
  444. self.checker.prises = []
  445. self.schema.Prise.layer = None
  446. r = self.run_test("test_pbo_dimension", True)
  447. self.assertError(r)
  448. self.assertErrorLogged(r, "La couche des prises n'est pas chargée")