自動化を最優先としたアプリ設計フレームワークとベストプラクティス

開発者がアプリを最初から自動化に対応できるように設計する方法を促進するコンセプト ― テスターの視点から。

イントロダクション

自動化テスターとして、私は自動化を意図的に阻害するように設計されたと思われるアプリケーションと格闘するのに膨大な時間を費やしてきました。UIのちょっとした変更で壊れてしまう脆弱なセレクタ、識別可能なプロパティを持たないコンポーネント、不明瞭な状態の背後に隠された複雑なワークフロー――これらは私たちが日々直面するフラストレーションです。

しかし重要なのは、これらの課題のほとんどは予防可能だということです。開発者が最初から自動化を念頭に置いてアプリケーションを設計すれば、テストはより迅速になり、信頼性も高まり、保守性も大幅に向上します。

これは単に私たちの仕事を楽にするためだけではなく、より高品質なソフトウェアをより迅速に提供するためのものなのです。

この記事では、アプリケーション開発者がアプリケーションを「自動化対応」にするために従うべき実践的な推奨事項を紹介します。

要素を識別可能かつ安定させる

問題:

多くのアプリは、ビルドごとに変化するCSSクラス名や生成IDのみに依存しています。一方、Selenium、Playwright、Appiumなどの自動化フレームワークは、要素を操作するためにロケーター(一意の識別子)に依存しています。

開発者がすべきこと:

  • 追加 data-testid インタラクティブ要素(ボタン、入力フィールド、フォーム、リンク)に属性を付与する
  • これらのIDはリリース間で安定させ、公開APIのように扱ってください。
  • 動的なクラス名やXPathの位置だけに頼るのは避けてください。

実際の例:

// ❌ BAD - Changes frequently 

<button className="btn-primary-v2 btn-submit-form"> 

Submit 

</button> 

// ✅ GOOD - Stable identifier for testers 

<button data-testid="form-submit-button" className="btn-primary-v2"> 

Submit 

</button>

送信

これが重要な理由:

あなたが追加するとき data-testidテスターは、以下の方法で要素を確実に特定できます。 page.locator('[data-testid="form-submit-button"]') 劇作家または find_element(By.CSS_SELECTOR, '[data-testid="form-submit-button"]') Seleniumにおいて。

セマンティックHTMLと適切なラベル関連付けを使用する

問題:

ジェネリック <div> (NAIST) と <span> ラベルのない要素があると、テスターがコントロールの目的を理解することがほぼ不可能になり、アクセシビリティツールが正しく機能しなくなります。

開発者がすべきこと:

  • セマンティックなHTML要素を使用する: <button>, <input>, <label>, <form>
  • ラベルを入力に関連付けるには、 <label for="inputId">
  •   aria-label or aria-labelledby 複雑な部品の場合

実際の例:

// ❌ BAD - No semantic meaning 

<div onClick={() => setSelected(!selected)}> 

<span>Enable notifications</span> 

</div> 

 

// ✅ GOOD - Semantic and testable 

<label htmlFor="notifications-toggle"> 

<input  

id="notifications-toggle"  

type="checkbox"  

data-testid="notifications-toggle" 

/> 

Enable notifications 

</label>

テスターの視点:

セマンティック HTML を使用すると、役割ベースのセレクタを使用できます。例えば、page.locator('input[role=”checkbox”]') や Playwright の getByRole(“checkbox”, { name: /enable notifications/i }) などです。これにより、テストの可読性が向上し、スタイルの変更にも強くなります。

明示的な待機状態とロードインジケータを実装する

問題:

JavaScriptを多用するアプリケーションでは、コンテンツが動的に読み込まれます。要素の表示/非表示が非同期で行われるため、テスターはページが本当に「準備完了」になったタイミングを把握できず、テストが不安定になることがよくあります。

開発者がすべきこと:

  •   data-testid ロード状態の場合:
    <div data-testid="loading-spinner"> 
  • コンテンツセクションにステータス属性を付与する: aria-busy="true" 負荷時
  • ユーザー操作に応答する前に、アプリが安定した状態になっていることを確認してください。
  • 明示的なロード完了シグナルを提供する

実際の例:

// ❌ BAD - No semantic meaning 

