9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TestCafeの導入からお問い合わせフォームのSampleまで

Last updated at Posted at 2017-11-12

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)

## 参考サイト

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?