2017-02-26 1 views
0

Ich habe ein Python-Projekt, das auf einem bestimmten Modul, receivers.py, basiert, importiert wird.Wie schreibe ich einen Python-Test, der prüft, ob mein Code ein Modul importiert

Ich möchte einen Test schreiben, um sicherzustellen, dass es importiert wird, aber ich möchte auch andere Tests für das Verhalten des Codes innerhalb des Moduls schreiben.

Das Problem ist, dass, wenn ich in meinem Test-Suite alle Tests überall, die es automatisch importieren oder dann von receivers.py alles Patch wird das Modul importieren, möglicherweise macht den Test für den Import falsch passieren.

Irgendwelche Ideen?

. (Anmerkung: speziell das ist ein Django-Projekt)

+1

Das hört sich überhaupt nicht nach einem nützlichen Test an; sicherlich würde ein "ImportError" ausgelöst, wenn das Modul nicht verfügbar ist. Sagen Sie, dass der Import bedingt ist? –

+0

Das Problem, das ich zu lösen versuche, ist, dass es eine funktionale Anforderung gibt, dass Empfänger im normalen Betrieb des Web-Frameworks importiert werden. Dies ist die Art von Sache, die verpasst wird/anfällig für Regressionen ist. Mein Problem ist, dass gerade beim Testen der Empfänger bedeutet, dass sie während Tests importiert werden, selbst wenn sie in der Hauptcodebasis verpasst wurden. – seddonym

+2

Sie möchten also einen * Integrationstest *, einen, der den Code ausübt, der die Empfänger verwendet. –

Antwort

0

Ein (etwas unvollkommen) Art und Weise, es zu tun die folgende Testcase zu verwenden ist:

from django.test import TestCase 

class ReceiverConnectionTestCase(TestCase): 
    """TestCase that allows asserting that a given receiver is connected 
    to a signal. 

    Important: this will work correctly providing you: 
     1. Do not import or patch anything in the module containing the receiver 
      in any django.test.TestCase. 
     2. Do not import (except in the context of a method) the module 
      containing the receiver in any test module. 

    This is because as soon as you import/patch, the receiver will be connected 
    by your test and will be connected for the entire test suite run. 

    If you want to test the behaviour of the receiver, you may do this 
    providing it is a unittest.TestCase, and there is no import from the 
    receiver module in that test module. 

    Usage: 

     # myapp/receivers.py 
     from django.dispatch import receiver 
     from apples.signals import apple_eaten 
     from apples.models import Apple 

     @receiver(apple_eaten, sender=Apple) 
     def my_receiver(sender, **kwargs): 
      pass 


     # tests/integration_tests.py 
     from apples.signals import apple_eaten 
     from apples.models import Apple 

     class TestMyReceiverConnection(ReceiverConnectionTestCase): 
      def test_connection(self): 
       self.assert_receiver_is_connected(
        'myapp.receivers.my_receiver', 
        signal=apple_eaten, sender=Apple) 

    """ 
    def assert_receiver_is_connected(self, receiver_string, signal, sender): 
     receivers = signal._live_receivers(sender) 
     receiver_strings = [ 
      "{}.{}".format(r.__module__, r.__name__) for r in receivers] 
     if receiver_string not in receiver_strings: 
      raise AssertionError(
       '{} is not connected to signal.'.format(receiver_string)) 

Das funktioniert, weil Django django.test.TestCases läuft vor unittest.TestCases .

Verwandte Themen