2013-05-13 7 views
12

Testuję aplikację Flask (Flask 0.9), aw szczególności mam sesję sesji, którą chciałbym uruchomić w sposób udokumentowany, będąc czymś podobnym (jak rozumiem):Test jednostkowy sesji Flask - nie można odtworzyć błędu za pomocą session_transaction

from flask import Flask, session 
app = Flask(__name__) 

@app.route('/', methods=['POST']) 
def m(): 
    logging.error(session) # expect {'x': 1} 
    return "" 

with app.test_request_context() as trc: 
    with app.test_client() as c: 
    with c.session_transaction() as sess: 
     sess['x'] = 1 
    c.post() 

to działa zgodnie z oczekiwaniami, z wyjściem będącego coś takiego:

ERROR:root:<SecureCookieSession {'x': 1}> 

Niestety ja napotkaniu nieoczekiwany rezultat w którym dane sesji nie jest ustawiony w punkcie końcowym funkcja, tzn. wynik jest mniej więcej taki:

ERROR:root:<SecureCookieSession {}> 

Ten numer jest wyświetlany tylko wtedy, gdy jest uruchamiany z mojej platformy testowej. W obecnej formie nie jestem w stanie odtworzyć tego problemu ze zdegenerowanym przypadkiem, chociaż wykonałem dość duży wysiłek with a gist of some of this effort here. Najważniejsze punkty to to, że zawarłem itsdangerous i Google App Engine testbed, spodziewając się, że być może jedna z nich była przyczyną.

W moim własnym systemie poszedłem dalej niż gist i prawie całkowicie zreplikowałem mój układ testów jednostkowych próbując to odizolować. Podobnie, usunąłem stale rosnące ilości odpowiedniego kodu z mojej struktury testowej. Nie jestem w stanie myśleć o różnicach między zdegenerowanym przypadkiem a moim uproszczonym schematem, który mógłby wpłynąć na wynik. Przeprowadziłem wywołanie c.post() w pdb, aby wypróbować przyczynę tej złośliwości, ale muszę jeszcze zebrać wszelkie przydatne informacje.

To wszystko, co mogę powiedzieć, byłbym wdzięczny za mały kierunek lub sugestię, gdzie może leżeć problem. Co może mieć wpływ na kontekst Werkzeug w taki sposób, że session_transaction nie jest honorowany?

+0

Wiem, że minął już rok, ale sam wpadam na ten problem. Czy kiedykolwiek byłeś w stanie to rozgryźć? Zgodnie z tym, co przeczytałem online i w dokumentach, powinno to działać idealnie. Ale tak nie jest. –

+0

@IanHunter Spójrz na moją odpowiedź, poniżej. To może pomóc. –

Odpowiedz

0

Oto co skończyło się robi:

# Code that modifies the current `session`; we must be in a test context already. 
headers = {} 
with self.client.session_transaction(): 
    # Get the cookie that is sent to the browser to establish a connection 
    # via a fake request. 
    response = make_response() 
    self.app.session_interface.save_session(self.app, session, response) 
    headers['Cookie'] = response.headers.get('Set-Cookie', '') 
self.client.post(..., headers=headers) # also works for .get, .put, etc. 
0

Bez testówki, która faktycznie zawiedzie, trudno powiedzieć cokolwiek. Wszystko, co przychodzi mi do głowy, to to, że instancja TestClient, z której korzystasz, powoduje, że żądanie różni się od tego, którego używasz do skonfigurowania sesji. Na przykład. można zrobić istota nie jak oczekiwano z tym:

with self.app.test_client() as c: 
    with c.session_transaction() as sess: 
     sess['d'] = 1 
    self.client.post() 

Ale to nie jest przypadek tutaj lub istota, idź figurę.

+0

Dzięki. Mam trochę problemów ze zrozumieniem, co próbujesz tutaj dodać, Tommi. Jeśli zauważysz, że problem jest trudny, z pewnością się zgadzam - stąd hojność! ;) –

+1

Jak widzę, głównym powodem, dla którego jest to trudne, jest to, że kod, który wysłałeś * nie zawiedzie * zgodnie z opisem. Więc biorąc pod uwagę działający kod, wszystko, co mogę zrobić, to zrobić zgrabne domysły, jak sprawić, by to się nie powiodło, tak jak opisałeś, a przykład, który wysłałem, wydaje się równie dobry jak każdy inny. Po prostu nie rób tego w prawdziwym kodzie i powinieneś być bliżej, aby uzyskać coś działającego. –

3

W moim przypadku ograniczałem pliki cookie do konkretnej domeny automatycznie, ładując plik konfiguracyjny. Aktualizując konfigurację "w locie", udało mi się przekonać do działania ciasteczek podczas testów jednostkowych. Ustawiając właściwość SESSION_COOKIE_DOMAIN na None, wszystkie domeny (a mianowicie localhost) były w stanie ustawić sesje.

app.config.update(              
    SESSION_COOKIE_DOMAIN = None             
) 

Możesz bawić z ustawieniami konfiguracyjnymi opisanymi w Configuration Handling w docs.

1

Nienawidzę wskrzesić starą pytanie, ale wierzę, że zorientowali się rozwiązanie tego problemu. Do testowania, spróbuj ustawić nazwę serwera do localhost:

app.config['SERVER_NAME'] = 'localhost' 

I został pierwotnie używając siekać Briana, ale to rozwiązało problem dla mnie.

Powiązane problemy