JavaScript(Node.js)でSeleniumを使って自動UIテストをする方法

技術

はじめに

こんにちは!さいけです。

今回は「JavaScript(Node.js)でSeleniumを使って自動UIテストをする方法 」を紹介します!

また、前回のJava編と似たような内容です。m(_ _)m

JavaScript(Node.js)でSeleniumを使って自動UIテストをする方法

Seleniumとは?

まず、Seleniumについて簡単に説明します。

Seleniumとは、webブラウザの自動操作を行えるライブラリです。

利用用途は様々ですが、主にテストの自動化に用いられます。

利用環境

本記事で利用する環境は以下です。

  • MacOS Catalina 10.15.2
  • Visual Studio Code 1.33.1
  • node 12.13.0
  • npm 6.12.0
  • Google Chrome 79

利用準備

Seleniumを動かすためのパッケージをインストールします。

以下のパッケージをインストールします。

  • mocha
  • selenium-webdriver
  • chromedriver

以下コマンドでまとめてインストールすることができます。

$ npm install -D selenium-webdriver mocha chromedriver@79.0.0

また、chromedriverにおいては、利用しているchromeブラウザのバージョンと合わせてください。

今回はchromeブラウザのバージョンは79なので、@79.0.0で79バージョンを指定してインストールします。

テストを書いてみる

当ブログに対するテストを書きました。

実施するUIテストは以下となります。

  • ブログホームのページタイトルが「さいけの技術ブログ」と表示されているか検証
  • ブログホームの技術タブをクリックし技術ページに遷移するか検証

コードは以下です。

const { Builder, By } = require("selenium-webdriver");
const assert = require("assert");

let driver;

describe("SeleniumChromeTest", () => {
  before(() => {
    driver = new Builder().forBrowser("chrome").build();
  });

  after(() => {
    return driver.quit();
  });

  it("正常系_表示_ページタイトル", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com");

    // 要素を取得
    const title = await driver.getTitle();

    // 検証
    assert.equal(title, "さいけの技術ブログ");
  });

  it("正常系_遷移_技術ページ", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com");

    // タブの「技術」要素を取得し、クリックする
    await driver.findElement(By.id("menu-item-37")).click();

    // 要素を取得
    const title = await driver.getTitle();
    const currentUrl = await driver.getCurrentUrl();

    // 検証
    assert.equal(title, "技術 – さいけの技術ブログ");
    assert.equal(
      currentUrl,
      "https://saikeblog.com/category/%e6%8a%80%e8%a1%93/"
    );
  });
});

テストコードを実行するための準備

package.jsonにmochaでテスト実行をするnpm scriptを追加します。

タイムアウトは一旦無効にしたいため、「–timeout 0」を指定します。

ちなみにデフォルトのタイムアウト値は2000msです。

"scripts": {
...
    "test": "mocha test/SeleniumChromeTest.js --timeout 0",
...
  },

テストを実行してみる

以下コマンドを実行して、テストの実行をしてみます。

$ npm run test

通りました!

今度は実行結果と期待値をずらして、テストが落ちるか検証してみます。

書き換えるテストケースは「正常系_遷移_技術ページ」で、以下のようにassert.equalを書き換えます。

assert.equal(title, "技術 – さいけの技術ブログ");
↓
assert.equal(title, "さいけの技術ブログ");

遷移したページタイトルと期待しているページタイトルは違うので、落ちるはずです。

ちゃんと落ちました!

👍🎉

おまけ

おまけですが、表示、整合、遷移、動作を担保するテストケースをざっと書いてみました。

以下、サンプルコードです。参考にしてみてください!

const { Builder, By } = require("selenium-webdriver");
const assert = require("assert");
require("date-utils");

let driver;

describe("SeleniumChromeTest", () => {
  before(() => {
    driver = new Builder().forBrowser("chrome").build();
  });

  after(() => {
    return driver.quit();
  });

  it("正常系_表示_ページタイトル", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com");

    // 要素を取得
    const title = await driver.getTitle();

    // 検証
    assert.equal(title, "さいけの技術ブログ");
  });

  it("正常系_表示_コピーライト", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com");

    // 要素を取得
    const title = await driver.getTitle();
    const copyright = await driver
      .findElement(By.className("source-org"))
      .getText();

    // 現在の年を取得する
    const year = await new Date().toFormat("YYYY");

    // 検証
    assert.equal(title, "さいけの技術ブログ");
    assert.equal(
      copyright,
      "Copyright © " + year + " さいけの技術ブログ All Rights Reserved."
    );
  });

  it("正常系_整合_URL", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com");

    // 要素を取得
    const currentUrl = await driver.getCurrentUrl();

    // 検証
    assert.equal(currentUrl, "https://saikeblog.com/");
  });

  it("正常系_遷移_技術ページ", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com");

    // タブの「技術」要素を取得し、クリックする
    await driver.findElement(By.id("menu-item-37")).click();

    // 要素を取得
    const title = await driver.getTitle();
    const currentUrl = await driver.getCurrentUrl();

    assert.equal(title, "技術 – さいけの技術ブログ");
    assert.equal(
      currentUrl,
      "https://saikeblog.com/category/%e6%8a%80%e8%a1%93/"
    );
  });

  it("正常系_動作_検索", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com");

    // 検索ボックス要素にjavaを入力し検索する
    await driver.findElement(By.name("s")).sendKeys("java\n");

    // 要素を取得
    const title = await driver.getTitle();
    const currentUrl = await driver.getCurrentUrl();

    assert.equal(title, "“java” の検索結果 – さいけの技術ブログ");
    assert.equal(currentUrl, "https://saikeblog.com/?s=java");
  });

  it("正常系_動作_ページング_次へボタン", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com");

    // 画面下部にスクロールするjavascriptを実行
    await driver.executeScript(
      "window.scrollTo(0, document.body.scrollHeight);"
    );

    // 「>」要素をクリックする
    await driver.findElement(By.className("next")).click();

    // 要素を取得
    const currentUrl = await driver.getCurrentUrl();

    assert.equal(currentUrl, "https://saikeblog.com/page/2/");
  });

  it("正常系_動作_ページング_前へボタン", async () => {
    // 指定したURLに遷移する
    await driver.get("https://saikeblog.com/page/2/");

    // 画面下部にスクロールするjavascriptを実行
    await driver.executeScript(
      "window.scrollTo(0, document.body.scrollHeight);"
    );

    // 「<」要素をクリックする
    await driver.findElement(By.className("prev")).click();

    // 要素を取得
    const currentUrl = await driver.getCurrentUrl();

    assert.equal(currentUrl, "https://saikeblog.com/");
  });
});

おわりに

前回はJava編で、今回はJavaScript(Node.js)編を紹介しました。

言語やテストフレームワークが違うので、そこに関しては結構大変でした。

ですが、SeleniumAPIに関してはほとんど一緒なので、あまり苦労せずに書けました。

Seleniumを活用して、テストの効率化をしていきたいですね。

また、興味があればJava編も覗いてみてください!

では〜

コメント

タイトルとURLをコピーしました