Seleniumとは
Selenium は、実ブラウザ(Chrome, Firefox, Edge, Safari など)をドライバ経由で操作し、UI テストや業務オペレーションの自動化を行うためのオープンソース群(WebDriver プロトコル/クライアント/サーバ)です。人のクリックや入力に近い再現性と、主要言語に対応した SDK が特徴です。
- 対応言語:Python / Java / JavaScript / C# / Ruby / PHP など
- 動作形態:各ブラウザの WebDriver と通信(近年は Chrome for Testing + 付属ドライバが主流)
- 用途:E2E テスト、回帰テスト、スクレイピング(要配慮)、RPA 的な自動化、監視 など
概要
構成要素
- WebDriver:ブラウザ自動操作の標準プロトコル
- Client(言語バインディング):Python/Java などの SDK
- Driver Binary:chromedriver/geckodriver 等(新 Chrome は内蔵)
基本フロー
- ドライバ起動(ヘッドレス可)
- URL を開く / 要素探索 / 操作
- 明示的ウェイトで安定化
- アサーション / スクショ保存 / 終了
よくある落とし穴
- 暗黙的ウェイトだけに依存しフレークが増える
- 不安定な XPath で brittle なテストに
- 定位できない Shadow DOM / iframe の扱い漏れ
基本
セットアップから要素探索・ウェイト・スクショまで、最小限のパターン。
Python(推奨の最小構成)
# pip install selenium webdriver-manager
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
opt = Options()
opt.add_argument('--headless=new') # 画面不要なら
with webdriver.Chrome(options=opt) as driver:
driver.get('https://example.com')
# 明示的ウェイト:id="login" が出るまで最大10秒待つ
wait = WebDriverWait(driver, 10)
btn = wait.until(EC.element_to_be_clickable((By.ID, 'login')))
btn.click()
# スクショ
driver.save_screenshot('shot.png')
Java
// Maven: org.seleniumhq.selenium:selenium-java
WebDriver driver = new ChromeDriver(new ChromeOptions().addArguments("--headless=new"));
driver.get("https://example.com");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement e = wait.until(ExpectedConditions.elementToBeClickable(By.id("login")));
e.click();
driver.quit();
JavaScript (Node)
// npm i selenium-webdriver
const {Builder, By, until} = require('selenium-webdriver');
(async () => {
const driver = await new Builder().forBrowser('chrome').build();
try {
await driver.get('https://example.com');
const el = await driver.wait(until.elementLocated(By.id('login')), 10000);
await el.click();
} finally { await driver.quit(); }
})();
C#
// dotnet add package Selenium.WebDriver
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI;
var opt = new ChromeOptions(); opt.AddArgument("--headless=new");
using var driver = new ChromeDriver(opt);
driver.Navigate().GoToUrl("https://example.com");
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.FindElement(By.Id("login"))).Click();
PHP
// composer require php-webdriver/webdriver
use Facebook\WebDriver\Chrome\ChromeOptions;
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\WebDriverBy;
$opt = new ChromeOptions();
$opt->addArguments(['--headless=new']);
$cap = DesiredCapabilities::chrome();
$cap->setCapability(ChromeOptions::CAPABILITY, $opt);
$driver = RemoteWebDriver::create('http://localhost:9515', $cap); // chromedriver 起動前提
$driver->get('https://example.com');
$driver->findElement(WebDriverBy::id('login'))->click();
$driver->quit();
Chrome 124+ では Chrome for Testing が標準化。従来の個別ドライバ配布から内蔵化の流れ。CI では固定バージョンを使い、再現性を担保しましょう。
基礎
要素探索の優先度
- 安定属性(data-testid, data-qa 等)
- CSS セレクタ(#id, .class, [name=], :has() は未対応)
- XPath(最後の手段。構造に依存しがち)
ウェイト戦略
- 明示的 Wait(要素出現/クリック可まで)を基本に
- 暗黙 Wait は短め(0〜2s)で初期化にのみ
- ポーリング間隔とタイムアウトをユースケース別に調整
iframe / Shadow DOM
# iframe
frame = wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, 'iframe[name="pay"]')))
# Shadow root
host = driver.find_element(By.CSS_SELECTOR, '#shadow-host')
shadow_root = host.shadow_root
btn = shadow_root.find_element(By.CSS_SELECTOR, 'button.primary')
応用
ログイン/2FA の扱い
- テスト用 ID を発行し、本番アカウントとは分離
- メール/SMS 2FA は テストバイパス を用意
- SSO(SAML/OIDC)はスタブ環境で検証
ダウンロード
from selenium.webdriver.chrome.options import Options
opt = Options(); opt.add_experimental_option('prefs', {
'download.default_directory': '/tmp/dl',
'download.prompt_for_download': False,
'safebrowsing.enabled': True,
})
ファイルアップロード
driver.find_element(By.CSS_SELECTOR, 'input[type=file]').send_keys('/path/to/file.png')
並列実行
発展
Page Object Model
class LoginPage:
def __init__(self, driver):
self.d = driver
def open(self):
self.d.get('https://example.com/login')
return self
def login(self, user, pw):
self.d.find_element(By.ID,'user').send_keys(user)
self.d.find_element(By.ID,'pw').send_keys(pw)
self.d.find_element(By.CSS_SELECTOR,'button[type=submit]').click()
CI 連携
- Docker で
selenium/standalone-chromeを利用 - テスト失敗時のスクショ/har/console log をアーティファクト保存
- 安定化のためネットワーク/時間に依存するテストを隔離
アクセシビリティ
重要シナリオの ARIA/コントラストを自動検査(axe-core 等)と組み合わせ、セマンティクスを担保。
最新情報
目的
主な目的は UI の正しさを担保 し、リリースの信頼性を上げること。副次的に、定型のブラウザ操作業務を自動化して人手を削減します。
仕事の現場
テスト戦略
- 単体/結合テストで土台を固め、E2E は 要点のみ に絞る
- テストデータ/テスト環境は毎回クリーンに
- フレーク検知 → 自動リトライ+原因切り分け
運用
- 失敗スクショ・ログを自動収集
- 失敗解析テンプレ(要素未検出/タイムアウト/ネットワーク)
- 週次で flakiness レポートを共有
自動化プログラムと比較
Playwright / Puppeteer
- 高速で API がモダン。テスト記録/トレース が強力(特に Playwright)
- マルチブラウザは Playwright がカバー、Puppeteer は Chrome 系中心
- 既存 Selenium 資産が多い環境では Selenium 継続が合理的
HTTP クライアント + パーサ
- requests + BeautifulSoup 等:速度/安定性は高いが JS 実行 UI は対象外
- API があるなら まず API 直叩き を検討
RPA ツール
- UiPath / Power Automate:ノーコードで社内手続きに向く
- Web UI 中心・コード管理したいなら Selenium/Playwright が適合
知っておくといい
知識
- DOM/CSS セレクタ/イベント伝播
- ネットワーク/キャッシュ/同一生成元制約
- ブラウザ別の差(ポリフィル/レンダリング)
技能
- 安定 Locators 設計(data-* 属性の導入)
- Page Object / テストデータ戦略
- CI/CD 組み込み & 並列化
用語
- Headless / Explicit Wait / Shadow DOM / Viewport
- Har / Console log / Trace
ルール
- テストはユーザ価値の高い シナリオ優先
- UI 変化に強い Locator を採用(role/name 等)
- 外部サイト自動化は規約/法令を順守
例
スクリーンショット+エラーハンドリング
from selenium.common.exceptions import TimeoutException
try:
driver.get('https://example.com/dashboard')
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'h1.title')))
except TimeoutException:
driver.save_screenshot('error.png')
raise
Network 条件の制御(Chrome)
from selenium.webdriver.common.devtools.v125 import network
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
# 例: 速度制限
with driver.bidi_connection() as cdp:
cdp.session.execute(network.enable())
cdp.session.execute(network.emulate_network_conditions(
offline=False, latency=200, download_throughput=50*1024, upload_throughput=20*1024))
CSV に結果を書き出す
import csv
rows = [(e.text, e.get_attribute('href')) for e in driver.find_elements(By.CSS_SELECTOR,'a.item')]
with open('list.csv','w',newline='',encoding='utf-8') as f:
writer = csv.writer(f); writer.writerow(['title','url']); writer.writerows(rows)
関連リンク
- 公式 Docs / 言語別クライアント / サンプル集(社内 Wiki や Notion へのリンク推奨)
- ブラウザ毎の WebDriver リリースノート
- CI 用 Docker イメージ(selenium/standalone-*)
※ 本ページは学習・社内ナレッジ用。外部サイト自動化は対象サイトの規約を遵守してください。
より具体的に:導入チェックリスト
- ✅ テスト対象の 安定 Locator を用意(data-testid 等)
- ✅ CI で実行できる Docker 化
- ✅ 失敗時の スクショ/ログ収集
- ✅ 並列実行と 独立データ の設計
- ✅ flake を計測し 閾値超過で要因分析