前々からテスト自動化に興味はあったものの、中々踏み出せず、手動でテストしていた私ですが、
ついに一歩踏み出しました。
いざ試してみると思ったより簡単だったので驚きました。
Seleniumの他には、下記ツールを使用します。
mocha
テスティングフレームワーク
chai
アサーションライブラリ
今回はkintone開発において、Seleniumを使ってテストを自動化する手順を記載します。
といっても自動でログインする所までですが…。
とはいえ、ログインまでテストできれば、要素の取得や、要素の出現までの待機など、最低限の機能の使い方が理解できることと思います。
テスト内容
今回テスト対象とするのは、「kintoneにログインができること」とします。
「kintoneにログインができること」とは、ログイン後にリダイレクトされる https://○○○○.cybozu.com/k/#/portal にアクセスできること、とします。
必要な処理
その為に必要な処理は、こんな感じ。
- 指定のサブドメインにアクセスする。
- 「ログイン名」テキストフィールドに正しいログイン名を入力する。
- 「パスワード」テキストフィールドに正しいパスワードを入力する。
- 「ログイン」ボタンをクリックする。
- cybozu.comにログインし画面遷移後、「kintone」のボタンをクリックする。
- 現在のURLをテストする。
「ログイン名」と「パスワード」を入力して「ログイン」ボタンをクリック。
「kintone」ボタンをクリック。
環境構築手順
0.環境一覧
手順の前に今回確認した環境は以下の通り。
- Node.js:8.11.4
- selenium-webdriver:4.0.0-alpha.5
- chromedriver:77.0.0
- mocha:6.2.1
- chai::4.2.0
1.パッケージ初期化
任意のディレクトリでパッケージ初期化処理をします。
$ npm init -y
-y オプションは対話のスキップ
2.npmで必要ライブラリをインストール
前提として、Node.jsはインストール済みとします。
npmを使用して必要ライブラリをインストールします。
$ npm i --save-dev selenium-webdriver chromedriver mocha chai
ここから少し脱線
上記コマンドではグローバルインストールは使用せずにライブラリをインストールしています。
これは、Qiitaの記事を参考にして使用しないという結論に至りました。
グローバルインストールにしないとコマンドが冗長になると思っていましたが、scriptsに記載する事でその点も解消されるようでしたので。
脱線ここまで
3.package.jsonのscriptsにコマンドを追加
下記scriptsの部分に、
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
下記のようにmochaのコマンドを追加する。
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "mocha": "mocha" }
これで npm run mocha ファイル名.js のコマンドで実行できるようになる。
4.設定ファイルを作成
手順1.と同じディレクトリに設定ファイルとして setting.json を作成します。
setting.jsonの内容は下記の通り。
もちろんそれぞれの環境のドメイン、ログイン名、パスワードを入力します。
{ "domain": "domainhogehoge", "loginName": "name", "passWord": "pass" }
5.追加コンポーネントをダウンロード
公式ドキュメントより、追加コンポーネントをダウンロードします。
今回はChromeを選択。
ダウンロード後、解凍し、exeを手順1.と同ディレクトリに配置します。
テストコード
ファイル名は、test.js とします。
コード全体
全体のコードとしては下記の通り。
const fs = require("fs"); const chai = require("chai"); const webdriver = require('selenium-webdriver'); const setting = JSON.parse(fs.readFileSync('./setting.json', 'utf-8')); const driver = new webdriver.Builder().forBrowser('chrome').build(); // 対象ドメイン const TEST_DOMAIN = "https://" + setting.domain + ".cybozu.com"; describe("ログイン", function() { it("ログインできること", async function() { await login(); chai.expect(await driver.getCurrentUrl()).to.equal(TEST_DOMAIN + "/k/#/portal", "URLが異なります。"); }); }); async function login() { await driver.get(TEST_DOMAIN); await driver.findElement(webdriver.By.id('username-:0-text')).sendKeys(setting.loginName); await driver.findElement(webdriver.By.id('password-:1-text')).sendKeys(setting.passWord); await driver.findElement(webdriver.By.className('login-button')).click(); await driver.wait(webdriver.until.elementLocated(webdriver.By.xpath('//a[@title="kintone"]')), 3000); await driver.findElement(webdriver.By.xpath('//a[@title="kintone"]')).click(); }
テスト部分
実際にテストしている部分は以下。
describe("ログイン", function() { it("ログインできること", async function() { await login(); chai.expect(await driver.getCurrentUrl()).to.equal(TEST_DOMAIN + "/k/#/portal", "URLが異なります。"); }); });
- it()内で async functionとして宣言する。
- login()処理の官僚を待つ為、await指定する。
- 現在のURLを取得するgetCurrentUrl()も非同期処理となっている為、await指定する。
ログイン処理部分
Seleniumにより自動でログインしている部分は以下。
async function login() { await driver.get(TEST_DOMAIN); await driver.findElement(webdriver.By.id('username-:0-text')).sendKeys(setting.loginName); await driver.findElement(webdriver.By.id('password-:1-text')).sendKeys(setting.passWord); await driver.findElement(webdriver.By.className('login-button')).click(); await driver.wait(webdriver.until.elementLocated(webdriver.By.xpath('//a[@title="kintone"]')), 3000); await driver.findElement(webdriver.By.xpath('//a[@title="kintone"]')).click(); }
findElement()ではid、class、xpathで取得しているだけです。
cybozu.comへログイン後の「kintone」ボタンのみ、すぐに表示されないようでしたので、waitしてます。
テストの実行
テストの実行は下記コマンドで実行する。
$ npm run mocha test.js
ただし、デフォルトのタイムアウトが2000msとなっており、私のケースではブラウザ立ち上げから画面遷移でタイムアウトとなってしまいました。
その為、実行時の引数でタイムアウト時間を指定します。
$ npm run mocha test.js -- --timeout 10000
タイムアウト10000msとする。
正常にテストが通ればこんな感じで表示されます。
√ ログインできること (4354ms) 1 passing (4s)
おわりに
参考にしたページは下記の通りです。ありがとうございます。
要素が取得するまでの待ちや、非同期も問題なくできるようなので、本格的に業務にも取り入れられそうな予感です。