J'ai vraiment du mal à écrire des tests unitaires efficaces pour un grand projet Django. J'ai une couverture de test raisonnablement bonne, mais je me suis rendu compte que les tests que j'ai écrits sont définitivement des tests d'intégration / d'acceptation, pas des tests unitaires du tout, et j'ai des parties critiques de mon application qui ne sont pas testées efficacement. Je veux résoudre ce problème dès que possible.
Voici mon problème. Mon schéma est profondément relationnel et fortement axé sur le temps, ce qui donne à mon objet modèle un couplage interne élevé et beaucoup d'état. Beaucoup de mes méthodes de modèle interrogent en fonction des intervalles de temps, et j'ai beaucoup de auto_now_add
choses à faire dans les champs horodatés. Prenez par exemple une méthode qui ressemble à ceci:
def summary(self, startTime=None, endTime=None):
# ... logic to assign a proper start and end time
# if none was provided, probably using datetime.now()
objects = self.related_model_set.manager_method.filter(...)
return sum(object.key_method(startTime, endTime) for object in objects)
Comment approche-t-on un test comme celui-ci?
Voici où j'en suis jusqu'à présent. Il me semble que l'objectif de test unitaire devrait être donné un comportement moqué by key_method
sur ses arguments, est-il summary
correctement filtré / agrégé pour produire un résultat correct?
Se moquer de datetime.now () est assez simple, mais comment puis-je me moquer du reste du comportement?
- Je pourrais utiliser des appareils, mais j'ai entendu des avantages et des inconvénients d'utiliser des appareils pour construire mes données (la mauvaise maintenabilité étant un con qui frappe chez moi).
- Je pourrais également configurer mes données via l'ORM, mais cela peut être limitant, car je dois également créer des objets associés. Et l'ORM ne vous permet pas de jouer avec les
auto_now_add
champs manuellement. - Se moquer de l'ORM est une autre option, mais non seulement il est difficile de se moquer des méthodes ORM profondément imbriquées, mais la logique dans le code ORM se moque du test, et la moquerie semble rendre le test vraiment dépendant des internes et des dépendances du fonction sous test.
Les écrous les plus difficiles à casser semblent être les fonctions comme celle-ci, qui reposent sur quelques couches de modèles et de fonctions de niveau inférieur et sont très dépendantes du temps, même si ces fonctions peuvent ne pas être super compliquées. Mon problème global est que, peu importe la façon dont je semble le découper, mes tests semblent beaucoup plus complexes que les fonctions qu'ils testent.