Apidog

オールインワン協働API開発プラットフォーム

API設計

APIドキュメント

APIデバッグ

APIモック

API自動テスト

Selenium WebDriverを使用したAPIテストの方法

@apidog

@apidog

Updated on 4月 1, 2025

💡
Seleniumチュートリアルに飛び込む前に、Apidogをチェックしてください。これはAPIテストと統合を簡素化するために設計された無料のツールです。Apidogの直感的なインターフェースを使用すると、APIワークフローを簡単にデバッグおよび最適化でき、開発プロセスを効率化し、貴重な時間を節約できます。APIを構築している場合でも、問題をトラブルシューティングしている場合でも、Apidogはワークフローを向上させるために必要なすべてを提供します。
ボタン

Selenium WebDriverについて考えると、通常はブラウザの自動化やUIテストと関連付けられます。しかし、Seleniumは正しく使用すればAPIテストの強力なツールにもなります。このチュートリアルでは、Selenium WebDriverの機能を活用してAPIテストを実行するプロセスをガイドし、実用的な例とベストプラクティスを提供します。

API(アプリケーションプログラミングインターフェース)テストは、アプリケーションのAPIを直接テストし、その機能、信頼性、パフォーマンス、安全性を検証することを含みます。Postman、REST Assured、SoapUIなどの専用ツールがある一方で、Selenium WebDriverは、特にUIとAPIテストを同じフレームワーク内で統合したい場合に、APIテストツールキットに貴重な追加物となります。

前提条件

