0

Web ページをスクレイピングしてデータをファイルに保存する方法があります (コード例については以下を参照してください)。結果のデータが整形式であることをテストする必要があります。

問題は、データが一連の呼び出しから受信され、その後の呼び出しで前の呼び出しの結果が使用されることです。さらに悪いことに、関連する呼び出しの多くは、同じオブジェクト ( a Webdriver、 a 、WebDriverWaitおよびexpected_conditionsモジュール) に対して異なる引数で行われます。

私はそれを見るunittest.mock.Mock単純な呼び出しまたは一連の単純な呼び出しの結果をモックすることはできますが、このように絡み合ったものを実装する方法がわかりません。私が見る唯一の方法は、メソッドが行うすべての呼び出しを手動で再実装し、メソッドで渡す引数をそれらの実装にコピーして、呼び出しごとに何を返すかを知ることです。そして、他のすべてのテスト ケースに対してこれを繰り返します。これは、書いて維持するのは絶対的な悪夢のように思えます: テスト自体よりも数倍多くのコードがあり、コードとほぼ 1:1 の重複があります。だから私は、誰かがもっと良い方法があると言うか、何もないことを証明し、誰もが本当にこのようにしていることを証明するまで先に進むことを拒否し (私は信じていません)、たとえば、ページのラベルが変更されるたびにすべてのテストを書き直します (これは実装の詳細であるため、通常はそうすべきです」

サンプルコード ( http://example.comに適応):

import selenium.webdriver
from selenium.webdriver.common.by import By as by
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


def dump_accreditation_data(d, w, i, path):
    f = codecs.open(os.path.join(path, "%d.txt" % i), "w", encoding="utf-8")

    u = u'http://example.com/%s/accreditation' % i
    d.get(u)

    # page load
    w.until(EC.visibility_of_element_located((by.XPATH,"//p")))    #the real code has a more complex expression here with national characters
    w.until_not(EC.visibility_of_element_located((by.CSS_SELECTOR, '.waiter')))
    print >> f, u

    # organization name
    e = w.until(EC.visibility_of_element_located((
        by.CSS_SELECTOR, 'h1'
    )))
    org_name = e.text
    print >> f, org_name
    del e

    #etc
    e = d.find_element_by_xpath(u'//a[text()="More information..."')
    print >> f, e.get_attribute('href')

#How it's supposed to be used:
d = selenium.webdriver.Firefox()
w = WebDriverWait(d, 10)
dump_accreditation_data(d, w, 123, "<output_path>")
4

1 に答える 1

1

そのままのコードについては、あなたが説明した方法で単体テストを行うことはあまり意味がありません。しかし、それは単に手間がかかるからというだけではありません。テストの目的は、間違いなく、コード内のエラーを見つけることです。単体テストの目的は、分離された単体で見つかるエラーを見つけることです。ただし、サンプル コードの重要な部分は、外部ライブラリとのやり取りに関連しています。

アルゴリズム レベルのコードは比較的少なく、たとえば次のようになります。

os.path.join(path, "%d.txt" % i)

また

u = u'http://example.com/%s/accreditation' % i

または出力ファイルのコンテンツの作成。

つまり、コードにバグがある場合、それらは相互作用レベルにある可能性が高くなります: 適切なパラメーターを使用して適切なライブラリ関数を正しい順序で呼び出す、正しい形式のパラメーターなど。 - ライブラリのモックを使用すると、ただし、モックはユーザーによって実装され、ライブラリの動作に関する (間違っている可能性がある) 理解を反映するだけなので、相互作用のバグは見つかりません。

このコードをテストするための私の提案は次のとおりです。 ライブラリとのやり取りを行うコードからアルゴリズム コードを分離します。たとえば、小さなヘルパー関数を作成して、出力ファイル名と入力 URL を計算できます。コードのインタラクションが支配する部分で、Web ページからすべてのデータを抽出し、(別の関数で) そのすべてのデータを使用して出力ファイルのコンテンツを作成することができます。

これらのヘルパー関数はすべて、単体テストを使用してテストできます。統合テストでテストする残りの機能。

于 2019-01-23T19:48:50.943 に答える