<div onClick={() => setSelected(!selected)}> 

<span>Enable notifications</span> 

</div> 

 

// ✅ GOOD - Semantic and testable 

<label htmlFor="notifications-toggle"> 

<input  

id="notifications-toggle"  

type="checkbox"  

data-testid="notifications-toggle" 

/> 

Enable notifications 

</label>

テスターの自動化コード(Playwright):

// Wait for loading to complete 

await page.locator('[data-testid="loading-spinner"]').waitFor({ state: 'hidden' }); 

 

// Now interact with the list 

const userList = page.locator('[data-testid="user-list"]'); 

await expect(userList).toBeVisible();

入力処理が明確なデザインフォーム 

問題: 

エラー状態が不明瞭だったり、検証が隠されていたり、入力動作が標準的でなかったりする複雑なフォームは、自動化スクリプトを混乱させる。 

開発者がすべきこと: 

  • 明確な名前属性を持つ標準のHTMLフォーム要素を使用する 
  • 明示的なエラーメッセージを提供する data-testid マーカー 
  • フォーム検証が確実に可視化されるようにする(サイレントエラーにならないようにする) 
  • 成功確認を含める 

実際の例: 

// ✅ GOOD - Clear form with observable states 

<form data-testid="login-form"> 

<div> 

<label htmlFor="email-input">Email:</label> 

<input 

id="email-input" 

name="email" 

type="email" 

data-testid="email-input" 

required 

/> 

{errors.email && ( 

<span data-testid="email-error" role="alert"> 

{errors.email} 

</span> 

)} 

</div> 

 

<div> 

<label htmlFor="password-input">Password:</label> 

<input 

id="password-input" 

name="password" 

type="password" 

data-testid="password-input" 

required 

/> 

</div> 

 

<button  

type="submit"  

data-testid="login-submit-button" 

disabled={isSubmitting} 

> 

{isSubmitting ? 'Logging in...' : 'Login'} 

</button> 

 

{submitSuccess && ( 

<div data-testid="login-success-message" role="status"> 

Login successful! Redirecting... 

</div> 

)} 

</form>

テスターの自動化コード(Selenium):

from selenium import webdriver 

from selenium.webdriver.common.by import By 

from selenium.webdriver.support.ui import WebDriverWait 

from selenium.webdriver.support import expected_conditions as EC 

 

driver = webdriver.Chrome() 

driver.get("https://app.com/login") 

 

# Fill form 

driver.find_element(By.CSS_SELECTOR, '[data-testid="email-input"]').send_keys("test@example.com") 

driver.find_element(By.CSS_SELECTOR, '[data-testid="password-input"]').send_keys("password123") 

 

# Submit 

driver.find_element(By.CSS_SELECTOR, '[data-testid="login-submit-button"]').click() 

 

# Wait for success message 

WebDriverWait(driver, 10).until( 

EC.presence_of_element_located((By.CSS_SELECTOR, '[data-testid="login-success-message"]')) 

)

APIレスポンスを予測可能かつ一貫性のあるものにする

問題:

APIレスポンスに依存するモバイルアプリやウェブアプリには、安定したデータ構造が必要です。APIレスポンスが不安定だったり予測不能だったりすると、テストがランダムに失敗する原因となります。

開発者がすべきこと:

  • すべてのエンドポイントで一貫したJSON構造を使用する
  • すべてのオブジェクトに一意の識別子(ID)を含める
  • API契約書(OpenAPI/Swagger)を文書化する
  • 意味のあるHTTPステータスコードとエラーメッセージを返す
  • 開発中にテストAPIの応答を確認する

実際の例:

// ✅ GOOD - Predictable API response 

{ 

"success": true, 

"data": { 

"id": "user-123", 

"email": "test@example.com", 

"name": "John Doe", 

"created_at": "2026-03-01T10:00:00Z" 

}, 

"timestamp": "2026-03-22T14:30:00Z" 

} 

 

// ❌ BAD - Inconsistent response 

{ 

"status": "ok", 

"user": { 

"uid": "123", 

"email_address": "test@example.com" 

}, 

"meta": { "time": 1679574600 } 

}

テスターのモバイル オートメーション (Appium):

