2014-08-28 15 views
6

Chcę móc zwrócić wartość z urządzenia do wielu testów/klas testowych, ale wartość, która jest przekazywana, jest funkcją.urządzenie pytające zawsze zwraca funkcję

Oto mój kod:

import pytest 

@pytest.fixture() 
def user_setup(): 
    user = { 
     'name': 'chad', 
     'id': 1 
    } 
    return user 

@pytest.mark.usefixtures('user_setup') 
class TestThings: 
    def test_user(self): 
     assert user_setup['name'] == 'chad' 

Wyjście jest:

=================================== FAILURES =================================== 
_____________________________ TestThings.test_user _____________________________ 

self = <tests.test_again.TestThings instance at 0x10aed6998> 

    def test_user(self): 
>  assert user_setup['name'] == 'chad' 
E  TypeError: 'function' object has no attribute '__getitem__' 

tests/test_again.py:14: TypeError 
=========================== 1 failed in 0.02 seconds =========================== 

Ale gdybym przepisać mój test tak, aby nie używać usefixtures dekorator, że działa zgodnie z oczekiwaniami:

def test_user(user_setup): 
    assert user_setup['name'] == 'chad' 

Jakieś pomysły, dlaczego nie działają, gdy próbuję użyć metody dekoratora?

Odpowiedz

13

Po użyciu markera @pytest.mark.usefixtures trzeba jeszcze zapewnić podobnie nazwie argumentu wejściowego jeśli chcesz tego osprzętu muszą być wstrzykiwane do twojej funkcji testowej.

Jak opisano w py.test docs for fixtures:

Nazwa funkcji osprzętu może później odwoływać się do spowodowania jego inwokację przed uruchamiania testów ... funkcje testowe mogą bezpośrednio korzystać nazw uchwytów jako argumentów wejściowych w takim przypadku zostanie wstawiona instancja urządzenia zwrócona z funkcji urządzenia.

Po prostu używając dekoratora @pytest.mark.usefixtures wywołasz tylko funkcję. Podanie argumentu wejściowego da wynik tej funkcji.

Naprawdę powinieneś używać tylko @pytest.mark.usefixtures, gdy chcesz wywołać urządzenie, ale nie chcesz mieć go jako argument wejściowy do testu. Jak opisano w py.test docs.

Powodem, dla którego otrzymujesz wyjątek, który mówi o user_setup, ponieważ jest funkcją, jest to, że wewnątrz funkcji nazwa odnosi się do funkcji zdefiniowanej wcześniej w pliku. Aby otrzymać kod, aby działać zgodnie z oczekiwaniami trzeba by dodać argument do funkcji test_user:

@pytest.mark.usefixtures('user_setup') 
class TestThings: 
    def test_user(self, user_setup): 
     assert user_setup['name'] == 'chad' 

Teraz z perspektywy funkcji test_user nazwa user_setup będzie odnosić się do argumentów funkcji, które zostaną Zwracany wartość urządzenia jako wstrzyknięta przez py.test.

Ale tak naprawdę po prostu nie trzeba używać dekoratora @pytest.mark.usefixtures.

+2

Dzięki za jasne wyjaśnienie, jak to działa. Myślałem, że mogę to osiągnąć bez dodawania argumentu do każdej funkcji testowej, która jest w mojej klasie testowej. – Cass

+0

Właśnie szukałem różnicy i/lub przypadków użycia dla tych dwóch wariantów i kiedy używać, które dzięki za wyjaśnienie. – Zelphir

+0

Zgodnie z oficjalnymi dokumentami, nie powinieneś * mieć * dodawać 'user_setup' do każdej funkcji testowej, gdy są zgrupowane w klasie ozdobionej' @ pytest.mark.usefixtures': "Ze względu na znacznik Usefixtures, Do wykonania każdej metody testowania będzie wymagane oprzyrządowanie cleandir, tak jakby dla każdego z nich podano argument funkcji "cleandir". (Źródło: http://pytest.org/latest/fixture.html#using-fensions -z-klas-modułów-lub-projektów) Ostatecznie, cały punkt grupowania testów w ten sposób polega na manipulowaniu nimi jako partia.) ... Być może jest to błąd pyta? – Zearin

-1

W obu przypadkach zakres zakres user_setup odnosi się do funkcji. Różnica polega na tym, że w wersji nonfixture tworzysz parametr o tej samej nazwie, który jest klasyczną receptą na zamieszanie.

W tej wersji nonfixture, w zakresie test_user, twój identyfikator user_setup odnosi się do tego, co przekazujesz, a NIE do funkcji w zasięgu globalnym.

myślę, że prawdopodobnie znaczy być wywołanie user_setup i indeksowanie wynik jak

assert user_setup()['name'] == 'chad' 
Powiązane problemy