Python 2용 핸들러 테스트

Python용 로컬 단위 테스트 문서에는 애플리케이션에 단위 테스트를 실행하는 방법이 설명되어 있습니다. 단위 테스트는 코드의 개별 단위를 테스트하는 데 적합한 방법이지만, 해당하는 코드 단위를 통합해야 애플리케이션이 실행되므로 통합 테스트도 중요합니다.

App Engine 애플리케이션의 경우 요청 핸들러는 중요한 통합 지점입니다. WSGI 애플리케이션이 요청을 올바른 핸들러로 라우팅하는 동안 핸들러 자체에서는 요청 데이터를 처리하고 응답을 생성합니다(요청 핸들러에 대한 자세한 내용 참조). 요청 핸들러는 다른 함수나 클래스와 마찬가지로 일반적인 Python 객체이므로 자동화된 테스트에서 쉽게 사용할 수 있습니다. 그러나 WSGI 애플리케이션은 핸들러를 셸처럼 래핑하므로 테스트에서는 이와 유사한 셸을 사용합니다.

WebTest

테스트에는 WebTest 프레임워크를 활용합니다. WebTest는 WSGI 기반 애플리케이션 및 요청 핸들러를 테스트하기 위해 간단한 인터페이스를 제공하는 라이브러리입니다. WebTest는 이후에 테스트에 사용할 수 있는 특별한 테스트 앱에 WSGI 애플리케이션을 래핑하여 이 작업을 수행합니다. WebTest를 사용하면 전체 App Engine 환경이 없어도 핸들러와 상호작용하고 간편하게 요청을 실행하고 요청 환경을 수정할 수 있습니다. 응답에도 테스트에 적합한 인터페이스가 제공됩니다. WebTest를 반드시 사용할 필요는 없지만 사용하면 훨씬 간편하게 작업을 진행할 수 있습니다.

시작하기 전에 먼저 로컬 머신 또는 핸들러 테스트를 실행할 위치에 WebTest를 설치하세요. http://webtest.pythonpaste.org/#installation에서 안내를 확인할 수 있습니다.

간단한 'Hello World' 핸들러 테스트

일반 텍스트 답장으로 사용자 요청에 응답하는 간단한 'Hello World!' 핸들러를 먼저 테스트해 보겠습니다. 핸들러의 응답은 'Hello World!이고 콘텐츠 유형은 'text/plain'입니다.

import webapp2
import webtest

class HelloWorldHandler(webapp2.RequestHandler):
   def get(self):
       # Create the handler's response "Hello World!" in plain text.
       self.response.headers['Content-Type'] = 'text/plain'
       self.response.out.write('Hello World!')

그런 다음 테스트 사례를 만들고 핸들러를 사용하는 테스트 애플리케이션을 초기화합니다.

...
class AppTest(unittest.TestCase):
    def setUp(self):
        # Create a WSGI application.
        app = webapp2.WSGIApplication([('/', HelloWorldHandler)])
        # Wrap the app with WebTest’s TestApp.
        self.testapp = webtest.TestApp(app)

    # Test the handler.
    def testHelloWorldHandler(self):
        response = self.testapp.get('/')
        self.assertEqual(response.status_int, 200)
        self.assertEqual(response.normal_body, 'Hello World!')
        self.assertEqual(response.content_type, 'text/plain')

이와 같이 WebTest를 사용하면 간단한 get() 호출로 GET 요청을 실행할 수 있습니다(다른 요청 메서드에도 비슷한 메서드가 있음). 반환 값은 상태 코드, 본문, 콘텐츠 유형 등을 테스트할 수 있는 응답 객체입니다. 수행할 수 있는 모든 작업에 대한 자세한 설명은 WebTest 홈페이지를 확인하세요.

App Engine 서비스를 사용하는 핸들러 테스트 만들기

App Engine 서비스를 사용하는 핸들러를 테스트하는 방법을 살펴보겠습니다. 즉, 테스트에 영향을 미칠 수 있는 두 가지 구성요소인 핸들러와 사용 중인 서비스를 처리해야 합니다. Python용 로컬 단위 테스트 문서에 설명된 대로 테스트에서 서비스를 처리하는 가장 좋은 방법은 testbed를 사용하는 것입니다.

다음 예에서는 Memcache를 사용하지만 Datastore 또는 작업 대기열과 같은 다른 서비스와 원칙적으로는 동일합니다.

테스트하는 핸들러는 제공된 키와 값을 캐시합니다. 요청 매개변수의 두 값을 모두 파싱한다는 점에 주의하세요.

from google.appengine.api import memcache
from google.appengine.ext import testbed
import webapp2
import webtest

class CacheHandler(webapp2.RequestHandler):
  def post(self):
    key = self.request.get('key')
    value = self.request.get('value')
    memcache.set(key, value)

이 테스트에서는 이전과 마찬가지로 애플리케이션을 먼저 만든 다음 WebTest로 래핑합니다. 그리고 Testbed 인스턴스를 활성화하고 테스트 후에는 반드시 비활성화합니다.

...
class AppTest(unittest.TestCase):

  def setUp(self):
    app = webapp2.WSGIApplication([('/cache/', CacheHandler)])
    self.testapp = webtest.TestApp(app)
    self.testbed = testbed.Testbed()
    self.testbed.activate()

  def tearDown(self):
     self.testbed.deactivate()

  def testCacheHandler(self):
    # First define a key and value to be cached.
    key = 'answer'
    value = '42'
    self.testbed.init_memcache_stub()
    params = {'key': key, 'value': value}
    # Then pass those values to the handler.
    response = self.testapp.post('/cache/', params)
    # Finally verify that the passed-in values are actually stored in Memcache.
    self.assertEqual(value, memcache.get(key))

테스트 프레임워크 설정

원하는 경우 테스트 프레임워크를 설정할 수 있습니다. WebTest를 사용하는 핸들러 테스트는 App Engine의 단위 테스트와 같은 방법으로 실행할 수 있지만, WebTest가 설치되었는지 확인해야 한다는 점이 유일하게 다릅니다.