paint-brush
QA テスターのための Python を活用したパフォーマンス テスト: クラウド API 負荷テストの初心者ガイド@shad0wpuppet
27,064 測定値
27,064 測定値

QA テスターのための Python を活用したパフォーマンス テスト: クラウド API 負荷テストの初心者ガイド

Konstantin Sakhchinskiy8m2024/01/19
Read on Terminal Reader
Read this story w/o Javascript

長すぎる; 読むには

クラウド アプリ API で負荷テストを実施する QA テスター向けの Python スクリプトを調べます。この記事では、非同期およびマルチプロセッシングのアプローチについて説明し、カスタマイズ、方法論の選択、実践的な監視のヒントについての洞察を提供します。 Python の技術機能を活用して、包括的なパフォーマンス分析を行います。
featured image - QA テスターのための Python を活用したパフォーマンス テスト: クラウド API 負荷テストの初心者ガイド
Konstantin Sakhchinskiy HackerNoon profile picture
0-item
1-item


あなたは、広範なプログラミングの専門知識を必要とせずにパフォーマンス テストに取り組みたいと考えている QA テスターですか?この記事では、プログラマーではない人でもPythonを使用してクラウド アプリ API で一種の負荷テストを実行できるアプローチ可能な方法を検討します。複雑なコーディングを必要とせずに負荷テストを実行 - 通常の QA テスターでも Python を使用して重大なバグを発見し、潜在的なパフォーマンスのボトルネックを発見する方法を発見してください。


パフォーマンス テストは、アプリケーションが実際の要求に対応できることを確認するために重要な側面です。私のアプローチと、ブラウザを管理するクラウド サービスの負荷テスト用に設計された Python スクリプトについて説明してみます。


負荷テストのシナリオブラウザー プロファイル (Web スクレイピング用のブラウザー) の管理を担当するクラウド サービスを想像してください。ユーザーは API を介してサービスと対話し、プロファイルの作成、開始、停止、削除などを行います。私の Python スクリプトはこのシナリオをシミュレートし、これらのアクションを繰り返し実行することでクラウド サービスに負荷を適用します。


 # Dependencies import asyncio import httpx # Configuration API_HOST = 'https://cloud.io' API_KEY = 'qatest' API_HEADERS = { "x-cloud-api-token": API_KEY, "Content-Type": "application/json" } CYCLES_COUNT = 3 # Browser profile configuration data_start = { "proxy": "http://127.0.0.1:8080", "browser_settings": {"inactive_kill_timeout": 120} }

非同期関数: 私の負荷テストの中心

  • ブラウザ プロファイルの取得: get_profiles関数は、サービスから既存のブラウザ プロファイルを取得し、ユーザーが情報を要求するシナリオをシミュレートします。
 async def get_profiles(cl: httpx.AsyncClient): resp = await cl.get(f'{API_HOST}/profiles', params={'page_len': 10, 'page': 0}, headers=API_HEADERS) return resp.json()


  • ブラウザの起動:スクリプトはサイクルを開始し、各サイクルにはブラウザ プロファイルの非同期起動が含まれます。これは、ユーザーが複数のブラウザを同時に作成し、ブラウザ プロファイルを使用するシナリオをエミュレートします。
 async def start_profile(cl: httpx.AsyncClient, uuid): resp = await cl.post(f'{API_HOST}/profiles/{id}/start', json=data_start, headers=API_HEADERS) if error := resp.json().get('error'): print(f'Profile {id} not started with error {error}')


  • ブラウザの停止とプロファイルの削除:プロファイルを開始した後、スクリプトはアクティブなプロファイルを取得して停止し、その後すべてのプロファイルを削除します。この負荷シナリオでは、動的な変更に対するクラウド サービスの応答性とリソースのクリーンアップの効率を評価します。
 async def stop_profile(cl: httpx.AsyncClient, uuid): resp = await cl.post(f'{API_HOST}/profiles/{id}/stop', headers=API_HEADERS) if error := resp.json().get('error'): print(f'Profile {id} not stopped with error {error}') async def delete_profile(cl: httpx.AsyncClient, uuid): resp = await cl.delete(f'{API_HOST}/profiles/{id}', headers=API_HEADERS) if error := resp.json().get('error'): print(f'Profile {id} not stopped with error {error}')


  • 接続の監視: 負荷への影響を理解するスクリプトは、アクティブな接続を確認してレポートすることで終了します。このステップは、負荷の影響を理解し、監視に関連する潜在的な問題を特定するために重要です。
 for conn in cl._transport._pool.connections: if conn._connection._state.value != 1: continue print(f'Connection in progress: {conn}')

