適用於 Python 的本機單位測試一文說明如何為應用程式執行單位測試。雖然單位測試非常適合用於測試個別的程式碼單位,但程式碼單位的整合是讓應用程式得以運作的關鍵,因此,整合測試同樣重要。
就 App Engine 應用程式而言,要求處理常式是關鍵的整合點。WSGI 應用程式會將要求路由至適當的處理常式,而處理常式本身則會處理要求資料並產生回應 (如要瞭解詳情,請參閱要求處理常式)。要求處理常式是如同任何其他函式或類別的一般 Python 物件,易於在自動化測試中使用。但由於 WSGI 應用程式將這些要求處理常式包裝成類似 Shell,因此我們會在測試中使用類似的 Shell。
WebTest
我們會在測試中使用 WebTest 架構。WebTest 是針對測試 WSGI 應用程式提供簡易介面的程式庫,因此適用於要求處理常式。其做法是將 WSGI 應用程式包裝在特殊的測試應用程式中,以供後續測試使用。WebTest 可讓您在不具完整 App Engine 環境的情況下與處理常式互動;您可以輕鬆發出要求及修改要求環境。回應也有便於測試的介面。您未必需要使用 WebTest,但 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 或 Task Queue 等其他服務是相同的。
我們測試的處理常式會快取指定的鍵和值。請注意,我們會剖析要求參數中的兩個值。
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))
設定測試架構
您可以視需要設定測試架構。您可以如同 App Engine 的單位測試方法,針對使用 WebTest 的處理常式進行測試。唯一的差別在於您必須確定已安裝 WebTest。