web-dev-qa-db-ja.com

スクレイパーをテストするためにサイトを模擬するための推奨アプローチ

Subj。 Atm私はSeleniumとPythonを使用していますが、同じことが他のスクレイピングソリューションにも当てはまります。

不思議なんだけど:

  1. 以下に概説されているオプションのうち、最適/推奨/ベストプラクティスはどれですか
  2. 既存のソリューション/ヘルパーライブラリがある場合、どのキーワードで検索するか。

客観性を維持するために、「最適/推奨/ベストプラクティス」とは、「ニッチな分野で注目を集めているプロジェクトによって広く使用されているか、推奨されているか、推奨されているか」を意味します。

このトピックに関するSelenium関連または汎用の資料を見つけることができなかったため、ネット検索に1日ほど費やしたため、重要な情報が不足している可能性があります。


スクレイピングの基本的な操作は次のとおりです。

  • 要素を検索する(CSSセレクター/ XPathを使用して、および/または手動でそれらができないことを検索する)
  • 要素との相互作用(入力テキスト、クリック)
  • 要素データを読み取る

コールチェーンは次のようになります。

(テストコード->)ユーザーコード->フレームワーク(セレン)->ブラウザ(ウェブドライバ)->サイト


だから、私が模倣できる3つのホップがあります。それぞれに課題があります。

  • サイトのモックを作成する:ローカルHTTPサーバーを起動し、そこにブラウザーを誘導する
    • スクレイピングされたサイトのインターフェースをWebテクノロジーで再実装する必要がある
  • ブラウザーをモックします(例:HtmlUnit(インプロセスブラウザーエンジン)に適切なタイミングで事前定義されたHTMLを入力します)
    • はるかに単純ですが、何らかの方法で状態遷移/アクション反応をエミュレートする必要があります
  • フレームワーク呼び出しをモックする
    • ユニットテストの哲学に最も忠実で、最小限の作業
    • ただし、制限が多すぎるのではないかと心配しています。例えば。いろいろな方法で同じ要素を見つけることができます。モックオブジェクトは、非常に具体的な一連のアクションしか受け入れることができません。他のセレクタが同じ結果を生成するかどうかを確認してください。

提供するコンテンツには2つのオプションもあります。

  • テストクエリ用に作成したサイトの元のコンテンツを提供し、ある種のパッケージまたは自己完結型パッケージにコンパイルします
    • 労働集約的でエラーが発生しやすい、または
  • テストされたアルゴリズムを満たすための最小限の情報を提供する
    • はるかに単純ですが、実際のサイトで成功する他の可能なアルゴリズムでは失敗します

最後の懸念の1つは、サイトが事実上状態マシンであるという事実です。私はどちらがより便利になるかわかりません:

  • おそらく何らかの仕様として完全な状態マシンを実装し、テストでその状態を設定/チェックします
    • 正式な仕様を書くための作業を軽減する、なんらかのライブラリなしで非常に労働集約的。または
  • アクションシーケンスを検証するだけです
    • 実際にはコードを何に対してもテストしていないようです-それは単にコードが何をするかを繰り返すだけです

表明された懸念に対処するための更新:

私はサードパーティのサイトをスクレイピングしています-いつの日か予告なしに変更される可能性があり、変更される可能性があります。したがって、「執筆時のサイトのインターフェイス」に対するテストで問題はありません。コードの変更がスクレイパーの内部ロジックに違反していないかどうかをすばやく確認するためです。

5
ivan_pozdeev

c796112 で@RobertHarveyによって与えられたアイデアは、サイトをまったく模倣しないことです。

目的がスクレーパーの内部ロジックをテストすることである場合、それを正確にテストします:

  • 基本ページ操作を直接実装するコードをサブルーチンに分割し、それらを模擬します。
    • アイデアは、これらのサブルーチンを可能な限り単純にして(事実上、栄光のセレクター/ XPath)、テストなしで実行できるようにすることです。