Selenium WebDriverを使用してAPIテストに飛び込む前に、次のことを確認してください:

  1. Selenium WebDriverの基本的な知識
  2. お好きなプログラミング言語(Java、Python、C#、JavaScript)
  3. 開発環境に設定されたSelenium WebDriver
  4. REST/SOAP APIの理解
  5. HTTPメソッド(GET、POST、PUT、DELETE)の基本的な知識

アーキテクチャの理解

Selenium WebDriverのアーキテクチャは次の能力により、APIテストに適しています:

  1. 組み込みまたは外部ライブラリを使用してHTTPリクエストを直接送信する
  2. レスポンスを処理し、データを検証する
  3. 既存のテストフレームワークと統合する
  4. テストデータと環境を管理する

環境の設定

Selenium WebDriverを使用してAPIテスト用の基本的な環境を設定しましょう:

Javaの例

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class SeleniumApiTesting {
    private WebDriver driver;

    public void setUp() {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless"); // APIテスト用のヘッドレスモード
        driver = new ChromeDriver(options);
    }

    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

Pythonの例

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import requests
import json

def setup_driver():
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # APIテスト用のヘッドレスモード
    driver = webdriver.Chrome(options=chrome_options)
    return driver

def teardown_driver(driver):
    if driver is not None:
        driver.quit()

Selenium WebDriverによるAPIテストのアプローチ

1. ネイティブHTTPライブラリの使用

最も単純なアプローチは、自身のプログラミング言語のネイティブHTTPライブラリをSelenium WebDriverと併用することです。

Javaの例 - GETリクエスト

public String performGetRequest(String endpoint) throws IOException {
    URL url = new URL(endpoint);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");

    int responseCode = connection.getResponseCode();
    System.out.println("GETレスポンスコード: " + responseCode);

    if (responseCode == HttpURLConnection.HTTP_OK) {
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String inputLine;
        StringBuilder response = new StringBuilder();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        return response.toString();
    } else {
        return "GETリクエストはレスポンスコード: " + responseCode + "で失敗しました";
    }
}

Pythonの例 - POSTリクエスト

def perform_post_request(endpoint, payload):
    headers = {'Content-Type': 'application/json'}
    response = requests.post(endpoint, data=json.dumps(payload), headers=headers)

    print(f"POSTレスポンスコード: {response.status_code}")

    if response.status_code == 200:
        return response.json()
    else:
        return f"POSTリクエストはレスポンスコード: {response.status_code}で失敗しました"

2. JavaScriptExecutorを使用してAJAXコールを行う

別のアプローチは、SeleniumのJavaScriptExecutorを使用してブラウザから直接AJAXコールを行うことです。

Javaの例

import org.openqa.selenium.JavascriptExecutor;

public String performApiCallWithJsExecutor(String endpoint, String method, String payload) {
    String script = String.format(
        "var xhr = new XMLHttpRequest();" +
        "xhr.open('%s', '%s', false);" +
        "xhr.setRequestHeader('Content-Type', 'application/json');" +
        "xhr.send('%s');" +
        "return xhr.responseText;",
        method, endpoint, payload
    );

    return (String) ((JavascriptExecutor) driver).executeScript(script);
}

Pythonの例

def perform_api_call_with_js_executor(driver, endpoint, method, payload):
    script = f"""
        var xhr = new XMLHttpRequest();
        xhr.open('{method}', '{endpoint}', false);
        xhr.setRequestHeader('Content-Type', 'application/json');
        xhr.send('{payload}');
        return xhr.responseText;
    """

    return driver.execute_script(script)

3. APIコールの傍受と変更

Selenium WebDriverは、アプリケーションによって行われるAPIコールを傍受して変更するために使用できます。特に、BrowserMob Proxyのようなプロキシツールと組み合わせて使用する場合、効果的です。

BrowserMob Proxyを使用したJavaの例

import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import org.openqa.selenium.Proxy;

public void setupProxyForApiInterception() {
    // プロキシを起動
    BrowserMobProxy proxy = new BrowserMobProxyServer();
    proxy.start(0);

    // Seleniumプロキシオブジェクトを取得
    Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);

    // Chromeをプロキシを使用するように設定
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", seleniumProxy);

    // WebDriverインスタンスを作成
    driver = new ChromeDriver(options);

    // APIコールを傍受するためのリクエストフィルターを追加
    proxy.addRequestFilter((request, contents, messageInfo) -> {
        if (request.getUri().contains("/api/")) {
            System.out.println("傍受したAPIコール: " + request.getUri());
            // 必要に応じてヘッダー、パラメーター、またはリクエストボディを変更
        }
        return null;
    });

    // APIレスポンスを検査し、変更するためのレスポンスフィルターを追加
    proxy.addResponseFilter((response, contents, messageInfo) -> {
        if (messageInfo.getOriginalRequest().getUri().contains("/api/")) {
            String responseBody = contents.getTextContents();
            System.out.println("APIレスポンス: " + responseBody);
            // 必要に応じてレスポンスを変更
        }
    });
}

完全なAPIテストフレームワークを構築する

Selenium WebDriverを使用して、より構造化されたAPIテストフレームワークを作成しましょう:

Javaの例

import org.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.io.IOException;

public class ApiTestFramework {
    private WebDriver driver;
    private final String BASE_URL = "<https://api.example.com>";

    @BeforeClass
    public void setUp() {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless");
        driver = new ChromeDriver(options);
    }

    @Test
    public void testGetUserEndpoint() throws IOException {
        String endpoint = BASE_URL + "/api/users/1";
        String response = performGetRequest(endpoint);

        JSONObject jsonResponse = new JSONObject(response);

        Assert.assertEquals(jsonResponse.getString("name"), "John Doe");
        Assert.assertEquals(jsonResponse.getInt("id"), 1);
        Assert.assertTrue(jsonResponse.has("email"));
    }

    @Test
    public void testCreateUserEndpoint() throws IOException {
        String endpoint = BASE_URL + "/api/users";
        JSONObject payload = new JSONObject();
        payload.put("name", "Jane Smith");
        payload.put("email", "jane.smith@example.com");

        String response = performPostRequest(endpoint, payload.toString());
        JSONObject jsonResponse = new JSONObject(response);

        Assert.assertTrue(jsonResponse.has("id"));
        Assert.assertEquals(jsonResponse.getString("name"), "Jane Smith");
    }

    private String performGetRequest(String endpoint) throws IOException {
        // 前の例からの実装
    }

    private String performPostRequest(String endpoint, String payload) throws IOException {
        URL url = new URL(endpoint);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setDoOutput(true);

        // ペイロードを接続に書き込む
        try (java.io.OutputStream os = connection.getOutputStream()) {
            byte[] input = payload.getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        int responseCode = connection.getResponseCode();
        System.out.println("POSTレスポンスコード: " + responseCode);

        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(connection.getInputStream(), "utf-8"))) {
            StringBuilder response = new StringBuilder();
            String responseLine;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            return response.toString();
        }
    }

    @AfterClass
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

Pythonの例

import unittest
import json
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import requests

class ApiTestFramework(unittest.TestCase):
    BASE_URL = "<https://api.example.com>"

    def setUp(self):
        chrome_options = Options()
        chrome_options.add_argument("--headless")
        self.driver = webdriver.Chrome(options=chrome_options)

    def test_get_user_endpoint(self):
        endpoint = self.BASE_URL + "/api/users/1"
        response = self.perform_get_request(endpoint)

        self.assertEqual(response['name'], "John Doe")
        self.assertEqual(response['id'], 1)
        self.assertIn('email', response)

    def test_create_user_endpoint(self):
        endpoint = self.BASE_URL + "/api/users"
        payload = {
            "name": "Jane Smith",
            "email": "jane.smith@example.com"
        }

        response = self.perform_post_request(endpoint, payload)

        self.assertIn('id', response)
        self.assertEqual(response['name'], "Jane Smith")

    def perform_get_request(self, endpoint):
        response = requests.get(endpoint)
        return response.json() if response.status_code == 200 else None

    def perform_post_request(self, endpoint, payload):
        headers = {'Content-Type': 'application/json'}
        response = requests.post(endpoint, data=json.dumps(payload), headers=headers)
        return response.json() if response.status_code in [200, 201] else None

    def tearDown(self):
        if self.driver:
            self.driver.quit()

if __name__ == '__main__':
    unittest.main()

UIとAPIテストの統合

Selenium WebDriverを使用してAPIテストを行う最大の利点の一つは、同じフレームワークでUIテストとAPIテストを統合できることです:

@Test
public void testLoginAndVerifyUserDataAPI() throws IOException {
    // UI部分: UIを通じてログイン
    driver.get("<https://example.com/login>");
    driver.findElement(By.id("username")).sendKeys("testuser");
    driver.findElement(By.id("password")).sendKeys("password");
    driver.findElement(By.id("loginButton")).click();

    // ログインの完了を待つ
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    wait.until(ExpectedConditions.urlContains("/dashboard"));

    // クッキーまたはローカルストレージから認証トークンを抽出
    String authToken = (String) ((JavascriptExecutor) driver)
        .executeScript("return localStorage.getItem('authToken');");

    // API部分: トークンを使用して認証されたAPIコールを行う
    String endpoint = BASE_URL + "/api/user/profile";
    URL url = new URL(endpoint);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Authorization", "Bearer " + authToken);

    // APIレスポンスを処理および検証
    int responseCode = connection.getResponseCode();
    Assert.assertEquals(responseCode, 200);

    // レスポンスを読み取り、解析
    BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
    String response = in.lines().collect(Collectors.joining());
    in.close();

    JSONObject jsonResponse = new JSONObject(response);

    // APIデータがUIに表示される内容と一致することを確認
    String uiUsername = driver.findElement(By.id("profileUsername")).getText();
    Assert.assertEquals(jsonResponse.getString("username"), uiUsername);
}

Selenium WebDriverによるAPIテストのベストプラクティス

  1. ヘッドレスモードを使用する: 純粋なAPIテストを行う場合、リソースを節約するためにSeleniumをヘッドレスモードで実行します。
  2. APIテストとUIテストを分ける: 統合できる一方で、APIテストとUIテストは論理的に分けておくことが重要です。
  3. アサーションライブラリを活用する: APIレスポンスを検証するために包括的なアサーションライブラリを使用します。
  4. エラーハンドリングを実装する: APIの失敗に対する適切なエラーハンドリングを追加します。
  5. APIリクエストとレスポンスをログに記録する: デバッグの目的で、すべてのAPIインタラクションをログに記録します。
  6. テストをパラメータ化する: データプロバイダやパラメータ化されたテストを使用して様々なシナリオをテストします。
  7. 認証処理を実装する: 認証を処理するための再利用可能なメソッドを作成します。
  8. パフォーマンスを考慮する: Seleniumは専用のAPIテストツールと比較してオーバーヘッドが発生する可能性があることを意識します。

Selenium WebDriverによるAPIテストの制限

  1. パフォーマンスオーバーヘッド: Seleniumは主にブラウザの自動化用に設計されているため、純粋なAPIテストの場合オーバーヘッドが発生します。
  2. 限定的なAPI特有の機能: 専用のAPIテストツールはAPIテストに特化した機能を提供します。
  3. ブラウザ依存: ヘッドレスモードでも、Seleniumはブラウザを必要としますが、APIテストには不要な場合もあります。
  4. 複雑さ: APIテスト用にSeleniumを設定するのは、専用のAPIテストツールを使用するよりも複雑である可能性があります。

APIテストにSelenium WebDriverを使用するタイミング

Selenium WebDriverは、以下のシナリオでAPIテストに最も適しています:

  1. すでにSeleniumベースのUIテストフレームワークを持っていて、これを拡張したい場合。
  2. UIとAPIの相互作用が含まれるシナリオをテストする必要がある場合。
  3. ブラウザのコンテキストでAPIをテストする必要がある場合(JavaScript APIコールのテストなど)。
  4. アプリケーションによって行われるAPIコールを傍受して変更したい場合。

結論

Selenium WebDriverはAPIテストのための多目的なツールとなり得ます。特に既存のUIテストフレームワークと統合することで、その能力を発揮します。複雑なAPIテストニーズのために専用のAPIテストツールを置き換えることはできませんが、UIテストとAPIテストをシングルフレームワークで組み合わせるフレキシブルな方法を提供します。

このチュートリアルで提供されたアプローチと例を活用すれば、Selenium WebDriverを効果的にAPIテストの要件に利用できます。トレードオフを考慮し、自分の特定のテストニーズに最適なツールを選ぶことを忘れないでください。

REST API、SOAPサービス、またはGraphQLエンドポイントをテストする際には、Selenium WebDriverを利用して、アプリケーションのUIとその根底にあるAPI機能の両方を検証する包括的なテストを作成できます。

より高度なAPIテストニーズを持つ場合、Selenium WebDriverをREST Assured(Java用)やRequests(Python用)などの専用のAPIテストライブラリやフレームワークと組み合わせて、両方の利点を得ることを検討してください。

テストを楽しんでください!