單元測(cè)試

2018-02-24 15:39 更新

單元測(cè)試

也許你經(jīng)常需要對(duì)你的的應(yīng)用進(jìn)行單元測(cè)試或者僅僅檢查 Python session 的輸出。理論上講這是很簡(jiǎn)單的,你可以偽造一個(gè)環(huán)境,通過(guò)一個(gè)假的 start_response 遍歷應(yīng)用,但是這里還有一個(gè)更好的方法。

Diving In

Werkzeug 提供了一個(gè) Client 對(duì)象,可以傳入一個(gè) WSGI 應(yīng)用(可選傳入一個(gè) response),通過(guò)這個(gè)你可以向應(yīng)用發(fā)出一個(gè)虛擬請(qǐng)求。

用三個(gè)參數(shù)調(diào)用一個(gè) response: 應(yīng)用迭代器、狀態(tài)和一個(gè) headers。默認(rèn) response 返回一個(gè)元組。因?yàn)?response 對(duì)象有相同的簽名,所以你可以像使用 response 一樣使用他們。通過(guò)這樣一種方式進(jìn)行測(cè)試功能是很理想的。

>>> from werkzeug.test import Client
>>> from werkzeug.testapp import test_app
>>> from werkzeug.wrappers import BaseResponse
>>> c = Client(test_app, BaseResponse)
>>> resp = c.get('/')
>>> resp.status_code
200
>>> resp.headers
Headers([('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', '8339')])
>>> resp.data.splitlines()[0]
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"'

或默認(rèn)沒(méi)有 response:

>>> c = Client(test_app)
>>> app_iter, status, headers = c.get('/')
>>> status
'200 OK'
>>> headers
[('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', '8339')]
>>> ''.join(app_iter).splitlines()[0]
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"'

環(huán)境搭建

0.5 新版功能.

交互測(cè)試應(yīng)用 最簡(jiǎn)單的方法是使用 EnvironBuilder 類。它可以創(chuàng)建標(biāo)準(zhǔn) WSGI環(huán)境和請(qǐng)求對(duì)象。

下面的例子創(chuàng)建了一個(gè)上傳文件和文件表單的 WSGI 環(huán)境:

>>> from werkzeug.test import EnvironBuilder
>>> from StringIO import StringIO
>>> builder = EnvironBuilder(method='POST', data={'foo': 'this is some text',
...      'file': (StringIO('my file contents'), 'test.txt')})
>>> env = builder.get_environ()

返回的環(huán)境是一個(gè)新的 WSGI 環(huán)境,可用于進(jìn)一步的處理:

>>> from werkzeug.wrappers import Request
>>> req = Request(env)
>>> req.form['foo']
u'this is some text'
>>> req.files['file']
<FileStorage: u'test.txt' ('text/plain')>
>>> req.files['file'].read()
'my file contents'

當(dāng)你將一個(gè)字典傳給構(gòu)造函數(shù)數(shù)據(jù), EnvironBuilder 會(huì)自動(dòng)自動(dòng)找出內(nèi)容類型。如過(guò)你傳的似乎一個(gè)字符串或者輸入字符流,你不得不自己來(lái)做這些處理。

默認(rèn)地它將會(huì)嘗試使用 application/x-www-form-urlencoded ,如果文件被上傳則只使用 multipart/form-data :

>>> builder = EnvironBuilder(method='POST', data={'foo': 'bar'})
>>> builder.content_type
'application/x-www-form-urlencoded'
>>> builder.files['foo'] = StringIO('contents')
>>> builder.content_type
'multipart/form-data'

如果傳入一個(gè)字符串(或一個(gè)輸入流),你必須自己指定內(nèi)容的類型:

>>> builder = EnvironBuilder(method='POST', data='{"json": "this is"}')
>>> builder.content_type
>>> builder.content_type = 'application/json'

測(cè)試 API

class tests.EnvironBuilder(path='/', base_url=None, query_string=None, method='GET', input_stream=None, content_type=None, content_length=None, errors_stream=None, multithread=False, multiprocess=False, run_once=False, headers=None, data=None, environ_base=None, environ_overrides=None, charset='utf-8')
這個(gè)類為了測(cè)試可以方便的創(chuàng)建一個(gè) WSGI 環(huán)境。他可以從任意數(shù)據(jù)快速創(chuàng)建 WSGI環(huán)境或請(qǐng)求對(duì)象。

這個(gè)類的簽名也可用于 Werkzeug 的其他地方(create_environ(), BaseResponse.from_values(), Client.open())。因?yàn)榇蠖鄶?shù)功能只可通過(guò)構(gòu)造函數(shù)實(shí)現(xiàn)。

文件和表格數(shù)據(jù)可以被各自的 form 和 files 屬性獨(dú)立處理。但是以相同的參數(shù)傳入構(gòu)造函數(shù):data。

