2013-07-08 7 views
25

In un test di python unit (in realtà Django), qual è la corretta istruzione assert che mi dirà se il risultato del mio test contiene una stringa di mia scelta?Python/Django: come affermare che il risultato del test unitario contiene una determinata stringa?

cioè, qualcosa di simile a self.assertContainsTheString(result, {"car" : ["toyota","honda"]})

voglio fare in modo che il mio result contiene almeno l'oggetto JSON (o stringa) che ho specificato come secondo argomento di cui sopra, vale a dire, {"car" : ["toyota","honda"]}

+0

farebbe [https://docs.djangoproject.com/en/1.11/topics/testing/tools /#django.test.Response.json] aiuto? – coya

risposta

16
self.assertContains(result, "abcd") 

È possibile modificarlo per lavorare con JSON.

Utilizzare self.assertContains solo per oggetti HttpResponse. Per altri oggetti, utilizzare self.assertIn.

+2

sì, ma a causa della struttura json, potrebbe essere aggiunto qualche spazio bianco che non è problematico in json ma problematico se si desidera confrontare con una stringa python. – francois

+20

assertContains non è destinato ad essere utilizzato per un oggetto diverso da HttpReponse, preferibilmente usando assertTrue con la parola chiave "in" python invece (vedi il mio risponditore qui sotto). – Pcriulan

+9

Questo è sbagliato. Assertconains è per le risposte http. – kagronick

6

Costruire un JSON oggetto utilizzando json.dumps().

poi confrontarle con assertEqual(result, your_json_dict)

import json 

expected_dict = {"car":["toyota", "honda"]} 
expected_dict_json = json.dumps(expected_dict) 

self.assertEqual(result, expected_dict_json) 
+1

Perché usare 'assertTrue()' invece di ['assertEqual()'] (http://docs.python.org/3/library/unittest.html#unittest.TestCase.assertEqual)? Almeno con 'assertEqual()', il modulo stamperà sia il risultato che i valori attesi. –

+0

Hai ragione, assertEqual() è migliore. Non riesco a trovare il collegamento ma sono sicuro di aver letto da qualche parte per usare assertTrue invece di assertEqual. Ovviamente, ho sbagliato :) risolverò l'esempio sopra. –

+8

Si noti che questo non sarà affidabile quando si ha più di una chiave in qualsiasi dizionario, perché 'dumps()' usa un ordinamento arbitrario e non conosciamo l'ordine delle chiavi in ​​'result'. Faresti molto meglio a usare 'self.assertEqual (json.loads (result), expected_dict)'. –

13

È possibile scrivere affermazione sulla parte atteso di stringa in un'altra stringa con un semplice assertTrue + in python parola chiave:

self.assertTrue("expected_part_of_string" in my_longer_string) 
+4

Il problema con questa strategia è che è in grado di dare poveri messaggi di errore del modulo "AssertionError: False non è vero" – jamesc

-1

mi sono trovato in un problema simile e ho usato l'attributo rendered_content, così ho scritto

assertTrue('string' in response.rendered_content) e allo stesso modo

assertFalse('string' in response.rendered_content) se voglio verificare che una stringa non sia resa

Ma ha lavorato anche il metodo suggerito all'inizio,

AssertContains(response, 'html string as rendered')

Quindi direi che il primo è più semplice. Spero possa essere d'aiuto.

57

Per affermare se una stringa è o non è una sottostringa di un altro, è necessario utilizzare assertIn e assertNotIn:

# Passes 
self.assertIn('bcd', 'abcde') 

# AssertionError: 'bcd' unexpectedly found in 'abcde' 
self.assertNotIn('bcd', 'abcde') 

Questi sono novità dal Python 2.7 e Python 3.1

+2

Anche "assertIn' fornisce messaggi utili in caso di errore come te" ve illustrato. – jamesc

3

As mentioned by Ed I, assertIn è probabilmente il più semplice rispondi a trovare una stringa in un'altra. Tuttavia, la questione afferma:

I want to make sure that my result contains at least the json object (or string) that I specified as the second argument above,i.e., {"car" : ["toyota","honda"]}

Perciò vorrei utilizzare più asserzioni in modo che i messaggi vengono ricevuti utile in caso di fallimento - i test dovranno essere compreso e mantenuto in futuro, potenzialmente da qualcuno che non li scrivere in origine .Quindi supponendo che siamo all'interno di un django.test.TestCase:

# Check that `car` is a key in `result` 
self.assertIn('car', result) 
# Compare the `car` to what's expected (assuming that order matters) 
self.assertEqual(result['car'], ['toyota', 'honda']) 

che dà utili messaggi come segue:

# If 'car' isn't in the result: 
AssertionError: 'car' not found in {'context': ..., 'etc':... } 
# If 'car' entry doesn't match: 
AssertionError: Lists differ: ['toyota', 'honda'] != ['honda', 'volvo'] 

First differing element 0: 
toyota 
honda 

- ['toyota', 'honda'] 
+ ['honda', 'volvo']