2009-12-03 14 views
25

Ho uno script che funge da wrapper per alcuni test unitari scritti usando il modulo Python unittest. Oltre a ripulire alcuni file, la creazione di un flusso di output e la generazione del codice, carica casi di test in una suite conPython, unit test - Passa gli argomenti della riga di comando a setUp di unittest.TestCase

unittest.TestLoader().loadTestsFromTestCase() 

Sono già usando optparse a tirare fuori diverse argomenti della riga di comando utilizzate per determinare l'uscita posizione, se rigenerare il codice e se fare un po 'di pulizia. Voglio anche passare una variabile di configurazione, vale a dire un URI dell'endpoint, da utilizzare nei casi di test.

Mi rendo conto che posso aggiungere un OptionParser al metodo setUp del TestCase, ma voglio invece passare l'opzione a setUp. È possibile utilizzare loadTestsFromTestCase()? Posso scorrere il numero TestSuite restituito, TestCases, ma posso chiamare manualmente setUp su TestCases?

** EDIT ** ho voluto sottolineare che sono in grado di passare gli argomenti per setUp se iterare i test e chiamare setUp manualmente come:

(options, args) = op.parse_args() 
suite = unittest.TestLoader().loadTestsFromTestCase(MyTests.TestSOAPFunctions) 
for test in suite: 
    test.setUp(options.soap_uri) 

Tuttavia, io sto usando xmlrunner per questo e il suo metodo di esecuzione prende uno TestSuite come argomento. Presumo che eseguirà il metodo setUp stesso, quindi avrei bisogno dei parametri disponibili all'interno dello XMLTestRunner.

Spero che abbia senso.

risposta

43

Bene, voglio fare la stessa cosa e stavo per fare questa domanda io stesso. Volevo migliorare il codice seguente perché ha una duplicazione. Non mi permetta di inviare in argomenti per testare TestCase comunque:

import unittest 
import helpspot 

class TestHelpSpot(unittest.TestCase): 
    "A few simple tests for HelpSpot" 

    def __init__(self, testname, path, user, pword): 
     super(TestHelpSpot, self).__init__(testname) 
     self.hs = helpspot.HelpSpot(path, user, pword) 

    def test_version(self): 
     a = self.hs.version() 
     b = self.hs.private_version() 
     self.assertEqual(a, b) 

    def test_get_with_param(self): 
     a = self.hs.filter_get(xFilter=1) 

    def test_unknown_method(self): 
     self.assertRaises(helpspot.HelpSpotError, self.hs.private_wuggienorple) 

if __name__ == '__main__': 
    import sys 
    user = sys.argv[1] 
    pword = sys.argv[2] 
    path = sys.argv[3] 

    test_loader = unittest.TestLoader() 
    test_names = test_loader.getTestCaseNames(TestHelpSpot) 

    suite = unittest.TestSuite() 
    for test_name in test_names: 
     suite.addTest(TestHelpSpot(test_name, path, user, pword)) 

    result = unittest.TextTestRunner().run(suite) 
    sys.exit(not result.wasSuccessful()) 
+0

Cos'è l'Helppot qui? – SIslam

+0

HelpSpot è un'applicazione del servizio clienti di UserScape. Ho scritto un'interfaccia Python per la sua API - https://github.com/JohnSpeno/python-helpspot – jps

+0

Per far sì che funzioni come unittest.main() 'dovresti aggiungere' sys.exit (non result.wasSuccessful()) 'alla fine. – abergmeier

5

Definitivamente sconsiglio di passare argomenti a setUp come questo; setUp deve essere chiamato implicitamente durante l'esecuzione di un test, quindi non dovresti chiamarlo esplicitamente in questo modo.

Un modo per risolvere questo problema è impostare i valori che è necessario impostare come variabili di ambiente o valori in un modulo "contesto" accessibile a livello globale, che consentirebbe ai casi di test di accedervi secondo necessità. Vorrei usare le variabili di ambiente, poiché è più flessibile in termini di esecuzione dei test (non ci si basa più sugli argomenti della riga di comando).

+4

E poi qualche altro codice si basa su una variabile ambientale con lo stesso nome, ottima. – GNUnit

0

Se si definiscono gli attributi nel metodo init, allora si può semplicemente passare tutto nel costruttore come questo ..

import unittest 
import helpspot 

class TestHelpSpot(unittest.TestCase): 
    "A few simple tests for HelpSpot" 

    def __init__(self, testname, path, user, pword): 
     super(TestHelpSpot, self).__init__(testname) 
     self.path = path 
     self.user = user 
     self.pword = pword 
.... 
.... 
.... 


if __name__ == '__main__': 
    True 

    suite = unittest.TestSuite() 
    suite.addTest(TestHelpSpot("test_version", path, user, pword))  

    unittest.TextTestRunner().run(suite) 
7
if __name__ == '__main__': 
    from optparse import OptionParser 
    parser = OptionParser() 
    parser.add_option("-z", "--zebra", 
         action="store_true", dest="zebra", default=False, 
         help="run like a zebra")  


    (options, args) = parser.parse_args() 

    if options.zebra: 
     zebrafy() 


    # remove our args because we don't want to send them to unittest 
    for x in sum([h._long_opts+h._short_opts for h in parser.option_list],[]): 
     if x in sys.argv: 
      sys.argv.remove(x) 


    unittest.main() 
+0

Molto bello. Esattamente quello che stavo cercando. –

+1

II volevo aggiungere l'opzione '-i', e ho usato il codice sopra ... Inizio il mio test tramite' .. \ .. \ python \ python -m unittest -v "test_activation.test_activation" -i "file_input" ' . Perché questo mi dà un errore 'test_activation.py: errore: nessuna opzione del genere: -m'? – Danijel

+0

Questo non ha funzionato per me. – Indrajeet

Problemi correlati