はじめに
現在、最も人気のあるクライアントテストソリューションはセレンです。 それが十分に価値があることは注目に値します。セレンがWebドライバーと組み合わせて提供する機会は、Webアプリケーションとのユーザーインタラクションのほぼ全範囲をカバーします。
小規模なプロジェクトの場合、ブラウザプラグインのオプションは優れており、サードパーティのコンポーネント( UI-elementなど )を追加することで機能を拡張できます。 しかし、プロジェクトが十分に大きくなり、ページ構造またはデータ送信の方法が変更されるたびに、多くの部分が繰り返し変更され、完全に再ソーシングされると、テストのブロック全体をすぐに置き換えて、ほぼすべてのテストを調べる必要があります。 このようなセレンの後、プラグインはもはやそれほど便利ではないようです。 そして、ここで、セレンライブラリが助けになり、Web開発に関連する多くの言語に実装されています(公式Webサイトのドキュメント )
python-seleniumがレタスライブラリとともに提供するクライアントテスト(特にdjangoプロジェクト)の機能を確認することをお勧めします。
レタス+セレン
これらのコンポーネントが個別に提供する機能を見てみましょう。
Pythonセレン
- 上記のように、セレンにはブラウザを介したWebアプリケーションとの豊富な相互作用があります
- プラグインとは異なり、広範なPython機能を使用できます。
- プロジェクト自体との統合
レタス
- テストの疎結合部分への分離
- テストの各段階の制御
- ターミナルの美しい出力:)
そしてすぐに戦いに
例として単純な登録および承認テストを使用して、レタス+セレンを使用する主な側面を実証しようとします。
問題の声明
次のアクションを実行する2つのテストを作成する必要があります。
登録:
- 登録ページに移動します
- 登録フォームのフィールドに入力します
- 登録ボタンをクリックしてください
- 登録の成功に関するメッセージを見る
認可:
- ログインページに移動します
- 認証フォームのフィールドに入力します
- 認証ボタンをクリックします
- 承認の成功に関するメッセージを表示
問題の声明からすでに、これら2つのテストは類似したアクションを実行するが、異なるコンテキストで実行されていることがわかります。 タスクに取りかかりましょう。
タスク完了
公式ドキュメントに記載されているように、djangoプロジェクトにレタスを追加し、必要な依存関係(この場合は、FirefoxシステムパッケージとPythonモジュールレタスとセレン)をすべてインストールすることで、テストの作成を開始できます。
PS:ヘッドレスモードで実行するにはxvfbとpyvirtualdisplayが必要です
レタスを使用するには、次のファイルを作成する必要があります。
- プロジェクトのルートにあるterrain.pyには、指定されたテスト段階で実行される命令が含まれています
- * myapp / featuresフォルダー内の.featureファイルには、各テストの段階的な説明が含まれています
- * myapp / featuresフォルダー内の.pyファイルには、* .featureファイルで使用されるステップの説明が含まれています。
私からは、アプリケーションのページの構造を含むファイルをプロジェクトに含めることをお勧めします(セレンで使用されるPageObjectに似ています)。 このファイルをmapping.pyと呼び、プロジェクトのルートに配置します。 ページ構造をテストから分離することで、レイアウトを変更するときにテスト自体を書き換える必要が減ります。mapping.pyの対応するページを修正するだけです。 また、テストの可読性も大幅に向上します(これについては、後ほど明らかにします)。
mapping.py
host_url = 'http://example.com' site_mapping = { "registration": { "url": host_url + "/registration/", "username": "//input[@id='username']", "email": "//input[@id='email']", "password": "//input[@name='password1']", "verify password": "//input[@name='password2']", "signup button": "//button[@name='signup']", "status message": "//div[@id='status']", }, "authorization": { "url": host_url + "/login/", "username": "//input[@id='username']", "password": "//input[@name='password']", "login button": "//button[@name='login']", "status message": "//div[@id='status']", }, }
PS:私はxpathを使用しています これが要素を見つける最良の方法だと思います
terrain.py
from lettuce import before, after, world from selenium import webdriver from mapping import site_mapping @before.harvest def setup(server): # world - , lettuce , .. world.browser = webdriver.Firefox() # world.mapping = site_mapping # world @after.all def teardown(total): world.browser.close() #
myapp / features / auth.feature
Feature: Authorization Scenario: Registration Open "registration" page Fill "username" with "myusername" Fill "email" with "user@example.com" Fill "password" with "1234" Fill "verify password" with "1234" Click "signup button" See "Welcome aboard" in "status message" Scenario: Authorization Open "authorization" page Fill "username" with "myusername" Fill "password" with "1234" Click "login button" See "Hello! Again..." in "status message"
ご覧のとおり、要素の場所に関する情報の欠如がスクリプトの可読性に影響を与えました。 mapping.pyに感謝します
myapp / features / steps.py
from lettuce import step, world @step(r'Open "(.*)" page') def open_page(step, page): world.current_page = world.mapping[page] # url world.browser.get(world.current_page['url']) # url @step(r'Fill "(.*)" with "(.*)"') def fill_element_with_text(step, element, value): elem = world.browser.find_element_by_xpath(world.current_page[element]) elem.send_keys(value) @step(r'Click "(.*)"') def i_click_xpath(step, element): elem = world.browser.find_element_by_xpath(world.current_page[element]) elem.click() @step(r'See "(.*)" in "(.*)"') def i_see_text_in_element(step, text, element): elem = world.browser.find_element_by_xpath(world.current_page[element]) assert elem.text == text
以上です。 テストを実行し、どのようにテストが成功する(または失敗する)かを確認するだけです。
ジェスチャが多すぎるため、2つのテストを記述できないようです。 しかし、プロジェクトを多数のテストでカバーしたい場合、スクリプトとステップを作成するときに、新しいステップを作成する必要が少なくなります。 サイトでのユーザーとのやり取りのほとんどすべては、既存の手順で既に説明されています-残っているのは、新しいスクリプトを書くことだけです。
まとめ
バランスにあるもの:
- 開発者とテスターの両方が使用できるツール。
- mapping.pyのおかげで、サイト全体のレイアウトと構造の変更に対する高い耐性
- ほとんどすべてのテストを実行できます。 Firefox、chrome、phantomjs(他のオプションがあるかもしれませんが、これは私が試したものです)。
- どこでもテストを実行できます:コンピューター、仮想マシン、リモートサーバー
- テスト実行ごとに、テストデータベースを作成し、アプリケーションの個別のインスタンスを含め、テストデータをロードし、最後にこれらすべてを安全に削除できます(テストフレームワークはdjango自体で行うように)。
- ログストレージを接続できます。 また、この非同期タスクと一致する場合、N時間ごとにプロジェクト全体のステータスに関する情報を受け取ることができます。
- ステップの大きなデータベース(steps.py)では、TKを「翻訳」するのに非常に簡単に記述できるスクリプトのみを記述するだけで十分です。
- このようなテストを1つのプロジェクトに展開しても、それらを別のプロジェクトに転送するのは難しくありません。 新しいプロジェクトに移植する場合、スクリプト作成に最も時間がかかりますが、それほど難しくはないようです(たとえば、セレンプラグインでさらに100個のテストを作成する場合と比較して)
トピックに関する役立つリンク:
PS:誰かがこのトピックに興味を持ち、レタス+セレンを使用して遭遇した落とし穴について合理的に書いてくれることを願っています。 ご質問にお答えできることを嬉しく思います。
PPS:プレゼンテーション、句読点、および一般的なスタイルについて事前に謝罪します。 最初の記事とそのすべて...