93 votes

Comment puis-je tester les messages Django?

Dans mon application django, je suis en train d'écrire un test unitaire qui effectue une action, puis vérifie les messages dans la réponse.

Pour autant que je sache, il n'est pas de bonne façon de le faire.

Je suis à l'aide de la CookieStorage méthode de stockage, et je voudrais faire quelque chose de semblable à la suivante:

    response = self.client.post('/do-something/', follow=True)
    self.assertEquals(response.context['messages'][0], "fail.")

Le problème, c'est tout ce que je reçois est de retour d'une

print response.context['messages']
<django.contrib.messages.storage.cookie.CookieStorage object at 0x3c55250>

Comment puis-je transformer cela en quelque chose d'utile, ou suis-je tout faux?

Merci, Daniel

133voto

daveoncode Points 4453

J'ai trouvé une approche vraiment facile:

 r = self.client.post('/foo/')
m = list(r.context['messages'])
self.assertEqual(len(m), 1)
self.assertEqual(str(m[0]), 'my message')
 

(J'utilise un serveur basé sur une session pour les messages)

19voto

stalemate Points 311

Cela fonctionne pour moi (affiche tous les messages):

 print [m.message for m in list(response.context['messages'])]
 

Voici également quelques méthodes utilitaires que j'ai dans une classe de test héritée de TestCase de Django. Si vous préférez les avoir comme fonctions, supprimez les arguments self et remplacez les arguments self.fail() par un raise .

 def assert_message_count(self, response, expect_num):
    """
    Asserts that exactly the given number of messages have been sent.
    """

    actual_num = len(response.context['messages'])
    if actual_num != expect_num:
        self.fail('Message count was %d, expected %d' %
            (actual_num, expect_num))

def assert_message_contains(self, response, text, level=None):
    """
    Asserts that there is exactly one message containing the given text.
    """

    messages = response.context['messages']

    matches = [m for m in messages if text in m.message]

    if len(matches) == 1:
        msg = matches[0]
        if level is not None and msg.level != level:
            self.fail('There was one matching message but with different'
                'level: %s != %s' % (msg.level, level))

        return

    elif len(matches) == 0:
        messages_str = ", ".join('"%s"' % m for m in messages)
        self.fail('No message contained text "%s", messages were: %s' %
            (text, messages_str))
    else:
        self.fail('Multiple messages contained text "%s": %s' %
            (text, ", ".join(('"%s"' % m) for m in matches)))

def assert_message_not_contains(self, response, text):
    """ Assert that no message contains the given text. """

    messages = response.context['messages']

    matches = [m for m in messages if text in m.message]

    if len(matches) > 0:
        self.fail('Message(s) contained text "%s": %s' %
            (text, ", ".join(('"%s"' % m) for m in matches)))
 

3voto

Manoj Govindan Points 24030

J'ai fait une expérience pour tester cela. J'ai remplacé le paramètre MESSAGE_STORAGE dans l'un de mes projets par 'django.contrib.messages.storage.cookie.CookieStorage' et exécuté un test que j'avais écrit pour vérifier la présence de messages. Ça a marché.

La principale différence avec ce que vous faisiez est la façon dont j'ai récupéré les messages. Voir ci-dessous:

 def test_message_sending(self):
    data = dict(...)
    response = self.client.post(reverse('my_view'), data)
    messages = self.user.get_and_delete_messages()

    self.assertTrue(messages)
    self.assertEqual('Hey there!', messages[0])
 

Cela peut valoir la peine d'essayer.

0voto

Marco Fucci Points 325

Version simplifiée de l'impasse:

 class TestCaseMessagesMixture(object):
    def assertMessageCount(self, response, expect_num):
        """
        Asserts that exactly the given number of messages have been sent.
        """

        actual_num = len(response.context['messages'])
        if actual_num != expect_num:
            self.fail('Message count was %d, expected %d' %
                    (actual_num, expect_num)
                )

    def assertMessageEqual(self, response, text):
        """
        Asserts that the response includes the message text.
        """

        messages = [m.message for m in response.context['messages']]

        if text not in messages:
            self.fail(
                'No message with text "%s", messages were: %s' % 
                    (text, messages)
                )

    def assertMessageNotEqual(self, response, text):
        """
        Asserts that the response does not include the message text.
        """

        messages = [m.message for m in response.context['messages']]

        if text in messages:
            self.fail(
                'Message with text "%s" found, messages were: %s' % 
                    (text, messages)
                )
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X