# With predictable API, testers can mock and validate 

from appium import webdriver 

 

driver = webdriver.Remote("http://localhost:4723/wd/hub", capabilities) 

 

# Mock the API response 

mock_response = { 

"success": True, 

"data": { 

"id": "user-123", 

"name": "Test User" 

} 

} 

 

# Now reliably access user data in the app 

user_name_element = driver.find_element("xpath", "//text[@value='Test User']")

テストに適した構成とモードを提供する

問題:

分析機能、広告、サードパーティトラッカー、ネットワーク遅延などの本番環境における機能は、テストの実行を妨げる可能性があります。

開発者がすべきこと:

  • テストモードまたは環境変数を指定してください。
  • テスト環境で分析、広告、トラッキングを無効にすることを許可する
  • 不要なアニメーションや遅延をスキップする機能をサポート
  • テスト用にアプリの状態をリセットするためのAPIエンドポイントを提供する

実際の例(React):

// ✅ GOOD - Test-friendly configuration 

const isTestMode = process.env.REACT_APP_TEST_MODE === 'true'; 

 

function App() { 

return ( 

<div> 

{!isTestMode && <Analytics />} 

{!isTestMode && <Ads />} 

<MainContent /> 

</div> 

); 

}

環境変数:

REACT_APP_TEST_MODE=true npm start

文書自動化に関する期待

問題:

テスターは、アプリケーション、特にカスタムコンポーネントとのインタラクション方法をリバースエンジニアリングすることに時間を費やします。

開発者がすべきこと:

  • ドキュメント data-testid READMEファイル内の命名規則
  • 複雑な機能のテスト/自動化ガイドを提供する
  • コンポーネントのドキュメント(Storybookなど)を共有する
  • テスターが知っておくべきカスタムイベントとコールバックをすべてリストアップします

ドキュメントの例:

## Automation Testing Guide 

 

### Naming Conventions 

- Buttons: `data-testid="[feature]-[action]-button"` (e.g., `user-logout-button`) 

- Form inputs: `data-testid="[form]-[field]-input"` (e.g., `login-email-input`) 

- Lists: `data-testid="[list]-container"` and items as `[list]-item-[id]` 

 

### Key Components 

- **Modal**: `.modal-overlay` (hidden when closed), contains `data-testid="modal-close-button"` 

- **Dropdown**: Use semantic `<select>` or `aria-haspopup="listbox"` 

- **Date Picker**: Supports keyboard navigation and `aria-label` 

 

### Test Environment Setup 

Set `API_URL=http://localhost:3001/api` to use mock server

開発者にとっての重要なポイント

テスターに​​必要なもの 開発者がすべきこと
安定した要素識別子 data-testid属性を使用する
明確なコンポーネント階層 セマンティックHTMLを使用する
観測可能なロード/準備完了状態 識別子付きのローディングインジケーターを提供する
予測可能な形態挙動 文書検証と標準要素の使用
一貫性のあるAPIレスポンス API契約に従い、ドキュメント構造を遵守する
テストに適した環境 テストモードをサポートし、広告/分析を無効化します。
明確な自動化ガイダンス 自動化に関する期待事項を文書化してください。

結論

自動化に対応したアプリケーションを構築するということは、制約を回避することではなく、最初からアプリケーションを正しく設計することなのです。

開発者が明瞭さ、一貫性、そして可視性を優先すれば、誰もが恩恵を受ける。テスターはより速く、より信頼性の高いテストを作成でき、ユーザーはより高品質なソフトウェアを手に入れ、チーム全体がより迅速に作業を進めることができる。

朗報は?これらの手法のほとんどは、そもそも優れたソフトウェアエンジニアリングの手法であるということです。セマンティックHTML、予測可能なAPI、明確なエラー処理は、自動化テストだけでなく、アクセシビリティ、パフォーマンス、ユーザーエクスペリエンスにもメリットをもたらします。

で始まる data-testid 属性を記述し、セマンティックHTMLを使用し、読み込み状態を可視化し、コンポーネントを文書化しましょう。自動化テスト担当者はきっと感謝してくれるでしょうし、アプリケーション自体もより良いものになります。

リソースとツール

お勧めの関連ガジェット