45
45

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.

Riotのテストと宿命の反乱(karma-riot)

Last updated at Posted at 2015-09-12

AngularのテストではおなじみのKarma(=宿命、業)ですが、すごい名前ですよね...。karmaのRiotプラグインは日本語だと「宿命の反乱」でしょうか。フロントエンドのテストの話です、念のため。

というわけで、Riotの公式リポジトリにこのKarmaプラグインが仲間入りしたので、簡単に要所をまとめたいと思います。

アプリケーション構成(例)

極小構成ということで、この記事の登場人物はこの5ファイルだけです。動いているのをまず触りたいという方は、こちらにPlunkerで編集可能なものがあります。ソースとテスト一式はこちら。

  • app.tag
  • index.html
  • karma.conf.js
  • package.json
  • test/
    • specs.js

Riot Router Example: Page Switching.png

アプリケーション本体

まずapp.tagですが、簡単なルーティングのデモになっています。ここではテストの説明が主眼なので、細かい話は略。

<app>
  <nav><a each={ data } href="#{ id }">{ title }</a></nav>

  <article>
    <h1>{ page.title || 'Not found' }</h1>
    <p>{ page.body || 'Specified id is not found.' }</p>
  </article>

  <script>
    var self = this
    self.data = [
      { id: "", title: "Home", body: "Click the link above." },
      { id: "1", title: "First", body: "This is the first page." },
      { id: "2", title: "Second", body: "This is the second page." }
    ]
    self.page = self.data[0]

    riot.route(function(id) {
      self.page = self.data.filter(function(r) { return r.id == id })[0] || {}
      self.update()
    })
  </script>
</app>

アプリケーションとしては、これ(↑)をindex.htmlから呼び出すだけ。

<!doctype html>
<html>
  <head>
    <title>Riot Router Example: Page Switching</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  </head>
  <body>
    <app></app>
    <!-- riot tags -->
    <script type="riot/tag" src="app.tag"></script>
    <!-- scripts we need -->
    <script src="https://cdn.jsdelivr.net/g/riot@2.2(riot.min.js+compiler.min.js)"></script>
    <!-- mount this app -->
    <script> riot.mount('app') </script>
  </body>
</html>

必要なライブラリのインストール

少なくとも、次の3つは必ずインストール。

$ npm install --save-dav riot karma karma-riot

この辺も入れておきましょう。※好みのライブラリに適宜差し替えてください。

$ npm install --save-dav expect.js karma-mocha karma-mocha-reporter karma-phantomjs-launcher

package.jsonの中身はこんな感じになっているはずです。あと、テストの起動用にscriptsのところに記述をお忘れなく。

{
  "devDependencies": {
    "expect.js": "^0.3.1",
    "karma": "^0.13.9",
    "karma-mocha": "^0.2.0",
    "karma-mocha-reporter": "^1.1.1",
    "karma-phantomjs-launcher": "^0.2.1",
    "karma-riot": "^1.0.0",
    "riot": "^2.2.4"
  },
  "scripts": {
    "test": "karma start"
  }
}

karmaの設定

さて、このアプリケーション(と呼んでいいのか...)をテストしてみたいと思います。karmaの出番です。jasmineでもOKですが、ここではなんとなくmochaで。karma.conf.jsはこんな感じに。

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['mocha', 'riot'], // フレームワークにriotを指定
    plugins: [
      'karma-mocha',
      'karma-mocha-reporter',
      'karma-phantomjs-launcher',
      'karma-riot' // プラグイン指定
    ],
    files: [
      'node_modules/expect.js/index.js', // chaiとか好きなものでOK
      '**/*.tag', // タグファイルの指定
      'test/**/*.js' // テストファイルの指定
    ],
    preprocessors: {
      '**/*.tag': ['riot'] // プリプロセッサにriotを指定
    },
    browsers: ['PhantomJS'],
    reporters: ['mocha'],
    singleRun: true
  })
}

karmaはfilesで指定したファイルと、フレームワークで必要とするファイルをテスト時に自動的に読み込みます。その際、CoffeeScriptを自動変換したりするのに使えるのが、プリプロセッサです。karma-riotプラグインが読み込まれていれば、Riotのタグもよしなにkarmaが変換してくれます。

プロダクション用をBrowserifyで1ファイルに固めてると、単一タグのテスト用に別途コンパイルが必要だったりしますが、このプリプロセッサがあればそれも不要ですね。

その他の部分は、ごく一般的なkarmaの設定です。詳しくはkarmaの公式サイトをどぞ。

テスト

ここまででお膳立てはできたので、テスト本体です。ここではdocument.bodyの直下にDOMを追加して、そこにテストしたいタグをマウントする形をとりました。例として、(1)タグのマウントの確認、(2)ルーターの挙動をチェックするテストを入れています。

describe('Application specs', function() {

  before(function() {
    // create mounting points
    var html = document.createElement('app')
    document.body.appendChild(html)
  })

  it('タグのマウント', function() {
    riot.mount('app')
    expect(document.querySelector('article > h1').textContent)
      .to.be('Home')
  })

  it('別URLに移動して表示内容を切り替え', function() {
    riot.route('1') // http://localhost/1
    expect(document.querySelector('article > h1').textContent)
      .to.be('First')

    riot.route('2') // http://localhost/2
    expect(document.querySelector('article > h1').textContent)
      .to.be('Second')
  })

})

例では1ファイルにまとめていますが、長くなってきたら、テストのカテゴリーごとにファイルに分けていきます。

テストの実行

さあ、あとは...

$ npm test

するだけです。全部のテストがクリアなら"xx tests completed"と表示されます。

router-page-switcher — bash — 93×20.png

まとめ

Riotは見た目のHTMLっぽさが際立っていて、テストといってもピンとこないかもですが...、2ファイル(karma.conf.jsとテストファイル)を足すだけから始められます。やんなきゃ!

あとは、APIを叩くテストが入るならSinon.JSを叩くもよし、単体テストで切り出せるならmochaだけでテストしてもよし、普段のやり方でどぞ。

45
45
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
45
45

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?