3

2 つの異なるサービス (CKAN と MediaWiki) からデータを取得するために 2 つの異なる API で動作するプログラムを Python で作成しました。特に、上記のサービスからデータを要求して処理する Resource クラスがあります。

ある時点で、アプリのテストが必要であるという結論に達しました。そして問題は、私がウェブや本で見つけたすべての例がそのようなケースを扱っていないことです.

たとえば、 Resource クラス内に次のメソッドがあります。

def load_from_ckan(self):
    """
        Get the resource
        specified by self.id
        from config.ckan_api_url 
    """
    data = json.dumps({'id': self.id})
    headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
    url = config.ckan_api_url + '/action/resource_show'
    r = requests.post(url, timeout=config.ckan_request_timeout, data=data, headers=headers)
    assert r.ok, r
    resource = json.loads(r.content)
    resource = resource["result"]
    for key in resource:
        setattr(self, key, resource[key])

load_from_ckan メソッドは、CKAN API からリソースに関するデータを取得し、それをオブジェクトに割り当てます。シンプルですが...

私の質問は次のとおりです。このようなメソッドをテストする方法は? または、ここで何をテストする必要がありますか?

結果をHDDにピクル(保存)する可能性を考えました。次に、テストでそれをロードし、load_from_ckan() で初期化されたオブジェクトと比較できます。しかし、CKAN はコミュニティ主導のプラットフォームであり、そのようなテストの動作は予測できません。

自動テストの哲学 (何をテストし、何をテストしないか、テストを意味のあるものにする方法など) に関する本があれば、リンクを教えてください。

4

3 に答える 3

2

どのようなテストでも、重要な問題は実際には、何問題になる可能性があるかということです。

あなたの場合、3 つのリスクは次のように見えます。

  • 問題の Web API が機能しなくなる可能性があります。しかし、あなたはすでにこれをチェックしていassert r.okます.
  • あなたまたは他の誰かが、コードを壊してしまうような誤った変更 (例えば、変数の入力ミス) を将来コードに加える可能性があります。
  • API が変更され、必要なフィールドまたは形式が返されなくなる可能性があります。

実際に依存するこの API からのデータに応じて、後者の 2 つのかなり単純なテストを作成できるように感じます。ポイント摂氏番号、関数を呼び出すテストを作成し、self.temperatureが「float」のインスタンスであり、値の適切な範囲内にあることを確認できます(-30から50?)。これにより、API と関数の両方が設計どおりに機能していることを確信できます。

于 2013-02-06T23:49:28.173 に答える
1

通常、このような外部サービスに対してテストする場合は、モック/ダミーオブジェクトを使用して外部サービスのAPIを偽造する必要があります。これは、実行時に、メソッドの引数、クラスのコンストラクター、または別のタイプの間接参照のいずれかを介して構成可能である必要があります。もう1つのより複雑なオプションは、「import requests; request.post = fake_post」のように、テスト中にグローバルパッチにモンキーパッチを適用することですが、それによってさらに問題が発生する可能性があります。

したがって、たとえば、メソッドは次のような引数を取ることができます。

def load_from_ckan(self, post=requests.post):
    # ...
    r = post(url, timeout=config.ckan_request_timeout, data=data,
        headers=headers)
    # ...

次に、テスト中に、ckanから戻ってくるjsonの結果を返す独自のpost関数を作成します。例えば:

 def mock_post(url, timeout=30, data='', headers=None):
     # ... probably check input arguments
     class DummyResponse:
         pass
     r = DummyResponse()
     r.ok = True
     r.content = json.dumps({'result': {'attr1': 1, 'attr2': 2}})
     return r

テストで結果を作成すると、結果を取得して返すよりもはるかに柔軟性があります。これは、エラー条件を作成したり、コードが予期しない特定の形式に焦点を合わせたりできるためですが、存在する可能性はあります。

全体として、これがどれほど複雑になる可能性があるかがわかるので、エラーやその他の問題が繰り返し発生する場合にのみ、この種のテストを追加し始めます。これにより、維持する必要のあるコードが増えるだけです。

于 2013-02-07T00:08:04.263 に答える
0

この時点で、CKAN からの応答が適切に解析されていることをテストできます。そのため、CKAN から JSON を取得して、関心のある属性を含むデータが返されていることを確認できます。

于 2013-02-06T23:45:35.600 に答える