鈍足ランナーのIT日記

走るのが好きな5流のITエンジニアのブログ。

趣味の範囲は広いけど、どれも中途半端なクソブロガー楽しめるWebアプリを作ってあっと言わせたい。サーバーサイドPerl(Mojolicious)、クライアントサイドVue.js。Arduinoにも触手を伸ばす予定。

Vue+jestでテスト

以下のエラーが出てテストが通らない。

    console.error node_modules/vue/dist/vue.runtime.common.js:1715
      /Users/dokechin/work/gratan/src/assets/hero.jpeg:1
      ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){����
                                                                                               ^

jestで何か設定が足りないようです。

この辺だろうか・・
webpackのテンプレートに以下のプルリクを発見

github.com

これで、上記エラーは消えた。

次のエラーが現れる

        Failed to write coverage reports:
        ERROR: TypeError: metrics.isEmpty is not a function

これはhttps://github.com/facebook/jest/issues/5772

rm -rf node_modules
rm package-lock.json
npm install

次のエラー現れる

 Failed to write coverage reports:
        ERROR: TypeError: Cannot read property 'decl' of undefined
        STACK: TypeError: Cannot read property 'decl' of undefined
    at /Users/dokechin/work/gratan/node_modules/istanbul-reports/lib/lcovonly/index.js:32:38
    at Array.forEach (<anonymous>)
    at LcovOnlyReport.onDetail (/Users/dokechin/work/gratan/node_modules/istanbul-reports/lib/lcovonly/index.js:30:28)
    at LcovReport.(anonymous function) [as onDetail] (/Users/dokechin/work/gratan/node_modules/istanbul-reports/lib/lcov/index.js:21:24)
    at Visitor.(anonymous function) [as onDetail] (/Users/dokechin/work/gratan/node_modules/istanbul-lib-report/lib/tree.js:34:30)
    at ReportNode.Node.visit (/Users/dokechin/work/gratan/node_modules/istanbul-lib-report/lib/tree.js:123:17)
    at /Users/dokechin/work/gratan/node_modules/istanbul-lib-report/lib/tree.js:116:23
    at Array.forEach (<anonymous>)
    at visitChildren (/Users/dokechin/work/gratan/node_modules/istanbul-lib-report/lib/tree.js:115:32)
    at ReportNode.Node.visit (/Users/dokechin/work/gratan/node_modules/istanbul-lib-report/lib/tree.js:126:5)

そもそも、PWAテンプレートにjestサポートがないのが・・

前回のポストの後
vuetifyのユニットテストやっぱり、jestを使いたい - 鈍足ランナーのIT日記

Webpackテンプレートはjestをサポートしているのに、PWAテンプレートが
サポートしていないのがおかしい何とかしたいと思いたった。

技術のない私でもできるのか?
と思ったけれどやって見ると
そんなに難しくなかった。Webpackテンプレートを見ながら
取り込むだけだった。
とても勉強になった。
プルリクも久しぶりに送った。

しかーし。vue cliは3.0が開発中ですでに動かせる状態との情報が・・
これだとjestも選択的に取り込めるんだろうなぁ。と予想されます。

vue cli3.0の勉強をぼちぼちしてみよう。

vuetifyのユニットテストやっぱり、jestを使いたい

v-checkboxのユニットテストをしようとしたら、なかなかうまくいかない。
それはv-checkboxを展開したHTMLにinputタグが見えてこない。(階層が深いため?)
vuetify.jsのv-checkboxのテストソースを見たらjest.fn()を使っていて
jestを使ってテストしていた。

vue-cli(PWA)付属のユニットテストはkarmaを使ったテストになっているので
それをjestベースに書き換えてしようするようにしたい

npm install で以下のモジュールをインストール

  • jest
  • vue-jest
  • babel-jest
  • jest-serializer-vue
  • babel-plugin-transform-vue-jsx
  • babel-plugin-syntax-jsx
  • babel-plugin-dynamic-import-node

vue-cli(webpack)付属のユニットテストはjestベースなので、そちらのユニットテストのフォルダにある
jest.conf.jsとsetup.js,.babelrcをコピーして持ってきた。
とりあえず、これで起動できたけれど、jest用に一部書き換えないといけないようだ。
expectでエラーになっている。

to.contain()

toContain

equal

toBe

vuetifyのunitテストを動かす

背景

vue-cli で作ったwebpackサンプル+vuetifyで簡単なテストを動かそうとしているのですが、
[Vue warn]: $listeners is readonly.ワーニングが大量に出てしまう。。
なんでだろう。。

vue-test-utils?

まだベータバージョンだからかな。vue-test-utilsを捨てて、avoriazにして見たら嘘のようにエラーが消えた。

とりあえず環境は・・

うろ覚えだけど、一応書き留めておく。不足しているかもしれません。

モジュールのインストール

vuetifyをテストするには、polyfillというのが必要見たい。
あとはテストにasync,awaitを記述したいのでその辺のモジュールも必要になりました。

npm install --save-dev avoriaz
npm install --save-dev babel-plugin-transform-async-to-generator
npm install --save-dev babel-polyfill
npm install --save-dev babel-preset-stage-3

.babelrcの編集

stage-2と描いてあるところをstage-3へ(async,awaitを使うため)

index.jsの編集

testの起点のindex.jsの先頭行に以下の記載。

import 'babel-polyfill'

あとはテストを書くだけ

import { mount } from 'avoriaz'
import Vue from 'vue'
import Vuetify from 'vuetify'
import Shop from '@/components/Shop'
import VueI18n from 'vue-i18n'
import { store } from '../../../src/store/store.js'

Vue.use(Vuetify)
Vue.use(VueI18n)

const data = require('../../../src/i18n/message.json')

const i18n = new VueI18n({
  locale: 'ja',
  messages: data
})

describe('Shop.vue', () => {
  it('should render correct contents', () => {
    const wrapper = mount(Shop, {i18n, store})
 // 以下テストがつづく・・・

asyncはnode7.10.1から使える

https://node.green

これを見るとので7.10.1からasyncの機能が使えるはず。
今回はnodeのバージョン6でやろうとしていたので、トランスパイルでasync系を変換する必要があった。
結局node9.11.1にしたら必要なモジュールが減った。大分スッキリした。

npm install --save-dev avoriaz
npm install --save-dev babel-polyfill

トランスパイル周りの知識がイマイチよくわかっていないなぁ。
変換前のnode環境、変換後のnode環境。
node9.11.1はasyncを変換しなくても動くからトランスパイルが不要になるということなんだろうけど・・・

Karmaのテストコードでawaitが使えない

babelの設定を見直していたけど、よくよく考えたら
Webアプリのソース(vue)でawaitを使っているわけではなくて
テストコードの中で使っている。
Webアプリのソースはトランスパイル対象で、テストコードは
トランスパイルの対象ではないのかな?(全然わかっていない)

もしかしたらnodeのバージョンをあげれば解決するのでは
と思いバージョンを調べると

tachimitetsuya-no-MacBook-Air:~ dokechin$ node --version
v6.11.4

awaitが使えないバージョンのようでした。

やっぱり使えないと思いきや・・・

テストコードの方が間違っていた asyncブロックの中でawaitは使わないといけないのか!!

  it('adds a new shop', () => {  // bad

  it('adds a new shop', async () => {  // good

vue-test-utils+バリデーション

テキストフィールドに値を入れると、バリデーションが実行されて、formValidがtrueになるテスト
を描いて見たが・・trueにならない

const input = wrapper.find('input#name')
input.element.value = 'AEON'
input.trigger('input')
expect(wrapper.vm.editedItem.name).equal('AEON')
expect(wrapper.vm.formValid).equal(true)

await

await flushPromises()を追加

@vue/test-utilsで非同期イベントのテスト - Qiita

npm install --save-dev flush-promises
PhantomJS 2.1.1 (Mac OS X 0.0.0) ERROR
  Error: Module build failed: SyntaxError: await is a reserved word 

あちゃ、全然わからんなぁ。

awaitを使えるようにしたい!

設定ファイルを覗いたり、ググりまくりました。
今の環境の設定.babel.rc

{
  "presets": [
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
  "plugins": ["transform-runtime"],
  "env": {
    "test": {
      "presets": ["env", "stage-2"],
      "plugins": [ "istanbul" ]
    }
  }
}

stage-2というのは、awaitをサポートしていないバージョンらしい。
state-3をインストールしてあげればいい

babel stage-3のインストール

npm install --save-dev babel-preset-stage-3

.babel.rcをstage-2からstage-3へ編集

編集して、npm run unitを実行して見ましたが、依然としてawaitは使えない。
何が悪いのか?

transform-async-to-generatorのインストールも必要?

Async to generator transform · Babel