TestCafeとは
ブラウザテストを自動化するjavascriptのフレームワークになります。
async/awaitやimport機能を使いながらテストコードを書くことができます。
Seleniumとの違い
「Selenium」はjavascriptで書くブラウザテストで有名なフレームワークですが「TestCafe」との大きな違いがあります。
- TestCafeでは各ブラウザのWebdriverを設定する必要がない
- Node.jsをインストールしてない環境でもTestCafeでテスト結果を見ることができる。
作業環境構築
TestCafeをインストール
command
$ npm init
$ npm i testcafe -D // ローカルにtestcafeをインストール
$ export PATH=$PATH:./node_modules/.bin // パスを通す
$ testcafe -v // versionが表示されればインストール成功
ローカル環境でテスト実行
command
$ npm i http-server -D // ローカルにhttp-serverをインストール
package.json
{
"name": "testcafe",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "http-server -o" // npm startでブラウザ起動
},
"author": "",
"license": "ISC",
"devDependencies": {
"http-server": "^0.10.0",
"testcafe": "^0.18.2"
}
}
command
$ npm start // http://127.0.0.1:8080が起動
TestCafeのテンプレート
javascript
test.js
// import 文
// 変数・定数等の宣言
fixture('テスト内容の分類やページのタイトル等')
.page('テストするページのURL');
test('テスト項目名その1', async t => {
// テスト記入
});
test('テスト項目名その2', async t => {
// テスト記入
});
test('テスト項目名その3', async t => {
// テスト記入
});
テスト実行
command
$ testcafe chrome,safari ./test.js
お問い合わせフォームのSample
- 入力項目「お名前」 ※必須項目
- 送信ボタンを押下したとき「お名前」が入力されているかチェック
- 入力された場合、送信する旨をダイアログで表示してthanks.htmlに遷移
- 入力されない場合、エラーメッセージを表示
- 戻るボタンを押下したとき「TOPページ」に戻る
HTML
contact.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>TestCafe お問い合わせフォーム</title>
<style>
.errorMessage {
display: none;
}
.button {
display: flex;
}
</style>
</head>
<body>
<form>
<div class="errorMessage"></div>
<table>
<tr>
<th>お名前 <span>※</span></th>
<td><input type="text" name="name" class="name" required /></td>
</tr>
</table>
<div class="button">
<div><input type="button" value="戻る" class="back" onclick="location.href='/demo/'" /></div>
<div><input type="button" name="submit" value="送信" class="submit" /></div>
</div>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(function() {
formAction.init();
});
/*
名前入力が空白だったらエラーメッセージを表示
名前入力の値をSessionStorageのnameにsetして、thanks.htmlでgetする
*/
var formAction = {
init: function() {
var self = this;
self.nameSelector = $('.name');
self.errorMessageSelector = $('.errorMessage');
self.submitSelector = $('.submit');
self.errorMessageNone = self.errorMessageSelector.hide();
self.submitAction();
},
submitAction: function() {
var self = this;
self.submitSelector.on('click', function() {
if (self.nameSelector.val() === '') {
self.errorMessageAction(true);
return false;
}
self.errorMessageAction(false);
self.confirmAction();
});
},
errorMessageAction: function(errorMessage) {
var self = this;
if (errorMessage) {
self.errorMessageSelector.show().text('必須項目にご記入ください');
} else {
self.errorMessageNone;
}
},
confirmAction: function() {
var self = this;
if (confirm('この内容で送信します。')) {
self.submitSelector.prop('disabled', true);
sessionStorage.setItem('name', self.nameSelector.val());
setTimeout(function() {
document.location.href = 'thanks.html';
}, 1000);
} else {
return false;
}
}
}
</script>
</body>
</html>
thanks.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>TestCafe 完了画面</title>
</head>
<body>
<p class="thanksMessage">
<span class="name"></span>様、お問い合わせありがとうございます。
</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(function() {
thanksAction.init();
});
/*
名前の値をSessionStorageから取得する
*/
var thanksAction = {
init: function() {
var self = this;
self.nameSelector = $('.name');
self.nameGet = sessionStorage.getItem('name');
self
self.thanksDisplay();
},
thanksDisplay: function() {
var self = this;
self.nameSelector.text(self.nameGet);
}
}
</script>
</body>
</html>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>TestCafe</title>
</head>
<body>
<p>TOPページ</p>
</body>
</html>
テストコード
contactTest.js
import Page from './pageModel';
import { ClientFunction } from 'testcafe'; // 現在のページのURLを確認
const page = new Page();
const getWindowLocation = ClientFunction(() => window.location);
fixture('お問い合わせフォーム')
.page('http://127.0.0.1:8080/demo/contact.html'); // 実行するページ
test('必須項目を入力して確認後、thanksページに遷移', async t => {
await t
// テスト実行速度 1が最高速 0.01が最低速
.setTestSpeed(page.setTestSpeed)
// ダイアログの操作
.setNativeDialogHandler(() => true)
// アクション
.typeText(page.nameSelector, '佐藤一郎')
.click(page.submitSelector);
// アサーション(求める結果)
await t.expect(page.thanksMessage.innerText).eql('佐藤一郎様、お問い合わせありがとうございます。');
});
test('必須項目に入力されていないとき、errorMessageを表示', async t => {
await t
.setTestSpeed(page.setTestSpeed)
.click(page.submitSelector);
await t.expect(page.errorMessage.innerText).eql('必須項目にご記入ください');
});
test('戻るを押下したときにtopページに戻る', async t => {
await t
.setTestSpeed(page.setTestSpeed)
.click(page.backSelector);
const location = await getWindowLocation(); // ページ遷移してから現在のURLを取得
await t.expect(location.pathname).eql('/demo/');
});
pageModel.js
import { Selector } from 'testcafe';
/*
Page Object
*/
export default class Page {
constructor () {
this.nameSelector = Selector('.name');
this.submitSelector = Selector('.submit');
this.thanksMessage = Selector('.thanksMessage');
this.errorMessage = Selector('.errorMessage');
this.backSelector = Selector('.back');
this.setTestSpeed = 0.5;
}
}
テスト実行
command
$ testcafe chrome ./contactTest.js
Running tests in:
- Chrome 61.0.3163 / Mac OS X 10.13.1
お問い合わせフォーム
✓ 必須項目を入力して確認後、thanksページに遷移
✓ 必須項目に入力されていないとき、errorMessageを表示
✓ 戻るを押下したときにtopページに戻る
3 passed (8s)
## 参考サイト