2013-07-18 14 views
16

Używam py.test i zastanawiam się, czy/jak można pobrać nazwę aktualnie wykonywanego testu w metodzie setup, która jest wywoływana przed uruchomieniem każdego testu. Rozważmy następujący kod:py.test: jak uzyskać nazwę bieżącego testu z metody instalacji?

class TestSomething(object): 

    def setup(self): 
     test_name = ... 

    def teardown(self): 
     pass 

    def test_the_power(self): 
     assert "foo" != "bar" 

    def test_something_else(self): 
     assert True 

Tuż przed TestSomething.test_the_power zostaje stracony, chciałbym mieć dostęp do tej nazwy w setup jak przedstawiono w kodzie poprzez test_name = ... tak że test_name == "TestSomething.test_the_power".

W rzeczywistości, w setup, przydzielaję pewne zasoby dla każdego testu. Na koniec, patrząc na zasoby, które zostały utworzone przez różne testy jednostkowe, chciałbym móc zobaczyć, który z nich został stworzony za pomocą którego testu. Najlepiej byłoby po prostu użyć nazwy testu po utworzeniu zasobu.

Odpowiedz

8

W setup i teardown metody wydają się być starsze metody wspierania testy napisane dla innych ram, na przykład nos. Natywne metody pytest nazywają się setup_method, a także teardown_method, które otrzymują aktualnie wykonywaną metodę testową jako argument. Stąd, co chcę osiągnąć, można zapisać tak:

class TestSomething(object): 

    def setup_method(self, method): 
     print "\n%s:%s" % (type(self).__name__, method.__name__) 

    def teardown_method(self, method): 
     pass 

    def test_the_power(self): 
     assert "foo" != "bar" 

    def test_something_else(self): 
     assert True 

Wyjście py.test -s następnie jest:

============================= test session starts ============================== 
platform linux2 -- Python 2.7.3 -- pytest-2.3.3 
plugins: cov 
collected 2 items 

test_pytest.py 
TestSomething:test_the_power 
. 
TestSomething:test_something_else 
. 

=========================== 2 passed in 0.03 seconds =========================== 
0

Może spróbuj type(self).__name__?

+0

W moim przykładzie to zapewni tylko 'TestCoś". Głównie jestem po drugiej części nazwy :) –

0

Można mieć wiele testów, w tym przypadku ...

test_names = [n for n in dir(self) if n.startswith('test_')] 

... daje wszystkie funkcje i zmienne instancji, które zaczynają się od „test_” w self. Dopóki nie masz żadnych zmiennych o nazwie "test_something", to zadziała.

Można również zdefiniować metodę setup_method(self, method) zamiast setup(self), która będzie wywoływana przed każdym wywołaniem metody testowej. Używając tego, po prostu podajesz każdą metodę jako parametr. Zobacz: http://pytest.org/latest/xunit_setup.html

+0

Wszystkie metody reprezentujące testy py.test zaczynają się od 'testu'. Potrzebuję tutaj API py.test, ponieważ py.test zebrał wcześniej wszystkie testy (w zasadzie tak, jak sugerowałeś) i już wie, który test ma być teraz uruchomiony. Po prostu nie znam właściwego pytania do py.test :-) –

+0

Komentarz po edycji: Nie chcę po prostu mieć listy wszystkich metod zaczynających się od "test_". Z tej listy szukam jednej nazwy/metody przeprowadzanego testu * właśnie teraz *. I to tylko urządzenia wewnętrzne py.test mogą powiedzieć. –

+0

Myślę, że chcesz 'setup_method' zamiast tylko' setup' – ejk314

0

Możesz dać moduł inspekcji spróbować.

import skontrolować

def foo(): 
    print "My name is: ", inspect.stack()[0][3] 


foo() 

Output: Nazywam się: foo

+0

Wywoływany z metody 'setup', to oczywiście zwraca' setup'. –

+0

To było bardzo pomocne dla mnie, dzięki! – kroe761

35

Można też to zrobić za pomocą Request Fixture takiego:

def test_name1(request): 
    testname = request.node.name 
    assert testname == 'test_name1' 
+6

** Jest to odpowiedź ogólnego przeznaczenia, ** równorzędne zarówno dla funkcji testowych _i_ metod testowych. Podczas gdy dokumentacja py.test jest szczególnie spektakularna, jego dokumentacja dla 'request' jest niezwykle okropna. Atrybut 'request.node' jest udokumentowany tylko jako" podstawowy węzeł kolekcji (w zależności od bieżącego zakresu żądania). " to jest to! Ja absolutnie nigdy nie znalazłbym tego - i wątpię, by ktokolwiek inny mógł to zrobić. Bravo, żaby Daniel! –

+5

Pamiętaj jednak, że po parametryzacji funkcji testowej, 'request.node.name' zawiera unikatową nazwę z parametrami, np. 'nazwa_testowania [param-other_param]'. Dlatego też jest on nuższe, aby zawsze używać ['request.node.originalname'] (http://doc.pytest.org/en/latest/writing_plugins.html#_pytest.python.Function.originalname), która podaje oryginalną nazwę funkcji nienaruszony. Zwróć też uwagę, że jest to dostępne poczynając od py.test 3.0. – julen

Powiązane problemy