data 可以是這些值:

  • a str: 如果一個(gè)字符串被轉(zhuǎn)化為一個(gè) input_stream,將會(huì)設(shè)置content_length ,你還要提供一個(gè) content_type。
  • a dict: 如果是一個(gè)字典,鍵將是一個(gè)字符串,值是以下對(duì)象:

  • 一個(gè) file-like 對(duì)象。他們會(huì)被自動(dòng)轉(zhuǎn)化成 FileStorage 對(duì)象。
  • 一個(gè)元組。 add_file() 方法調(diào)用元組項(xiàng)目作為參數(shù)。

0.6 新版功能: path 和 base_url 現(xiàn)在是 unicode 字符串,它可以使用 iri_to_uri()函數(shù)編碼。

參數(shù):
  • path – 請(qǐng)求的路徑。在 WSGI 環(huán)境它等效于 PATH_INFO。如果 query_string沒(méi)有被定義,這里有一個(gè)問(wèn)題要注意,path 后面的將被當(dāng)作 query string
  • base_url – base URL 是一個(gè)用于提取 WSGI URL ,主機(jī) (服務(wù)器名 + 服務(wù)端口)和根腳本的 (SCRIPT_NAME) 的 URL。
  • query_string – URL 參數(shù)可選的字符串和字典。
  • method – HTTP 方法,默認(rèn)為 GET
  • input_stream – 一個(gè)可選輸入流。不要指定它,一旦輸入流被設(shè)定,你將不能更改 args 屬性和 files 屬性除非你將input_stream 重新設(shè)為 None 。
  • content_type – 請(qǐng)求的內(nèi)容類型。在0.5 版本當(dāng)你指定文件和表格數(shù)據(jù)的時(shí)候不必必須指定他。
  • content_length – 請(qǐng)求的內(nèi)容長(zhǎng)度。當(dāng)通過(guò) data 提供數(shù)據(jù)不必必須指定他。
  • errors_stream – 用于 wsgi.errors 可選的錯(cuò)誤流。默認(rèn)為 stderr。
  • multithread – 控制 wsgi.multithread。默認(rèn)為 False。
  • multiprocess – 控制 wsgi.multiprocess。默認(rèn)為 False
  • run_once – 控制 wsgi.run_once。默認(rèn)為 False。
  • headers – headers 一個(gè)可選的列表或者 Headers 對(duì)象。
  • data – 一個(gè)字符串或者表單數(shù)據(jù)字典。看上邊的 explanation。
  • environ_base – 一個(gè)可選的默認(rèn)環(huán)境。
  • environ_overrides – 一個(gè)可選的覆蓋環(huán)境。
  • charset – 編碼 unicode 數(shù)據(jù)的字符集。

path
應(yīng)用的地址。(又叫 PATH_INFO)

charset
編碼 unicode 數(shù)據(jù)的字符集。

headers
一個(gè)帶著請(qǐng)求 headers的 Headers 對(duì)象。

errors_stream
用于 wsgi.errors 流的錯(cuò)誤流。

multithread
wsgi.multithread 的值。

multiprocess
wsgi.multiprocess 的值。

environ_base
新創(chuàng)建環(huán)境的基本字典。

environ_overrides
用于覆蓋生成環(huán)境的帶值字典。

input_stream
可選選項(xiàng)輸入流。這個(gè)和 form / files 是相互獨(dú)立的。同時(shí)如果請(qǐng)求方法不是 POST / PUT 或其他類似方法,不要提供輸入流。

args
URL 參數(shù)是 MultiDict。

base_url
base URL 是一個(gè)用于提取 WSGI URL ,主機(jī)(服務(wù)器名 + 服務(wù)器端口) 和根腳本 (SCRIPT_NAME) 的 URL

close()
關(guān)閉所有文件。如果把 file 對(duì)象放入 files 字典,你可以通過(guò)調(diào)用這個(gè)方法自動(dòng)關(guān)閉他們。

content_length
整數(shù)的長(zhǎng)度,反射給 headers。如果你設(shè)置了 files 或 form屬性不要設(shè)置這個(gè)參數(shù)。

content_type
請(qǐng)求的內(nèi)容類型。反射給 headers。如果你設(shè)置了 files 和form 屬性就不能設(shè)置內(nèi)容類型。

get_environ()
返回內(nèi)置環(huán)境。

get_request(cls=None)
返回一個(gè)帶數(shù)據(jù)的請(qǐng)求。如果沒(méi)有指定請(qǐng)求類,將會(huì)是用 request_class。

input_stream
一個(gè)可選的輸入流。如果你設(shè)置它,將會(huì)清空 form 和 files。

query_string
查詢字符串。如果你設(shè)置它, args 屬性將不再可用。

request_class
默認(rèn)的請(qǐng)求類 get_request()。

BaseRequest 的別名

server_name
服務(wù)器名 (只讀, 使用 host 設(shè)置)

