2016-06-20 8 views
7

base alla disponibilità del pacchetto panda in ambiente di lavoro un metodo restituisce due diverse uscite:Come scrivere le unittests per una dipendenza opzionale in un pacchetto python?

  • A se panda è disponibile
  • Altrimenti un oggetto pandas.DataFramenumpy.recarray.

Come dovrei scrivere unittest per questa classe?

Una soluzione mi viene in mente è quello di scrivere i test per entrambi i casi (con e senza installazione panda) e saltare prova di conseguenza, qualcosa di simile:

try: 
    import pandas 
    HAVE_PANDAS = True 
except ImportError: 
    HAVE_PANDAS = False 

import unittest 

class TestClass(unittest.TestCase): 
    @unittest.skipUnless(HAVE_PANDAS, "requires pandas") 
    def tests_using_pandas(self): 
     # do something 
    @unittest.skipUnless(not HAVE_PANDAS, "doesn't require pandas") 
    def tests_without_pandas(self): 
     # do something 

Ma non mi piace questa soluzione molto a causa della diminuzione della copertura del test e dei test di salto. Voglio eseguire i miei test per entrambi i casi. Sarebbe utile se qualcuno potesse suggerire una soluzione alternativa migliore per questo.

risposta

4

IMHO, dovresti sempre eseguire i test che non richiedono PANDAS, perché nulla ti impedisce di farlo.

ma si dovrebbe davvero saltare il panda che richiedono se panda non è presente in fase di test, perché si otterrebbe errori uninformative semplicemente causati dalla assenza di un componente opzionale.

In questo modo, quando si esegue il test sul proprio ambiente (con i panda presumo), si verificheranno entrambi i casi, ma se un altro utente desidera eseguire i test in un ambiente senza panda, può comunque testare la parte che dovrà uso.

Quindi il mio consiglio è:

@unittest.skipUnless(HAVE_PANDAS, "requires pandas") 
def tests_using_pandas(self): 
    # do something 

def tests_without_pandas(self): 
    # do something 
5

Se si desidera testare entrambi i casi (che si dovrebbe), si potrebbe forzare l'importazione di Panda a fallire aggiungendo None alla voce 'pandas' in sys.modules, assicurandosi di aggiungerlo di nuovo (o cancellare la voce se non esistesse in primo luogo) una volta che il test è stato completato.

import unittest 
import sys 

class TestWithoutPandas(unittest.TestCase): 
    def setUp(self): 
     self._temp_pandas = None 
     if sys.modules.get('pandas'): 
      self._temp_pandas = sys.modules['pandas'] 
     sys.modules['pandas'] = None 

    def tearDown(self): 
     if self._temp_pandas: 
      sys.modules['pandas'] = self._temp_pandas 
     else: 
      del sys.modules['pandas'] 

    def tests_using_pandas(self): 
     flag = False 
     try: 
      import pandas 
     except ImportError: 
      flag = True 
     self.assertTrue(flag) 

class TestWithPandas(unittest.TestCase): 
    def tests_using_pandas(self): 
     flag = False 
     try: 
      import pandas 
     except ImportError: 
      flag = True 
     self.assertFalse(flag) 
Problemi correlati