https://www.jianshu.com/p/9a03984612c1?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=weixin-timeline&from=timeline&isappinstalled=0
プロジェクト構造
用例层(测试用例)
|
Fixtures层(业务流程)
|
PageObject层
|
Utils实用方法层
使用pytest、セレン
基本
# test_baidu.py
def test_baidu(selenium): selenium.get('https://www.baidu.com') selenium.find_element_by_id('kw').send_keys('简书 韩志超') selenium.find_element_by_id('su').click()
ラン
$ pytest test_baidu.py --driver=chrome
pytest.iniのまたは構成
[pytest]
addopts = --driver=chrome
クロムのオプションを使用します
# conftest.py
import pytest
@pytest.fixture
def chrome_options(chrome_options): # 覆盖原有chrome_options chrome_options.add_argument('--start-maximized') # chrome_options.add_argument('--headless') return chrome_options
ページオブジェクト层
基本モデル
# baidu_page.py
class BaiduPage(object): search_ipt_loc = ('id', 'kw') search_btn_loc = ('id', 'su') def __init__(self, driver): self.driver = driver def input_search_keyword(self, text): self.driver.find_element(*self.search_ipt_loc).send_keys(text) def click_search_button(self): self.driver.find_element(*self.search_btn_loc).click() def search(self, text): self.input_search_keyword(text) self.click_search_button()
メソッドを呼び出します。
# test_baidu_page.py
from baidu_page import BaiduPage
def test_baidu_page(selenium): baidu = BaiduPage(selenium) baidu.search('简书 韩志超')
ページの基本クラスを使用します
# pages/base_page.py
class BasePage(object): def __init__(self, driver): self.driver = driver def input(self, element_loc, text): element = self.driver.find_element(*element_loc) element.clear() element.send_keys(text) def click(self, element_loc): self.driver.find_element(*element_loc).click()
# pages/baidu_page.py
from pages.base_page import BasePage
class BaiduPage(BasePage): search_ipt_loc = ('id', 'kw') search_btn_loc = ('id', 'su') def input_search_keyword(self, text): self.input(self.search_ipt_loc, text) def click_search_button(self): self.click(self.search_btn_loc) def search(self, text): self.input_search_keyword(text) self.click_search_button()
備品のビジネス層
# conftest.py
import pytest
from pages.baidu_page import BaiduPage()
@pytest.fixture(scope='session') def baidu_page(selenium): return BaiduPage(selenium)
と実施例層
# test_baidu_page2.py
def test_baidu_page(baidu_page): baidu_page.search('简书 韩志超') assert '韩志超' in baidu.driver.title
プログレッシブ手順
-一部は、ログインページを開く必要として、同じビジネス・プロセスのユースケースを持っている場合例相互依存関係を使用すべきではない- - >ログイン>製品ページを入力するために追加をクリック>製品メニューを追加し
、以下のように使用することは推奨されていない、と秩序を作ります実行。
def test_login():
...
def test_click_menu(): ... def test_add_goods(): ...
推奨される一般的なカプセル化工程は、各コールがステップフィクスプログレッシブ方式、次の例を実装するために使用されてもよいです。
# conftest.py
import pytest
from pages.login_page import LoginPage
from pages.menu_page import MenuPage from pages.add_goods_page import AddGoodsPage @pytest.fixture(scope='session') def login_page(selenium): return LoginPage(selenium) @pytest.fixture(scope='session') def menu_page(selenium, login_page): """登录后返回菜单页面""" login_page.login('默认用户名', '默认密码') # 也可以从数据文件或环境变量中读取 return MenuPage(selenium) @pytest.fixture(scope='session') def add_goods_page(selenium, menu_page): """从MenuPage跳到添加商品页面""" menu_page.click_menu('商品管理', '添加新商品') return AddGoodsPage(selenium)
# test_ecshop.py
def test_login(login_page): login_page.login('测试用户名', '测试密码') assert login_page.get_login_fail_msg() is None def test_add_goods(add_goods_page): add_goods_page.input_goods_name('dell电脑') add_goods_page.input_goods_category("电脑") add_goods_page.input_goods_price('3999') add_goods_page.submit() assert add_goods_page.check_success_tip() is True
ログの使用
プロジェクトに必要な出力情報はPytestフレームワークが自動的に印刷情報と出力画面やレポートをキャプチャし、より多くの標準化され、使用のログ記録とログ出力することができますが、私たちは、いくつかの中間結果と試験手順の迅速な位置を示して助けることができます。
プリントを比較すると、ロギングモジュールは、情報が段階的記録することができます。
ログレベル
実用的な方法層、層の実施形態にページオブジェクト層、フィクスチャのビジネス層は、出力ログのロギング、使用に直接使用することができます。
# test_logging.py
import logging
def test_logging(): logging.debug('调试信息') logging.info('步骤信息') logging.warning('警告信息,一般可以继续进行') logging.error('出错信息') try: assert 0 except Exception as ex: logging.exception(ex) # 多行异常追溯信息,Error级别 logging.critical("严重出错信息")
Pytestのデフォルトの表示のみがエラーに情報にグレードログ上記の警告ので、使用pytestの実行には、ログ情報はありません。
リアルタイムのログ、表示中の画面をオンにし、ログレベルを変更します。
ログイン等级:NOTSET <DEBUG <INFO <WARNING(= WARN)<ERROR <CRITICAL
# pytest.ini
[pytest]
log_cli=True
log_cli_level=INFO
pytest test_logging.pyを実行し、結果を表示します:
--------------------------------------------- live log call ----------------------------------------------
INFO root:test_logging.py:5 步骤信息
WARNING root:test_logging.py:6 警告信息,一般可以继续进行
ERROR root:test_logging.py:7 出错信息
ERROR root:test_logging.py:11 assert 0
Traceback (most recent call last):
File "/Users/apple/Desktop/demo/test_logging.py", line 9, in test_logging
assert 0
AssertionError: assert 0
CRITICAL root:test_logging.py:12 严重出错信息
デバッグログが出力されませんので、ログレベルは、INFOレベルの設定です。
異なる層を使用するログレベルのために、この方法は、ファイルパスを組み立て、実用レベルのログのデバッグ出力層であってもよく、ファイルはデータ、SQLの実行、SQLクエリ結果などを読み取ります。
出力層のPageObject情報レベルのログでは、このようなページとしてアクションを実行する、などが挙げられます。
必要に応じて器具層と出力層が必要な情報、警告、またはエラーレベル情報ケースを使用することができます。
ログフォーマット
デフォルトのログ形式は、実行時間を表示しません、我々はまた、カスタマイズ出力フォーマットをログに記録することができます。
# pytest.ini
...
log_cli_format=%(asctime)s %(levelname)s %(message)s
log_cli_date_format=%Y-%m-%d %H:%M:%S
%(asctime)s
時間、デフォルト表しSat Jan 13 21:56:34 2018
、このフォーマットを、我々は時間の形式を指定するlog_cli_date_formatを使用することができます。%(levelname)s
この条ログの表現のレベル%(message)s
コンクリート出力
Pytest test_logging.py実行が再び、次の形式で表示しました:
--------------------------------------------- live log call ----------------------------------------------
2019-11-06 21:44:50 INFO 步骤信息
2019-11-06 21:44:50 WARNING 警告信息,一般可以继续进行
2019-11-06 21:44:50 ERROR 出错信息
2019-11-06 21:44:50 ERROR assert 0
Traceback (most recent call last):
File "/Users/apple/Desktop/demo/test_logging.py", line 9, in test_logging
assert 0
AssertionError: assert 0
2019-11-06 21:44:50 CRITICAL 严重出错信息
以上のログ表示オプション
- %(Levelno)S:印刷ログレベル値
- %(パス名)S:現在、実際には、プログラムを実行する印刷経路、sys.argvの[0]
- %(ファイル名)■:現在実行中のプログラムの名前を印刷
- %(FUNCNAME)S:印刷ログ現在の機能
- %(LINENO)D:印刷ログの現在の行番号
- %(スレッド)D:印刷スレッドID
- %(のthreadName)S:印刷スレッド名
- %(プロセス)D:印刷処理ID
ファイルへのログ出力
pytest.iniで次の設定を追加します。
...
log_file = logs/pytest.log
log_file_level = debug
log_file_format = %(asctime)s %(levelname)s %(message)s
log_file_date_format = %Y-%m-%d %H:%M:%S
LOG_FILE出力ファイルパス、ファイルは、ログレベル、フォーマット、別々に提供される日付の書式に入力されます。
残念ながら、ファイルへのログ出力あなたはカバーを実行するたびに、追加モードをサポートしていません。
使用フック
フックはPytest、フック方法は一般conftest.py、固定名で書かれた実行中のプロセスを使用して変更することができます。
フックメソッドのPytestは、6つのレベルに分けられます。
- この方法のガイドフック
- フックメソッドの初期化
- フックを収集する方法使用時の例
- テスト実行のフックメソッド
- レポートを生成するときの方法をフック
- フックメソッド時にブレークポイントのデバッグ
フックメソッドPytest完全なAPI、あなたはを参照することができます:APIリファレンスフック-04-(フック)
設定を変更
以下の方法では、動的テストレポート生成の名前を示しています。
# conftest.py
import os
from datetime import datetime
def pytest_configure(config): """Pytest初始化时配置方法""" if config.getoption('htmlpath'): # 如果传了--html参数 now = datetime.now().strftime('%Y%m%d_%H%M%S') config.option.htmlpath = os.path.join(config.rootdir, 'reports', f'report_{now}.html')
上記の例かどうかは、ユーザーがどのような各実行を渡す--html、プロジェクトレポートを生成し、ディレクトリになりますreport_运行时间.html
新しいレポート形式を。
Pytest初期設定は、私たちのメソッドが実行(メソッドがフックになって)、またはユースケースconftest.pyファイルにするために入れたときPytestガイドは、我々は再び、この方法を実現することができたときにフックpytest_configureは、固定された方法です。
設定パラメータは、メソッドのパラメータ、Pytestの初期化時に含むプラグ、コマンドラインパラメータのすべて、INIプロジェクトの設定を固定しています。
あなたは、Pythonのイントロスペクションメソッド印刷(設定。、使用することができますDictのを configオブジェクトのプロパティを表示します)。
典型的には、config.getoptionによって - コマンドラインパラメータ項目(「HTML」)の値を取得します。使用config.getiniは(「LOG_FILE」)構成アイテムpytest.iniファイルの値を取得することができます。
カスタムオプションと構成を追加します。
我々は完全な実行機能を実現するために電子メールを送信するとします。
私たちは、コマンドラインパラメータ入力--send-電子メールをカスタマイズし、パラメータ値を必要としません。場合は、ユーザの操作パラメータをもたらすために、我々は次のフォーマットを実行しなくても、レポートではなく、髪を送信します。
pytest test_cases/ --html=report.html --send-email
ここでは、一般的には、氏--htmlレポートに協力すべきです。
Pytest自体は、このパラメータを--send、電子メールで送信されませんので、我々は、フックメソッドで追加する必要があります。
# conftest.py
def pytest_addoption(parser): """Pytest初始化时添加选项的方法""" parser.addoption("--send-email", action="store_true", help="send email with test report")
また、我々はまた、電子メールメッセージの件名、本文、受信者およびその他の構成情報を送信する必要があります。私たちは、次のようなpytest.ini、に設定して、この情報を置くことができます。
# pytest.ini
...
email_subject = Test Report
email_receivers = superhin@126.com,[email protected]
email_body = Hi,all\n, Please check the attachment for the Test Report.
カスタム設定オプションは以下のように、登録を使用するために登録する必要があることに留意されたいです。
# conftest.py
def pytest_addoption(parser): ... parser.addini('email_subject', help='test report email subject') parser.addini('email_receivers', help='test report email receivers') parser.addini('email_body', help='test report email body')
送信メールの機能実現
以前の私たちは電子メールの構成と動作パラメータを追加したレポートを生成するとき、我々はこの方法をフック、電子メール機能、次の例に従って伝送パラメータを追加します。
from utils.notify import Email
# conftest.py
def pytest_terminal_summary(config): """Pytest生成报告时的命令行报告运行总结方法""" send_email = config.getoption("--send-email") email_receivers = config.getini('email_receivers').split(',') if send_email is True and email_receivers: report_path = config.getoption('htmlpath') email_subject = config.getini('email_subject') or 'TestReport' email_body = config.getini('email_body') or 'Hi' if email_receivers: Email().send(email_subject, email_receivers, email_body, report_path)
魅力-pytestを使用します
魅力のスタイルは非常に豊富なレポート・フレームワークです。
インストール:PIPは魅力-pytestをインストール
参照文献:https://docs.qameta.io/allure/#_installing_a_commandline
アリュールレポートには、以下の部分が含まれています。
- 概要:概要
- カテゴリー:失敗ユースケースの分類
- スイート:、手袋メンバーを測定するテストクラスpytestに対応
- グラフ:グラフ、全体的な実施形態では、異なる重要度レベルとマークされた実行時間分布を有する状態の報告。
- タイムライン:実行のタイムライン
- 行動:BDDは、ユーザーを、エピック、機能により、行動パターンを駆動する場面
マークや団体には、例を使用しています。 - Pachages:パッケージディレクトリに応じてユースケースを参照するには
例はで標識しました
pytest-魅力実施形態は、自動的を通してpytestにより故障を認識スキップ、XFAIL状態および他の理由、およびユースケースを改善するために、情報を複数の追加のマーカーを提供することができます。
さらに、魅力は、実施の形態で、補足情報を有する多くの追加の実施形態番号または組織を提供します。
マーク・テスト手順
@ allure.step( '')
@allure.step
def func(): pass
この方法は、実施例で呼び出されたときに、レポートがコール入れ子関係認識ステップによれば、工程とみなされます。
追加情報のユースケースを追加するには
添付ファイルを追加します。
- @ allure.attach.file( './データ/ totally_open_source_kitten.png'、attachment_type = allure.attachment_type.PNG)
タイトルと説明を追加します。
- @ allure.description( '')
- @ allure.description_html( '')
- @ allure.title(「このテストでは、カスタムタイトルを持っています」)
リンクを追加、問題のリンク、ユースケースをリンク
- @ allure.link( 'のhttp:// ...')
- Allure.issue @( 'B140'、 'バグの説明')
- @allure.testcase('http://...', '用例名称')
例BDDモード組織
- @ allure.epics( '')
- @ allure.feature( '')
- @ allure.story( '')
- @ allure.step( '')
あなたは、ストーリーや機能として実行することができます
- --allure、叙事詩
- --allure-機能
- --allure-の物語
重要度マーク
- @ allure.severity(allure.severity_level.TRIVIAL)
- @ allure.severity(allure.severity_level.NORMAL)
- @ allure.severity(allure.severity_level.CRITICAL)
次の方法で実行の優先順位を選択します
--allure-severities normal,critical
レポートの魅力を生成します
pytest --alluredir=报告文件夹路径
フォルダを実行した後、レポートファイルのXMLフォーマットを持つことになります。
この報告書を直接jenkinz解決するためのプラグイン-を使用します。
ローカルHTML形式のレポートを表示したい場合は、魅力をインストールする必要があります。
インストール:
- Macの場合:魅力をインストールBREW
- CentOSの:YUM魅力をインストール
- Windowsの場合:ダウンロードし、解凍外ダウンロード、binディレクトリに移動し、あなたがallure.batを使用することができます。使用すると、HTML形式のレポートを生成します。
allure generate 生成allure报告的文件夹
Windowsは、のbinディレクトリの魅力に生成allure.bat使用することができます...
またはレポートの静的なサービスを起動して:
allure serve 生成allure报告的文件夹
これは、自動的にアクセスレポートの生成にブラウザをポップアップ表示されます。
Pytest実際のテストフレームワークAPP
APPはと同じWeb UI層に属し、我々は同じ階層がページオブジェクトパターンが含まれて使用することができます。違いは、私たちは運転手にこのフィクスチャをカスタマイズする必要があるということです。
# conftest.py
import pytest
from appium import webdriver
@pytest.fixture(scope='session') def driver(): caps = { "platformName": "Android", "platformVersion": "5.1.1", "deviceName": "127.0.0.1:62001", "appPackage": "com.lqr.wechat", "appActivity": "com.lqr.wechat.ui.activity.SplashActivity", "unicodeKeyboard": True, "resetKeyboard": True, "autoLaunch": False } driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', caps) driver.implicitly_wait(10) yield driver driver.quit()
固定具及び他のドライバまたはパラメータとしての実施形態で直接組み込むを使用することができます。
# test_weixin.py
def test_weixin_login(driver): driver.find_element_by_xpath('//*[@text="登录"]').click() ...
使用pytest-変数
ピップによってインストールがpytest-変数をインストールし
、我々は、実行時に使用するデバイスの設定およびサービスAppiumアドレスを指定する必要がある場合は、我々はこれらの構成を置くことができpytest-変数はこれらの変数をロードするプラグイン使用し、その後、JSONファイルを書きました。
ファイルのcaps.json内容:
{
"caps": {
"platformName": "Android",
"platformVersion": "5.1.1", "deviceName": "127.0.0.1:62001", "appPackage": "com.lqr.wechat", "appActivity": "com.lqr.wechat.ui.activity.SplashActivity", "unicodeKeyboard": true, "resetKeyboard": true, "autoLaunch": false }, "server": "http://localhost:4723/wd/hub" }
備品を使用します:
# conftest.py
...
@pytest.fixture(scope='session')
def driver(variables): caps = variables['caps'] server = variables['server'] driver = webdriver.Remote(server, caps) ...
Runメソッド:
pytest test_weixin.py --variables caps.json
あなたが複数の構成を持っている場合は、実行に指定された設定ファイルをロードし、複数のプロファイルの保存、caps.jsonフォーマットすることができます。動作パラメータはまた、addoptsのpytest.iniに追加することができます。
セットアップとクリーンアップ
各ユースケースを実行すると、お互いに影響しないことを確実にするために、我々は、各ユースケースを取ることができ、アプリを完全に近い行っユースケースメソッドレベルフィクス方法に属するされているアプリを起動します。
一方、第1の実施形態の実行時点以降もアプリ即ちキャップがFalse =自動起動を設定して、我々は、デフォルトのデバイスを設定する必要がフィクスチャは、自動起動アプリに接続されていない開始と呼ばれています。
conftest.pyにして、次のフィクスチャのメソッドを追加します。
# conftest.py
...
@pytest.fixture(scope='function', autouse=True)
def boot_close_app(driver): driver.boot_app() yield driver.close_app()
ページのオブジェクトと他のサービスのカプセル化層かもしれフィクスチャのWeb参照モデルのフレームワーク。
著者:HANスーパー
リンクします。https://www.jianshu.com/p/9a03984612c1
出典:ジェーン・ブック
著者によって予約ジェーンブックの著作権は、いかなる形で再現され、承認を得るために、作者に連絡して、ソースを明記してください。