server_port
整型服務(wù)器接口(只讀,使用 host 設(shè)置)

server_protocol = 'HTTP/1.1'
服務(wù)器使用協(xié)議。默認(rèn)為 HTTP/1.1

wsgi_version = (1, 0)
使用的 WSGI 版本。默認(rèn)為(1, 0)。

class tests.Client(application, response_wrapper=None, use_cookies=True, allow_subdomain_redirects=False)
這個(gè)類允許你發(fā)送請(qǐng)求給一個(gè)包裹的應(yīng)用。

響應(yīng)可以是一個(gè)類或者一個(gè)有三個(gè)參數(shù)工廠函數(shù): app_iter, status and headers。默認(rèn)的響應(yīng)僅僅是一個(gè)元組。

例如:

class ClientResponse(BaseResponse):
     ...

 client = Client(MyApplication(), response_wrapper=ClientResponse)

use_cookies 參數(shù)默認(rèn)是開(kāi)啟的,無(wú)論 cookies 是否被存儲(chǔ),他都會(huì)和請(qǐng)求一起傳輸。但是你也可以關(guān)閉 cookie。

如果你想要請(qǐng)求應(yīng)用的子域名,你可以設(shè)置 allow_subdomain_redirects 為 True ,如果為 False ,將不允許外部重定向。

0.5 新版功能: use_cookies 是在這個(gè)版本添加的。老版本不提供內(nèi)置 cookie 支持。

open(options)
EnvironBuilder 一樣的參數(shù)還有一些補(bǔ)充: 你可以提供一個(gè)EnvironBuilder 類或一個(gè) WSGI 環(huán)境代替 EnvironBuilder類作為參數(shù)。同時(shí)有兩個(gè)可選參數(shù) (as_tuple, buffered),可以改變返回值的類型或應(yīng)用執(zhí)行方法。

在 0.5 版更改: 如果為 data 參數(shù)提供一個(gè)帶文件的字典,那么內(nèi)容類型必須為 content_type而不是 mimetype。這個(gè)改變是為了和 werkzeug.FileWrapper 保持一致。

follow_redirects 參數(shù)被添加到 open().

Additional parameters:

參數(shù):
  • as_tuple – 在表格中返回一個(gè)元組 (environ, result)。
  • buffered – 把這個(gè)設(shè)為 True 來(lái)緩沖區(qū)運(yùn)行應(yīng)用。這個(gè)將會(huì)為你自動(dòng)關(guān)閉所有應(yīng)用。
  • follow_redirects – 如果接下來(lái) Client HTTP 重定向,這個(gè)將會(huì)設(shè)為 True。

get(options)
和 open 相似,但是方法強(qiáng)制執(zhí)行 GET。

post(options)
和 open 相似,但是方法強(qiáng)制執(zhí)行 POST。

put(options)
和 open 相似,但是方法強(qiáng)制執(zhí)行 PUT。

delete(options)
和 open 相似,但是方法強(qiáng)制執(zhí)行 DELETE。

head(options)
和 open 相似,但是方法強(qiáng)制執(zhí)行 HEAD。

tests.create_environ([options])
根據(jù)傳入的值創(chuàng)建一個(gè) WSGI 環(huán)境。第一個(gè)參數(shù)應(yīng)該是請(qǐng)求的路徑,默認(rèn)為 ‘/'。另一個(gè)參數(shù)或者是一個(gè)絕對(duì)路徑(在這個(gè)例子中主機(jī)是 localhost:80)或請(qǐng)求的完整路徑,端口和腳本路徑。

它和 EnvironBuilder 構(gòu)造函數(shù)接受相同的參數(shù)。

在 0.5 版更改: 這個(gè)函數(shù)現(xiàn)在是一個(gè) EnvironBuilder 包裹,在 0.5 版本被添加。需要 headers, environ_base, environ_overrides 和 charset 參數(shù)。

tests.run_wsgi_app(app, environ, buffered=False)
返回一個(gè)應(yīng)用輸出的元組形式 (app_iter, status, headers)。如果你通過(guò)應(yīng)用返回一個(gè)迭代器他將會(huì)工作的更好。

有時(shí)應(yīng)用可以使用 start_ewsponse 返回的 write() 回調(diào)函數(shù)。這將會(huì)自動(dòng)解決邊界情況。如果沒(méi)有得到預(yù)期輸出,你應(yīng)該將 buffered 設(shè)為 True 執(zhí)行buffering

如果傳入一個(gè)錯(cuò)誤的應(yīng)用,這個(gè)函數(shù)將會(huì)是未定義的。不要給這個(gè)函數(shù)傳入一個(gè)不標(biāo)準(zhǔn)的 WSGI 應(yīng)用。

參數(shù):
  • app – 要執(zhí)行的應(yīng)用。
  • buffered – 設(shè)為 True 來(lái)執(zhí)行 buffering.
返回:

元組形式 (app_iter, status, headers)

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)