あなたのスキームでは、それは「ユーザーコード->フレームワーク」ホップから一歩高くなります:User code -> Elementary page operations -> Framework

0
ivan_pozdeev

あなたは細部をからかって夢中になることができます。多くの複雑なテストケースを考えると、それはおそらく実現可能ではありません。

可能な場合は、実際のテスト入力全体を記録し、編集して無関係な詳細を取り除き、完全なスクレイピングエンジンで実行することをお勧めします。サイトの表現方法と再生方法は、これらのテストに必要な忠実度によって異なります。例えば。サイトが複数のドメインにAjaxリクエストを行うことが予想される場合、これは非常に困難な場合があります。

たとえば、スクレイピングするページのHTMLを保存するだけで済む場合があります。極端なケースでは、サイトが行うすべてのHTTPリクエストをログに記録して再生する必要があります。つまり、サイトがリクエストを作成し、ライブサイトから記録したレスポンスを再生します。

すべての場合において、あなたが主張することは、あなたのスクレーパーがページから正しいデータを抽出したということです。そこに到達する方法は二次的なものになるでしょう。

これらの高度なテスト方法の利点は、

  • 彼らは非常に現実的です
  • テストスイートがセットアップされたら、別のテストケースを追加するのにそれほどの労力は必要ありません。

不利な点は、これらのテストがやや遅い–ライブサイトへの実際のリクエストを実行するよりもはるかに高速ですが、スクレイパーのターゲットを絞った単体テストよりも低速です。

時間の経過とともに、現実的なテストケースのコーパスを成長させることができます。テストケースが役に立たなくなった場合(ライブサイトが変更されたためなど)、いつでも破棄できます。

1
amon

ここでスクレーパーの意味がわかりません。 Selenium/Javaを使用してUIオートメーションを開発するとき-単体テストを定義します。 Webアプリケーションがあり、Seleniumテストを作成して、ログインの成功、無効なログインなどを確認したとします。次に、実行中の既存のWebアプリケーションを実際にテストして、何かがダウンしたり壊れたりしたことを警告し、予想と同期しなくなりました。

一方、私はそれが必ずしもSeleniumベースであるとは限らないことをスクレーパーで書いていました。私は基本的なHttp呼び出しを使用して、ページにアクセスし、HTMLを取得し、正規表現を使用してデータを抽出し、csv/jsonにデータを保存してから、ホテルやショップの価格を収集するなどの処理を行いました。

Javaのモックは、単体テストを個別に実行するための依存関係をシミュレートするためのものです。ATM操作があり、実際のカードを挿入して実際の残高を表示する代わりに、bankServiceのモックオブジェクトを作成して、定義済みの模擬残高を返します。 、「モック」カードを事前に定義されたデータとともにATMに挿入します。モックの目的は、遅延なくユニットテストを行うことです。スクレイパーとサイトのモックの意味がわかりません。サイトは構築されますが、配置されませんか?次にSeleniumテストを記述し、適切な要素名を定義して、サイトの稼働中にそれらを有効にします。

通常、開発者は開発用にサーバーのローカルインスタンスを実行するため、モックサイトの目的がわかりません。開発、品質、本番環境があります。

ええと、QAチームでの作業は、基本的にはそこにあるものをカバーするため、事前に定義されたシナリオをチェックし、何かがダウンしたり、開発者によって破損した場合に警告します。または、テスト駆動開発に使用します。一連のビジネスルールを定義すると、多くのことを実装している間に、環境に配慮してテストに合格します。

Seleniumでは、UIパーツをテストするだけだと思います。これは、手動テスターが行う自動バージョンです。

サーバー側は、単体テスト、統合テストでカバーされており、バックエンドコードの動作を検証する単体テストのモックがありますが、Seleniumとは関係ありません。 SeleniumはUIテスト用です。

0
Flamaker2018