Vue.js用テストライブラリ「avoriaz」入門

  • 20
    いいね
  • 0
    コメント

背景

Vue.js本家からは公式のテストライブラリは提供されておらず、非公式でvue-test, avoriaz, vue-testing, evue等が公開されています。それらの中で一番Star数が多いavoriazついて調査した内容をまとめます。

前提

  • Karma + Mocha + Chaiを利用する
  • 以下のHelloコンポーネントをテスト対象とする
Hello.vue
<template>
  <div id="hello">
    <img src="http://vuejs.org/images/logo.png">
    <h1>{{ msg }}</h1>
    <h2 class="subtitle">Essential Links</h2>
    <h2>Ecosystem</h2>
    <h3>nickname: {{ user.nickname }}</h3>
  </div>
</template>

<script>
export default {
  name: 'hello',
  props: ['user'],
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  methods: {
    hello: () => {
      return 'world'
    }
  }
}
</script>

<style scoped>
#hello {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.subtitle {
  font-size: 16px;
}

</style>

準備

インストール

$ npm install --save-dev avoriaz

API

mount

  • レンダリングされたVueコンポーネントのラッパーオブジェクトを返します。
  • 第2引数は任意で、Vue APIに沿ったstore, propsDataなどを渡すことが出来ます。
Hello.spec.js
import Hello from '../../src/components/Hello.vue'
import { mount } from 'avoriaz'

describe('Hello.vue', () => {
  it('mount', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
  })
})

contains

指定のセレクターが含まれているか検証できます。

  it('contains', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.contains('img')).to.be.eql(true)
    expect(wrapper.contains('h1')).to.be.eql(true)
    expect(wrapper.contains('h2')).to.be.eql(true)
  })

data

dataは、Vueインスタンスのdataオブジェクトを返します。dataオブジェクト内に、指定の値が入っているか検証できます。

  it('data', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    let msg = 'Hello World'
    wrapper.setData({msg: msg})
    expect(wrapper.find('h1')[0].text()).to.be.eql(msg)
    expect(wrapper.data().msg).to.be.eql(msg)
  })

find

セレクターで指定したDOMノードかVueコンポーネントの配列が返ります。指定したエレメントが存在するか検証できます。

  it('find', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.find('h2').length).to.be.eql(2)
    expect(wrapper.find('h2')[0].is('h2')).to.be.eql(true)
  }) 

hasAttribute

指定した属性が存在するか検証できます。

  it('hasAttribute', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.hasAttribute('id', 'hello')).to.be.eql(true)
  })

instance

Vueコンポーネントのインスタンスオブジェクトを返します。このオブジェクトを通じて、methodsやdataオブジェクトにアクセスできます。

  it('instance', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.instance().hello()).to.be.eql('world')
    expect(wrapper.instance().msg).to.be.eql('Welcome to Your Vue.js App')
  })

isVueComponent

Vueコンポーネントかどうか検証できます。(使うのか・・?)

  it('isVueComponent', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.isVueComponent).to.be.eql(true)
  })

methods

Vueオブジェクトのメソッドにアクセスできます。

  it('methods', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.methods().hello()).to.be.eql('world')
  })

但しmethods()を利用すると、以下のWarningが表示されvm経由で呼び出すことが案内されています。

warning: functions returned by methods() will not have this bound to the vue instance. Calling a method that uses this will result in an error. You can access methods by using the vue instance. e.g. to call a method function named aMethod, call wrapper.vm.aMethod(). See https://github.com/eddyerburgh/avoriaz/issues/15

name

コンポーネント名の検証ができます。(使うかな・・・?)

  it('name', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.name()).to.be.eql('hello')
  })

propsData

propDataのオブジェクトを返します。

  it('propsData', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.propsData().user.nickname).to.be.eql('John')
  })

但しpropsData()を利用すると、以下のWarningが表示されvm経由で呼び出すことが案内されています。

warning: functions returned by propsData() will not have this bound to the vue instance. Calling a propsData function that uses this will result in an error. You can access propsData functions by using the vue instance. e.g. to call a method function named propsDataFunc, call wrapper.vm.$props.propsDataFunc(). See https://github.com/eddyerburgh/avoriaz/issues/15

text

指定オブジェクトの文字列を返します。

  it('text', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.find('h1')[0].text()).to.be.eql('Welcome to Your Vue.js App')
  })

vm

vmプロパティは、Vueコンポーネントのオブジェクトを保持しています。それを通じて、data、methodsオブジェクトなどにアクセスできます。

  it('vm', () => {
    const wrapper = mount(Hello, {
      propsData: {
        user: {nickname: 'John'}
      }
    })
    expect(wrapper.vm.user.nickname).to.be.eql('John')
  })

まとめ

avoriazはドキュメント、サンプルコード共に充実しており、APIもとてもシンプルでした。Karma + Mocha, Karma + Jasmineなど各種テストライブラリの組み合わせのサンプルコードも公開されており、最初の導入の敷居はとても低い印象です。avoriazのようなフレームワーク専用のテストライブラリを利用することで、テストコードが書きやすくなので、コンポーネントのユニットテストを導入したい場合には利用すべきだと思いました。

参考