負荷テストの実行中

メイン関数は負荷テスト サイクルを調整し、プロファイルを反復処理して非同期タスクを実行します。各サイクルは、ブラウザー プロファイルの作成、使用、削除という、シミュレートされたユーザー インタラクションを表します。


 async def main(): async with httpx.AsyncClient(timeout=httpx.Timeout(timeout=300)) as cl: for _ in range(CYCLES_COUNT): profiles = await get_profiles(cl) start_tasks = [asyncio.create_task(start_profile(cl, profile['id'])) for profile in profiles] await asyncio.gather(*start_tasks) active_browsers = await get_active_profiles(cl) stop_tasks = [asyncio.create_task(stop_profile(cl, active_browser['id'])) for active_browser in active_browsers['data']] await asyncio.gather(*stop_tasks) profiles = await get_profiles(cl) del_tasks = [asyncio.create_task(delete_profile(cl, profile['id'])) for profile in profiles] await asyncio.gather(*del_tasks) # Monitor active connections for insights into load impact

負荷テストをニーズに合わせて調整する

このスクリプトは、QA が負荷テストのシナリオをアプリケーションに合わせて調整するための基盤を示します。サイクル数をカスタマイズし、ユーザー操作を調整し、特定の API エンドポイントに合わせてスクリプトを変更することで、テスターはさまざまな負荷下でのアプリケーションのパフォーマンスについて貴重な洞察を得ることができます。ここでは、サーバーの状態に関する情報を取得し、サーバーの負荷を評価し、リソースの使用率とログを追跡するために重要な監視ツールが必要になります。包括的な監視には、Grafana、Kibana、Prometheus などのツールを利用します。さらに、スクリプトが受け取る応答を注意深く監視し、アプリケーションのパフォーマンスを徹底的に評価してください。このアプローチは、効果的な負荷テストとパフォーマンス分析に非常に役立ちます。


さらに、より現実的な負荷シミュレーションを行うには、ブラウザで特定のページを開くことを検討してください。私は個人的にブラウザーのスタート ページを使用しましたが、Pyppeteer や Playwright などのオプションを使用して、複数のタブを開いてさまざまなページ間を移動することもできます。このアプローチにより、負荷テスト シナリオの信頼性が向上し、アプリケーションとのユーザー操作に非常に似たものになります。


 # Attempt to connect to the browser using the provided profile URL try: browser = await connect({'browserWSEndpoint': browser_url, 'defaultViewport': None}) except Exception as e: # Handle connection errors and print a message print(f'Error occurred when connecting to the browser: {str(e)}') return # Create a new page in the connected browser page = await browser.newPage() # Introduce a brief delay to ensure the page is ready await asyncio.sleep(2) # Set the viewport dimensions for the page width, height = 1920, 1080 await page.setViewport({'width': width, 'height': height}) # Try to navigate to a specific URL try: await page.goto('https://{your_website}') # Wait for 10 seconds to simulate user interaction await page.waitFor(10000) # Introduce another delay for additional stability await asyncio.sleep(5) except pyppeteer.errors.PageError as e: # Handle page navigation errors and print a message print(f'Error occurred during page navigation: {str(e)}') # Attempt to take a screenshot of the page try: await page.screenshot(path='screen.png', fullPage=True) # Print a success message if the screenshot is captured successfully print('Screenshot taken successfully.') except Exception as e: # Handle screenshot capture errors and print a message print(f'Error occurred during taking a screenshot: {str(e)}')

