__init__ dla unittest.TestCase


122

Chciałbym dodać kilka rzeczy do tego, co unittest.TestCaserobi klasa po zainicjowaniu, ale nie wiem, jak to zrobić.

Teraz robię to:

#filename test.py

class TestingClass(unittest.TestCase):

    def __init__(self):
        self.gen_stubs()

    def gen_stubs(self):
        # Create a couple of tempfiles/dirs etc etc.
        self.tempdir = tempfile.mkdtemp()
        # more stuff here

Chciałbym, aby wszystkie kody pośredniczące były generowane tylko raz dla całego zestawu testów. Nie mogę używać, setUpClass()ponieważ pracuję na Pythonie 2.4 (nie udało mi się też uzyskać tego działającego na Pythonie 2.7).

Co ja tu robię źle?

Otrzymuję ten błąd:

 `TypeError: __init__() takes 1 argument (2 given)` 

... i inne błędy, gdy przenoszę cały kod pośredniczący, __init__gdy uruchamiam go za pomocą polecenia python -m unittest -v test.


@Neeraj Myślę, że moje pytanie jest wcześniejsze niż to?
ffledgling

@Abhijeet To pytanie zostało zadane w 2013 r., To, do którego odsyłasz, zostało zadane w 2016 r. I ma mniej odpowiedzi i dyskursu, może zamiast tego należy oznaczyć drugie pytanie jako duplikat? Odpowiedź jest związana z Pythonem 3, a to pytanie dotyczy Pythona 2.
ffledgling

przepraszam za to mój błąd.
Abhijeet

Odpowiedzi:


166

Spróbuj tego:

class TestingClass(unittest.TestCase):

    def __init__(self, *args, **kwargs):
        super(TestingClass, self).__init__(*args, **kwargs)
        self.gen_stubs()

Zastępujesz wartości TestCase's __init__, więc możesz chcieć, aby klasa bazowa obsługiwała argumenty za Ciebie.


+1 Zainicjowałbym jednak klasę bazową przed wywołaniem jakiejkolwiek metody obiektu.
Joachim Isaksson

To nie działa na mnie. Rzeczy wewnątrz gen_stub nie są wykonywane. W rzeczywistości wygląda na to, że gen_stub w ogóle nie jest wywoływany ... Wiem, ponieważ do self.tempdir, który powinien istnieć, nie można uzyskać dostępu za pomocą innych metod tej klasy. Otrzymuję AttributeError: Obiekt „TestingClass” nie ma atrybutu „tempdir”
ffledgling

22
czy nie powinieneś raczej wzywać tego setUpniż zastępować __init__?
karthikr

2
@karthikr Chcę raz wygenerować kody pośredniczące dla wszystkich testów, zamiast tworzyć je ponownie dla każdego testu za każdym razem. Niektóre kody pośredniczące nie będą nawet używane w niektórych testach. Użyłbym setUpClass, ale nie sądzę, że Python 2.4 to obsługuje.
ffledgling

2
Możesz być również nieco bardziej wyraźne w tym przypadku (który pomaga czytelności moim zdaniem) i zastosowanie: unittest.TestCase.__init__(self,*args,**kwargs)zamiastsuper(TestingClass, self).__init__(*args, **kwargs)
Onyooo

22

Chciałem tylko dodać kilka wyjaśnień dotyczących zastępowania funkcji inicjującej

unittest.TestCase

Funkcja zostanie wywołana przed każdą metodą w klasie testowej. Zwróć uwagę, że jeśli chcesz dodać kilka kosztownych obliczeń, które należy wykonać raz przed uruchomieniem wszystkich metod testowych, użyj metody klasy SetUpClass

@classmethod
def setUpClass(cls):
    cls.attribute1 = some_expensive_computation()

Ta funkcja zostanie wywołana raz przed wszystkimi metodami testowymi klasy. Zobacz setUpmetodę, która jest wywoływana przed każdą metodą testową.


4

Zainstaluj unittest2 i użyj unittest tego pakietu.

import unittest2 

a następnie użyj klasy setupModule / tearDownModule lub setupClass / tearDown dla specjalnej logiki inicjalizacji

Więcej informacji: http://www.voidspace.org.uk/python/articles/unittest2.shtml

Najprawdopodobniej tworzysz test integracji bardziej niż niezbyt dobry. Wybierz dobrą nazwę dla testów, aby je rozróżnić lub umieść w innym module kontenera.


Dzięki za link do dokumentacji.
Chris,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.