2016-12-10 4 views
0

내가 짓고 있어요 플라스크 응용 프로그램에 대한 몇 가지 단위 테스트를 작성하기 위해 노력하고있어에서 시작,이 플라스크 응용 프로그램을종료하는 방법 플라스크 프로세스는 유닛 테스트

app.py가 들어있는 파일입니다

from flask import Flask 

app = Flask(__name__) 


@app.route('/') 
def home(): 
    return 'hello world' 

다음 파일에 포함 된 테스트

tests.py

from unittest import TestCase, main 
from app import app 
from multiprocessing import Process 
import requests 


class Test(TestCase): 

    @classmethod 
    def setUpClass(cls): 
     cls.hostname = 'http://localhost:8000' 

     with app.app_context(): 
      p = Process(target=app.run, kwargs={'port': 8000}) 
      p.start() 
      cls.p = p 

    def test_options(self): 
     # print(self.p.is_alive()) # returns True but requests doesn't connect 
     result = requests.post(self.hostname).text 
     self.assertEqual(result, 'hello world') 

    @classmethod 
    def tearDownClass(cls): 
     cls.p.terminate() # works fine if i comment it out 
     pass 


if __name__ == '__main__': 
    main() 

내가 와서 플라스크와 함께 제공되는 test_client 대신 requests 모듈을 사용하여 응용 프로그램을 테스트 할 생각입니다. 새로운 프로세스를 생성하고 응용 프로그램을 시작하는 setUpClass 방법은 한 번이라고

유닛 테스트 모듈에 대한 이해에서

,.

그 후 나는 request.post 또는 request.get으로 다양한 테스트를 무료로 실행할 수 있습니다.

그런 다음 하루가 끝날 때 모든 테스트가 완료되면 tearDownClass이 프로세스를 종료해야합니다. 나는 이것이 내가 무엇을 얻을 수있는 테스트를 실행하려고하면

는 (스택 트레이스는 실제로 더 이상이보다하지만, 모든이 아래로 비등) 플라스크 프로세스가 시작하고 요청하지 않는

requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=5000): Max retries exceeded with url:/(Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x7faeeba183c8>: Failed to establish a new connection: [Errno 111] Connection refused',)) 

때문에

cls.p.terminate 모든 것이 올바르게 작동하고 테스트가 통과되면 이상한 부분은 내가 플라스크 프로세스를 다시 죽일 수 없다는 것입니다.

나는 내가 프로세스가 악마의하거나이 같은 test_client 사용할 수 있습니다 알고

class Test(TestCase): 

    @classmethod 
    def setUpClass(cls): 
     cls.hostname = 'http://localhost:8000' 

     with app.app_context(): 
      app.config['TESTING'] = True 
      cls.app = app.test_client() 

    def test_options(self): 
     # print(self.p.is_live()) 
     result = self.app.get().data 
     self.assertEqual(result, b'hello world') 

그냥 내 인생에 이동을하지만, 내가하려고하면 내 코드가 작동하지 않는 이유는 정말 이해 할 내가 테스트 스위트를 찢을 때 프로세스를 죽이기 위해서.

pdb 디버깅을 시도했지만 어떤 이유로 pdb 프롬프트에 아무 것도 입력하지 않으면 터미널이 엉망이된다는 것을 모릅니다. (일부 문자는 터미널에 표시되지 않습니다. 내가 입력 한하지만 난 입력 쳤을 때 내가 문자가 실제로 있었다하지만 보이지 않았다 것을 발견, 예를 들면) 난을 눌러 때

+0

이 시점에서 테스트 하네스는 앱보다 복잡하고 깨지기 쉽기 때문에 테스트 하네스가 제대로 작동하더라도 테스트 하네스가 계속 남아있을 수 있습니다.아마도 조롱만으로 시작하는 것이 좋을 것입니다. 필요한 경우 플라스크 문서에 설명 된 테스트 설정으로 이동하십시오. – pvg

+0

그래, 나도 알아 ...하지만 다른 한편으로는,'test_client'는 REST API를 테스트하는 데 정말로 적합하지 않다. 실제로 Response 객체는 바이트 만 반환한다. (다른 데이터 타입으로의 변환을 스스로 처리해야한다.) 내 질문은 "질문"보다 더 많은 질문입니다. – danidee

+0

플라스크 앱을 완전히 뜯기 전에 실제로 초기화되지 않았기 때문일 수 있습니다. 작업 순서를 볼 수 있도록 기본 인쇄 로깅을 추가해야합니다. 당신은 또한 p.start 후 teardown을 주석 처리하지 않고 5-10 초간 수면을 유지할 수 있습니다 (붕대 대책으로 확인). 그러면 쉽게 이론을 확인할 수 있습니다. – pvg

답변

1

I을 표시하기를 거부 prrrinnntttr 때문에 t 내가 가진 끝낼 수 있습니다 print를 입력합니다 귀하의 경우에 무슨 일이 일어나고 있는지 모르겠지만 내 프로젝트 중 하나에서 테스트 할 때 이와 같은 bash 스크립트를 사용합니다.

#!/bin/bash 

set -eux 

python app.py & 
sleep 3 

set +e 

python tests.py 
result=$? 
kill $(ps aux | grep app.py | grep -v grep | awk '{print $2}') 
exit $result 

이것은 서버를 불러오고, 테스트를 실행 한 다음 서버를 죽이는 것을 처리합니다. 그리고 파이썬 테스트에서 서버를 다루는 언급은 없습니다.

+0

감사합니다 @AlexHall, 나는 또한 내가 bash 스크립트로 이것을 처리 할 수 ​​있다는 것을 알았습니다. 저는 파이썬에서이 모든 것을하고 싶었습니다. 이제는 (Test 클래스 밖에서 프로세스 생성을 이동하여 스크립트 및 데몬스트레이션). 그래서 문제는 unitTests 메소드와 관련이 있으며 내부적으로 어떻게 작동하는지 알 수 있습니다. – danidee