2017-04-07 18 views
0

カスタムHTTPサーバの動作をテストするためのツールセットを書いています。これは、適切なレスポンスコード、ヘッダフィールドなどを設定しているかどうかです。テスト。py.test:フィクスチャからテストを生成する方法

目的はいくつかのリソースにリクエストを行い、複数のテストでレスポンスを評価することです。各テストはHTTPレスポンスの1つの側面をテストする必要があります。しかし、すべての応答がすべてのテストでテストされるわけではなく、その逆もありません。

同じHTTPリクエストを複数回送信してHTTP応答メッセージを再利用しないようにするには、pytestのフィクスチャを使用することを考えています。また、pytestのテスト機能を使用したい異なるHTTP応答で同じテストを実行します。 輸入pytest インポート要求

def pytest_generate_tests(metafunc): 
    funcarglist = metafunc.cls.params[metafunc.function.__name__] 
    argnames = sorted(funcarglist[0]) 
    metafunc.parametrize(argnames, [[funcargs[name] for name in argnames] 
            for funcargs in funcarglist]) 


class TestHTTP(object): 
    @pytest.fixture(scope="class") 
    def get_root(self, request): 
     return requests.get("http://test.com") 

    @pytest.fixture(scope="class") 
    def get_missing(self, request): 
     return requests.get("http://test.com/not-there") 

    def test_status_code(self, response, code): 
     assert response.status_code == code 

    def test_header_value(self, response, field, value): 
     assert response.headers[field] == value 

    params = { 
     'test_status_code': [dict(response=get_root, code=200), 
          dict(response=get_missing, code=404), ], 
     'test_header_value': [dict(response=get_root, field="content-type", value="text/html"), 
           dict(response=get_missing, field="content-type", value="text/html"), ], 
    } 

問題のparamsの定義にあるように表示されます。dict(response=get_root, code=200)と同様の定義が気付いていない、私は実際の関数のリファレンスに上治具にバインドしたいと思います。

テストを実行しているとき、私はエラーのこの種類を取得:

________________________________________________ TestHTTP.test_header_value [コンテンツタイプ-response0-text/htmlの] _________________________________________________私が取るpytestを説得する方法

self = <ev-question.TestHTTP object at 0x7fec8ce33d30>, response = <function TestHTTP.get_root at 0x7fec8ce8aa60>, field = 'content-type', value = 'text/html' 

    def test_header_value(self, response, field, value): 
>  assert response.headers[field] == value 
E  AttributeError: 'function' object has no attribute 'headers' 

test_server.py:32: AttributeError 

関数の代わりにフィクスチャの値?

答えて

1

ちょうどあなたのフィクスチャをパラメータ化し、それが返す値のための定期的なテストを書き、fixtuesからテストを生成する必要はありません:

import pytest 
import requests 


should_work = [ 
    { 
     "url": "http://test.com", 
     "code": 200, 
     "fields": {"content-type": "text/html"} 
    }, 
] 

should_fail = [ 
    { 
     "url": "http://test.com/not-there", 
     "code": 404, 
     "fields": {"content-type": "text/html"} 
    }, 
] 

should_all = should_work + should_fail 


def response(request): 
    retval = dict(request.param) # {"url": ..., "code": ... } 
    retval['response'] = requests.get(request.param['url']) 
    return retval # {"reponse": ..., "url": ..., "code": ... } 


# One fixture for working requests 
response_work = pytest.fixture(scope="module", params=should_work)(response) 
# One fixture for failing requests 
response_fail = pytest.fixture(scope="module", params=should_fail)(response) 
# One fixture for all requests 
response_all = pytest.fixture(scope="module", params=should_all)(response) 


# This test only requests failing fixture data 
def test_status_code(response_fail): 
    assert response_fail['response'].status_code == response_fail['code'] 


# This test all requests fixture data 
@pytest.mark.parametrize("field", ["content-type"]) 
def test_header_content_type(response_all, field): 
    assert response_all['response'].headers[field] == response_all['fields'][field] 
+0

は、ニルス、ありがとうございました。しかし、このコードは、私が望むものではないすべてのフィクスチャに対してすべてのテストを実行します。どのテストとどのフィクスチャを組み合わせるかを指定したいと思います。議論のために、通常のリクエストで戻りコードをチェックしたくないと想像してください。404を返さなければならないものだけを返すようにしてください。また、それぞれのテストで応答の1つの側面だけをチェックします。アサーションを1つだけ実行します。したがって、あるヘッダーが見つからない場合は、そのヘッダーのみ、他のヘッダーはテストが合格するというエラーが表示されます。 – David

+0

私は、 'response'オブジェクトが' key'を持っているかどうかを確認するために 'key in response'をチェックすることはできません。もしそうなら、' pytest.skip() 'することができます。 – David

+0

リクエストごとに戻り値をテストしてみませんか?特定の条件の特別な扱いが少ないほど、間違いを起こす可能性は低くなります。 –

関連する問題