2015-11-03 13 views
7

Nei test Python, perché dovremmo scrivere:Perché non usare la dichiarazione di asserzione di python nei test, in questi giorni?

self.assertEqual(response.status_code, 200) 
self.assertIn('key', my_dict) 
self.assertIsNotNone(thing) 

Al contrario al naturale:

assert response.status_code == 200 
assert 'key' in my_dict 
assert thing is not None 

Per molti casi, i messaggi di errore generati dai metodi helper asserzione non sono più leggibili (probabilmente lo stile CamelCase di unittest è less leggibile).

sfondo del mio progetto:

  • Siamo sempre utilizzando le moderne corridori di test come il naso o py.test, e in realtà non si preoccupano unittest corridore. Alla scoperta del test non interessa nemmeno se la classe eredita definitivamente unittest.TestCase o se si lavora all'interno di una classe a tutti gli effetti.
  • Non eseguiremo mai i test automatici con l'opzione -O all'interprete.
  • Quando vogliamo un messaggio più leggibile, quello predefinito da unittest non è generalmente abbastanza buono in ogni caso - ad es. c'è un valore diverso, annidato in dati json da qualche parte, e vogliamo vedere una differenza contestuale.

Le librerie di base e i test CPython sono ancora generalmente scritti in uno stile ininterrotto e generalmente fanno tutto per una buona ragione. Quindi la mia domanda è, è OK lavorare fuori dallo stile di unittest, o ci sono alcuni svantaggi che mi manca - perché non usare solo assert nei tuoi test? Perché gli sviluppatori core non sono ancora passati da un altro ancora?


addendum: il docs fanno parlare di un motivo:

Questi metodi sono utilizzati al posto della dichiarazione assert in modo che il test runner può accumulare tutti i risultati dei test e produrre un rapporto

Tuttavia questa giustificazione sembra essere fasulla, il test runner può accumulare risultati e riferire come al solito anche se si usano asserzioni. In un related post unutbu ha dimostrato che l'unittest genererà uno AssertionError esattamente come l'affermazione assert, e che è stato più di 7 anni fa quindi non è nemmeno una nuova caratteristica.

+2

Lavoro così lontano da 'unittest' che uso' print() 'invece di' assert'. Penso che tutto dipenda dalla complessità e dalle dimensioni del tuo progetto. – TigerhawkT3

+1

Questa sembra essere principalmente una questione di opinione. Se pensate che 'asserire' sia superiore allora non c'è nulla che impedisca (a parte forse che i vostri colleghi non siano d'accordo) di usarlo. Tuttavia, si dovrebbe sapere che è possibile sovrascrivere i metodi nella classe 'TestCase' e ​​personalizzare il comportamento - l'istruzione' assert' non ha questa flessibilità. Anche il 'TestCase.failureException' può essere alterato, invalidando il punto in cui si tratta della stessa eccezione generata dall'istruzione' assert' (potrebbe essere usata se si desidera considerare 'assert' un errore invece di un errore). – skyking

+0

Il semplice 'assert' è molto più leggibile. Quindi usa sempre 'pytest' se i tuoi test falliscono. – o11c

risposta

-1

Il collegamento ai documenti che hai trovato è la risposta corretta. Se non ti piace questo stile di scrittura dei test altamente li suggerirei di usare pytest:

http://pytest.org/latest/

pytest ha fatto un po 'di lavoro che consente di utilizzare l'istruzione assert il modo in cui si desidera. Ha anche un sacco di altre caratteristiche davvero interessanti come i loro dispositivi.

+3

Io uso pytest, come menzionato nella domanda. In che modo il reclamo nei documenti può essere considerato corretto, quando il test runner accumula felicemente tutti i risultati dei test e produce un report indipendentemente dal fatto che si utilizzino dichiarazioni di asserzione o le funzioni di supporto? – wim

3

La differenza chiave tra l'utilizzo della parola chiave assert o metodi dedicati è il rapporto di output. Si noti che la dichiarazione successiva a assert è sempre True o False e non può contenere informazioni aggiuntive.

assert 3 == 4 

mostra semplicemente un AssertionError nel report. Tuttavia,

self.assertTrue(3 == 4) 

dà qualche info in più: AssertionError: False is not true. Non molto utile, ma prendere in considerazione:

self.assertEqual(3, 4) 

E 'molto meglio, come ci dice che AssertionError: 3 != 4. Leggi il rapporto e sai che tipo di asserzione era (test di uguaglianza) e valori coinvolti.

Supponiamo di avere qualche funzione e di voler affermare il valore restituito. Si può fare in due modi:

# assert statement 
assert your_function_to_test() == expected_result 

# unittest style 
self.assertEqual(your_function_to_test(), expected_result) 

In caso di errore, il primo che non fornisce alcuna informazione oltre al errore di asserzione, il secondo ti dice che cosa è il tipo di affermazione (test di uguaglianza) e ciò che i valori sono coinvolti (valore restituito e previsto).

Per i piccoli progetti non mi preoccupo mai di uno stile unittest in quanto è più lungo da digitare, ma nei progetti di grandi dimensioni si consiglia di saperne di più sull'errore.

+0

È possibile aggiungere una stringa arbitraria a un'asserzione, da includere nell'allegata "AssertionError':' assert 3 == 4, "3! = 4" '. – chepner

+1

Ancora più importante, il runner/test framework è in grado di generare automaticamente il contesto. – wim

Problemi correlati