2009-12-31 18 views
14

Piszę moduł Pythona, który otacza określony API serwisu WWW. To wszystko jest REST, więc stosunkowo proste do wdrożenia.Używanie SimpleHTTPServer do testowania jednostkowego

Znalazłem jednak problem, jeśli chodzi o testowanie jednostkowe: ponieważ nie uruchamiam usług, dla których zrobiłem ten moduł, nie chcę ich młotkować, ale jednocześnie muszę je odzyskać dane do uruchomienia moich testów. Spojrzałem na SimpleHTTPServer, co byłoby OK.

Rozwiązałem część problemu, który miałem, ale teraz, ponieważ nie mogę zakończyć wątku, pojawia się problem z "adresem już w użyciu" podczas uruchamiania aplikacji testowej więcej niż raz.

Oto niektóre przykładowy kod

PORT = 8001 

handler = SimpleHTTPServer.SimpleHTTPRequestHandler 

httpd = SocketServer.TCPServer(("", PORT), handler) 

httpd_thread = threading.Thread(target=httpd.serve_forever) 
httpd_thread.setDaemon(True) 
httpd_thread.start() 

api_data = urllib.urlopen("http://localhost:8001/post/index.json") 
print "Data start:" 
print json.load(api_data) 

Gdzie „index.json” to mock plik JSON zrobiłem który zastępuje prawdziwych. Jak mogę wyczyścić rzeczy z gracją po zakończeniu programu?

+0

SimpleHTTPServer powinien naprawdę być najprostszy sposób. Jakie masz problemy? – balpha

+0

Przeformułowałem sprawy, mam nadzieję, że teraz jest jaśniej. – Einar

Odpowiedz

11

Spróbuj użyć subclass of TCPServer with allow_reuse_address set True:

class TestServer(SocketServer.TCPServer): 
    allow_reuse_address = True 

... 
httpd = TestServer(("", PORT), handler) 
+0

genialny! miło i prosto – Claudiu

+0

To nie działało dla mnie, ale udało mi się to rozwiązać, konfigurując SocketServer w metodzie setUpClass zamiast w metodzie setUp. Błąd adresu w użyciu wydaje się zdarzyć przy drugim wywołaniu metody setUp (co ma miejsce po uruchomieniu drugiego testu). – mlissner

4

Używamy serwera zbudowanego na wsgiref. http://docs.python.org/library/wsgiref.html

Dodanie funkcji do tego serwera jest bardzo łatwe, ponieważ dodajemy testy jednostkowe.

Zaczynamy od serwera z subprocess. http://docs.python.org/library/subprocess.html?highlight=subprocess#module-subprocess

Nie używamy nici do tego rodzaju testów. Czemu? (1) Nasz serwer testów jednostkowych jest dość skomplikowany i chcielibyśmy, aby był całkowicie odizolowany od aplikacji klienckich. (2) Nasze aplikacje klienckie będą oddzielnymi procesami na oddzielnym sprzęcie, musimy mieć pewność, że mamy realistyczne oczekiwania odnośnie wydajności dla tej konfiguracji. (3) To jest prostsze. (4) Jest przenośny na wszystkich platformach. (5) Przejście z samodzielnego testowania jednostkowego do testowania integracji z serwerem produkcyjnym, który już działa, jest trywialne.

W rzeczywistości mamy małą aplikację WSGI, która powoduje, że zamknięcie serwera odbywa się w sposób racjonalnie kontrolowany, aby logi zostały poprawnie zamknięte.

+0

Rzeczywiście, wydaje się, że podproces może być dobrą alternatywą. Zbadam dalej. – Einar

4

Stary wątek ale odpowiedzi tutaj nie może mi pomóc, używam HTTPServer i wyłączania po każdym badaniu jednostkowych (domyślnie HTTPServer ma allow_reuse_address = 1 zestaw). Jednak po wywołaniu wyłączenia nadal mam problem z używaniem adresu. Poprawiłem używając:

from BaseHTTPServer import HTTPServer 

class MyHTTPServer(HTTPServer): 
    def shutdown(self): 
     self.socket.close() 
     HTTPServer.shutdown(self) 

Nie wiesz, dlaczego tak się nie dzieje domyślnie? Może to nie jest optymalne?

Powiązane problemy