Python の非同期機能と HTTP ライブラリを組み合わせることで、Python はクラウドベースのシステムの負荷テスト用の多用途ツールになります。この例は、負荷テストの試みで Python の能力を学ぼうとしている QA エンジニアにとっての出発点として役立ちます。


注記

私のシナリオでは、説明したスクリプトは堅牢で影響力があることがわかりました。これは、多くの問題を特定して対処するための有用なツールとして機能しました。スクリプトの積極的な性質は、重要な問題を正確に特定し、効果的なデバッグを促進し、シームレスで改善されたユーザー エクスペリエンスへの道を導くという点で問題なく、QA としては非常に優れています。



続けて、Python のマルチプロセッシング モジュールを利用した別のスクリプトについて簡単に説明します。このアプローチは、テスト スクリプトの複数のインスタンスを同時に実行することで負荷生成を強化することを目的としています。マルチプロセッシングの主な目的は、スクリプトの実行を並列化し、サービスとの同時対話を可能にすることです。このアプローチは、タスクが順次実行されながら同時に管理される、前述の非同期アプローチとは対照的です。これは、同じリクエストを含むスパム/DDO に似ていますが、非常に役立つ場合もあります。

主要コンポーネント

  • プロファイルを取得する関数:非同期スクリプトと同様に、クラウド サービスから既存のブラウザー プロファイルを取得する必要があります。
 def get_profiles(): response = requests.get(url=f"{api}", params=PARAMS, headers=headers) return response


  • 関数:スクリプトの中核は、start_profiles と stop_profiles という 2 つの関数を中心に展開します。これらの関数は、それぞれブラウザ プロファイルを開始および終了します。
 def start_profiles(list_of_profiles_uuids): for uuid in list_of_profiles_uuids: # ... (API request to start profile) def stop_profiles(internal_uuids): for uuid in internal_uuids: # ... (API request to stop profile) def run_script(): start_profiles(get_profile_ids()) stop_profiles(list_of_ids)


  • マルチプロセッシングの実行:スクリプトはマルチプロセッシング モジュールを利用して、負荷テスト サイクルを複数回並行して実行します。サイクルごとに、新しいプロセスが生成され、run_script 関数が同時に実行されます。
 if __name__ == "__main__": for runs in range(0, 5): processes = [] for i in range(20): p = multiprocessing.Process(target=run_script) processes.append(p) p.start() for p in processes: p.join()


マルチプロセッシングで負荷を生成する方法

  1. 並列実行:マルチプロセッシング モジュールによって生成された各プロセスは独立して動作し、run_script 関数を同時に実行します。この並列化により、サービスに同時に送信されるリクエストの数が大幅に増加します。
  2. ユーザー操作のシミュレーション:スクリプトの複数のインスタンスを並行して実行することで、クラウド サービスと同時に操作する大量のユーザーをシミュレートします。このアプローチは、実際の使用に多数の同時ユーザーが関与するシナリオで特に役立ちます。

適切なアプローチの選択

マルチプロセッシングは、アプリケーションの負荷テストのための戦略を提供します。これにより、QA エンジニアはアプリケーションの固有の特性に基づいてさまざまな方法を試すことができます。非同期テストは同時タスクの管理を効率化しますが、マルチプロセッシングはテスト プロセス全体の並列化に優れています。特定の負荷テストの目標とアプリケーション要件に最も適したアプローチを選択できます。


簡単な注意事項:

このデモは、初心者に優しい形式で基本概念を紹介し、パフォーマンス テストに取り組む QA テスターに Python のシンプルさを強調することを目的としています。

プログラミングの課題がある場合は、ためらわずに Google で検索したり、同僚に尋ねたり、ChatGPT または同様のツールを使用したり、負荷テスト スクリプトの作成をさらに支援するために GitHub Copilot を使用したりしてください。


ここでも公開されています。