ローカル環境で簡単にテスト可能なルーター駆動開発を作ってみました

# この記事は古いです
最新は以下レポジトリでご確認できます
https://github.com/ampcpmgp/am-coffee-time


## こんな感じに動きます

以下の適当なログインページに対しテストを行うと
https://ampcpmgp.github.io/amdev/modules/am-coffee-time/web/

↓　こんな感じに動きます

![coffee-time.gif](https://qiita-image-store.s3.amazonaws.com/0/85111/272d426a-0f72-7f21-daa7-a363971297a8.gif)


対象ページ（リストページ）はこちら。
https://ampcpmgp.github.io/amdev/modules/am-coffee-time/web/list.html


## 使い方の３ステップ
### 1. テストパターンの生成
まずはリストページにて`test-listタグ`を作り、`generateモジュール`を読み込みます。

推奨は以下のようにnpmから取得することですが、

```
//command
npm install am-coffee-time
//js
import generate from 'am-coffee-time/browser/generate'
```
今回は簡単にscriptタグから読み込みます。

```html
<body>
  <test-list></test-list>
  <script src="//ampcpmgp.github.io/amdev/modules/am-coffee-time/browser/generate.js" charset="utf-8"></script>
  <script>
    if (1) {
      const generate = this["modules/am-coffee-time/browser/generate"]
    }
  </script>
</body>
```

次に、constに続く箇所へ、パターンとオプションを設定します。

```javascript
let patterns = {
  "全パターン": {
    "動作フロー確認用": {
      "結果=成功": "./index.html",
      "結果=失敗": "./index.html"
    },
    "ID入力=melon": {
      "PW入力=google": "./index.html",
      "PW入力=apple": "./index.html"
    }
  }
}
let opts = {
  files: [
    "//ampcpmgp.github.io/amdev/modules/am-coffee-time/browser/Test.js", // 上記パターンに連動するモジュール
    "//ampcpmgp.github.io/amdev/modules/am-autoevent/browser/AutoEvent-no-gen.js", // ブラウザアクションを楽に書くモジュール
    "./test.src.js" // パターン２で作るファイル
  ]
}
generate(patterns, opts)
```

patternのキーには、アクションを書き、値にはテストをしたい対象ページをURLで入力します。各アクションはスラッシュ区切りで結合され、ハッシュタグをベースとしたルーターとして扱われます。
`全パターン/動作フロー確認用`のように。
_(patternはjsonで書いていますが、yaml/csonを推奨します。見やすいので。)_

optsは必須ではないですが、今回は外部ファイルを流し込むテスト方式のため、`files`キーに、テストしたいページへ読み込みたいファイルを順番で指定します。


### 2. テストページでパターンを受け取り、イベント発火

test.src.js

```javascript
const Test = this["modules/am-coffee-time/browser/Test"]
let actions = {
  動作フロー確認用() {
    console.log("動作フロー確認です")
  },
  結果(値) {
    if (値.match("成功")) console.assert(true)
    else if (値.match("失敗")) console.assert(false, "失敗です")
    console.info("finished")
  }
}
Test.start(actions)
```

Testの使い方は、リストで指定しておいたキーを、`actions`のキーで指定します。
キーは、`=`があると分断され、前方はキー、後方は引数の値に格納されます。
値は`,`があると配列として返ります。

リストページでは、テストページの`console.assert`と、`console.info`を監視しています。
`assert`が通らなかった瞬間、処理を止めエラーとして扱われます。
`info`で`finished`が入力されると、処理を止め成功として扱われます。

上記の例では、結果の値が失敗だったときに、エラーとして扱われます。


### 3. 関連モジュールautoeventを利用しブラウザテストを簡易に

詳しいAPIはこちらに書いています。
https://github.com/ampcpmgp/amdev/tree/master/modules/am-autoevent

サンプルコードは以下です。

```javascript
const Test = this["modules/am-coffee-time/browser/Test"]
const AutoEvent = this["modules/am-autoevent/browser/AutoEvent-no-gen"]
let autoEvent = new AutoEvent()
let $ = (selector) => document.querySelector(selector)
let actions = {
  ID入力(value) {
    autoEvent
      .wait(400).setValue(`[name="id"]`, value)
  },
  PW入力(value) {
    autoEvent
      .wait(400).setValue(`[name="pw"]`, value)
      .wait(400).click('[name="check"]')
      .wait(400).addEvent(() => console.assert($("after-login"), `after-login not found`))
  }
}

autoEvent.register()
Test.start(actions)
autoEvent.start(1, () => console.info("finished"))
```


## これで準備は終わりです！
あとは適当にクリックし、戻る　進む　を押せばテストをやめたり戻ったりします。
URLをクリックしたあと、URLの値を変えると、コードを書かずとも別なテストも行えます。


## 自分が思うメリット
* パターンを動作単位で、ウェブ上で一覧化しているので、非エンジニアにも見やすい作りになっている。
* イベントをモック化しているので、開発中のクリックやキー入力動作を軽減出来る。SPA開発がちょっと楽しくなる。
* エラーが有ったときに、すぐさまその状態へ連れていってくれる。


動作が複雑なページであるほど便利だと思います。


## 終わりに
今回作ったものは、原則、同一ドメインでのみ動作します。（XSSのため）

electron/webviewを使い、nodeのテストも可能になっていますが、まだ安定していないので保留中。

今後はelectronをベースとし、他ドメイン・他ページ遷移、CI連携を進めていこうと考えています。
nightmareと一部競合するので、役割を明確にしまた出来上がったら記事を共有しようと思います！

<(_ _)>


https://github.com/ampcpmgp/amdev/tree/master/modules/am-coffee-time