Meilleure doc (j'espère !)

This commit is contained in:
Ludovic Stephan 2020-05-10 23:58:13 +02:00
parent 88c9187e2e
commit b1c69eddb5

View file

@ -197,75 +197,68 @@ class TestCaseMixin:
self.assertEqual(actual, expected) self.assertEqual(actual, expected)
class ViewTestCaseMixin(TestCaseMixin): class ViewTestCaseMixin(TestCaseMixin):
""" """
TestCase extension to ease tests of kfet views. Utilitaire pour automatiser certains tests sur les vues Django.
Création d'utilisateurs
------------------------
# Données de base
On crée dans tous les cas deux utilisateurs : un utilisateur normal "user",
et un superutilisateur "root", avec un mot de passe identique au username.
Urls concerns # Accès et utilisateurs supplémentaires
------------- Les utilisateurs créés sont accessibles dans le dict `self.users`, qui associe
un label à une instance de User.
# Basic usage Pour rajouter des utilisateurs supplémentaires (et s'assurer qu'ils sont
disponibles dans `self.users`), on peut redéfinir la fonction `get_users_extra()`,
qui doit renvoyer aussi un dict <label: User instance>.
Attributes: Misc QoL
url_name (str): Name of view under test, as given to 'reverse' ------------------------
function. Pour éviter une erreur de login (puisque les messages de Django ne sont pas
url_args (list, optional): Will be given to 'reverse' call. disponibles), les messages de bienvenue de GestioCOF sont patchés.
url_kwargs (dict, optional): Same. Un attribut `self.now` est fixé au démarrage, pour être donné comme valeur
url_expcted (str): What 'reverse' should return given previous de retour à un patch local de `django.utils.timezone.now`. Cela permet de
attributes. tester des dates/heures de manière robuste.
View url can then be accessed at the 'url' attribute. Test d'URLS
------------------------
# Advanced usage # Usage basique
Teste que l'URL générée par `reverse` correspond bien à l'URL théorique.
Attributs liés :
- `url_name` : nom de l'URL qui sera donné à `reverse`,
- `url_expected` : URL attendue en retour.
- (optionnels) `url_args` et `url_kwargs` : arguments de l'URL pour `reverse`.
If multiple combinations of url name, args, kwargs can be used for a view, # Usage avancé
it is possible to define 'urls_conf' attribute. It must be a list whose On peut tester plusieurs URLs pour une même vue, en redéfinissant la fonction
each item is a dict defining arguments for 'reverse' call ('name', 'args', `urls_conf()`. Cette fonction doit retourner une liste de dicts, avec les clés
'kwargs' keys) and its expected result ('expected' key). suivantes : `name`, `args`, `kwargs`, `expected`.
The reversed urls can be accessed at the 't_urls' attribute. # Accès aux URLs générées
Dans le cas d'usage basique, l'attribut `self.url` contient l'URL de la vue testée
(telle que renvoyée par `reverse()`). Si plusieurs URLs sont définies dans
`urls_conf()`, elles sont accessibles par la suite dans `self.reversed_urls`.
Authentification
------------------------
Si l'attribut `auth_user` est dans `self.users`, l'utilisateur correspondant
est authentifié avant chaque test (cela n'empêche bien sûr pas de login un autre
utilisateur à la main).
Users concerns Test de restrictions d'accès
-------------- ------------------------
L'utilitaire vérifie automatiquement que certains utilisateurs n'ont pas accès à la
During setup, the following users are created: vue. Plus spécifiquement, sont testés toutes les méthodes dans `self.http_methods`
- 'user': a basic user without any permission, et tous les utilisateurs dans `self.auth_forbidden`. Pour rappel, l'utilisateur
- 'root': a superuser, account trigramme: 200. `None` sert à tester la vue sans authentification.
Their password is their username. On peut donner des paramètres GET/POST/etc. aux tests en définissant un attribut
<methode>_data.
One can create additionnal users with 'get_users_extra' method, or prevent
these users to be created with 'get_users_base' method. See these two
methods for further informations.
By using 'register_user' method, these users can then be accessed at
'users' attribute by their label.
A user label can be given to 'auth_user' attribute. The related user is
then authenticated on self.client during test setup. Its value defaults to
'None', meaning no user is authenticated.
Automated tests
---------------
# Url reverse
Based on url-related attributes/properties, the test 'test_urls' checks
that expected url is returned by 'reverse' (once with basic url usage and
each for advanced usage).
# Forbidden responses
The 'test_forbidden' test verifies that each user, from labels of
'auth_forbidden' attribute, can't access the url(s), i.e. response should
be a 403, or a redirect to login view.
Tested HTTP requests are given by 'http_methods' attribute. Additional data
can be given by defining an attribute '<method(lowercase)>_data'.
TODO (?): faire pareil pour vérifier les GET/POST classiques (code 200)
""" """
url_name = None url_name = None
@ -280,19 +273,13 @@ class ViewTestCaseMixin(TestCaseMixin):
""" """
Warning: Do not forget to call super().setUp() in subclasses. Warning: Do not forget to call super().setUp() in subclasses.
""" """
# Signals handlers on login/logout send messages.
# Due to the way the Django' test Client performs login, this raise an
# error. As workaround, we mock the Django' messages module.
patcher_messages = mock.patch("gestioncof.signals.messages") patcher_messages = mock.patch("gestioncof.signals.messages")
patcher_messages.start() patcher_messages.start()
self.addCleanup(patcher_messages.stop) self.addCleanup(patcher_messages.stop)
# A test can mock 'django.utils.timezone.now' and give this as return
# value. E.g. it is useful if the test checks values of 'auto_now' or
# 'auto_now_add' fields.
self.now = timezone.now() self.now = timezone.now()
# Register of User instances.
self.users = {} self.users = {}
for label, user in dict(self.users_base, **self.users_extra).items(): for label, user in dict(self.users_base, **self.users_extra).items():