水無月の余韻 開発Sc.

プログラミング関連の雑記

testemを使ったjavascriptテストの自動化

javascriptのテスト実行に、testemを使ってみました。

testem

testem は、テストランナーです。 https://github.com/airportyh/testem

大きな特徴は、3つです。

  1. 複数のテストフレームワーク(jasmine, mocha, QUnitなど)に対応
  2. Node.js、phantomJSの他、ブラウザ上での実行に対応
  3. Coffeescript, browserify などのプリプロセッサをサポート
インストール

npm を使用してインストールが可能です。(Node.jsが予めインストールされている前提です。)

npm install -g testem
設定ファイルの作成

testemの設定ファイル(testem.json)を作成します。

testem.ymlとすることもできますが、今回は、testem.json です。

{
  "before_tests":
    "grunt pre-spec"
  ,

  "framework": [
    "jasmine"
  ],

  "src_files": [
    "src/coffee/**/*.coffee",
    "spec/coffee/**/*.coffee"
  ],

  "serve_files": [
    "spec/js/**/*.js"
  ]
}
  • framework
  • src_files
  • serve_files
    • テスト実行時に使用するファイルを指定します。
    • 'spec/coffee/**/*.coffee' をコンパイルして、'spec/js/**/*.js' を生成し、js ファイルをテストで使用します。
  • before_tests
    • イベントハンドラのひとつです。
    • 記述しておくと、そのタイミングでコマンドが実行されます。
    • テスト実行前に、coffeescript→js のコンパイルを実行する必要があるため、その grunt タスクを指定しています。
    • プリプロセッサ対応の実態は、ここに適切にコマンドを指定することでできます、ということ。
テストの実行

テストコードと対象のコードを用意して、 testem コマンドを実行すると、はじめはこんなメッセージが表示されます。

TEST'EM 'SCRIPTS!
Open the URL below in a browser to connect.
http://localhost:7357/

    Waiting for runners...

f:id:ichiko_revjune:20140305193131p:plain

表示されているURLにアクセスすると、そのリクエストでテストが実行されます。

同時に、コンソールにも結果が表示され、こんな画面になります。(テストが1件の場合)

f:id:ichiko_revjune:20140305192837p:plain

ブラウザを開いた状態で、 src_files で指定しているファイルを編集し、保存すると、テストが再実行されます。 (ブラウザもリロードされます。)

テストコードのファイルを追加すると、そのファイルも実行してくれるようになります。

※画像の背景に映りこんでいるのは、この記事の編集画面です。(/ . \);

MVVMフレームワーク vue.js を使ってみた

MVVMパターンは、馴染がないなと思っていたのですが、調べるとMicrosoftの.NET(WPF)が近いことがわかりました。 なんだ、触れたことあるじゃん、って。

参考

そんな、MVVMパターンjavascript ライブラリ vue.js を使ってみました。

vue.jsのサイト のトップを見ると、"MVVM Made SImple" とあります。 たしかに、UIまわりをシンプルに書けました。

vue.js のさわりは、本家サイトもいいですし、私は、軽量でパワフルなデータバインディングMVVM, vue.jsで遊んでみた - mizchi's blog を参考にさせてもらいました。

MVVMパターン

MVVMパターンの特徴として以下の2点があります。図にまとめてみました。

  • View と ViewModel 間でデータバインディングが行われる
  • View 上のイベント処理は、ViewModel のコマンドによって表現、実行される

f:id:ichiko_revjune:20140225153300p:plain

vue.js では、View層とViewModel層を関連付けて管理するための、Vue クラスが提供されます。

View層に関しては、テンプレートを記述することで、バインディングの指定や、配列の繰り返しなどを記述することができます。これはなかなか便利。

フレームワークの強制力が弱いので、かなり使い易いライブラリだと思いました。 まだ、ほんのさわり程度なので、いろいろできそうなコマンドFilterまわりなど、試していきたいです。

経過時間を記録するアプリ

時間を記録して、直近の記録からの経過時間を表示するiPhoneアプリを作りました。

MMOなどで、一度取得すると一定時間取得できなくなるアイテムがあったりしまして、その把握を簡単にするのが目的です。

開発中にひっかかったとろなどを記録します。

完成図

アプリを起動すると、直近の記録と経過時間が表示されます。

画面1f:id:ichiko_revjune:20140107103628p:plain

「履歴を見る」、から一覧で参照することができ、削除もできます。

画面2f:id:ichiko_revjune:20140107103632p:plain

画面3f:id:ichiko_revjune:20140107103636p:plain

TableView with Storyboard

UIをStoryboardを使用して作成することにしたのですが、UIが反映されないという問題にハマりました。

  1. XCodeEmpty Applicationテンプレートから作成する。
  2. UIをStoryboardで作成することにしたので、プロジェクトに新規のStoryboardを追加する。
  3. TableViewを使用するので、Object libraryから、Table View Controllerを貼り付ける。
  4. TableViewの挙動を書き換えるため、UITableViewControllerを継承したクラスを作成し、プロパティCustom Classに指定する。
  5. そのまま実行してみると、画面は真っ白のままです。
  6. AppDelegate.didFinishLaunchingWithOptionsを変更して、Storyboardで指定した、Custom ClassからUIViewを作成して、windowに追加する。(←ここで間違った!
  7. 空っぽのTableViewが表示されました。(←ここで騙された!
  8. TableViewの項目に、セルの番号(indexPath.row)を設定するように変更する。
  9. 空っぽのTableViewが表示されました。おかしいぞ…

プロジェクトテンプレートをSingle View Applicationとすれば、テンプレートに含まれるStoryboardを使用するようにプロジェクトが設定されています。

Storyboardを使用するようにするために、以下のようにしました。

  1. AppDelegate.didFinishLaunchingWithOptionsを変更して、以下の内容のみとする。
    return YES;
  2. Project Navigatorのルートを選択して、Targets > [Application Name] > General > Deployment Info > MainInterface に、作成したStoryboardを指定する。

Core Data

日時の記録は、Core Dataを使用して保存することにしました。

Core Dataの基本的な使い方を調べて、CRUDを実装しようとしました。 このときの、Core Dataの使い方はこんなイメージです。

f:id:ichiko_revjune:20140107110914p:plain

Core Dataのしくみ、使い方は、以下のページを参考にしました。

その後、TableViewとCore Dataの連携はもっと簡単になるよ、ってことでキーワード NSFetchedResultController で調べました。

参考にしたのは、以下のページです。

NSFetchedResultController と NSFetchedResultsControllerDelegate を使うと、一覧上での削除はずいぶんと簡単になりそうです。差分だけ更新が可能になるので。 画面を表示するたびに、データを取得しなおして、再表示という手間はなくなりました。

ただし、完全になくなったというわけではなく、画面1では、viewDidAppearにて、画面の更新をしています。一覧で最新のレコード(画面1で表示しているデータ)が削除された場合に、画面が戻ってきてから、表示更新までにラグが発生することがあるためです。

Core Dataの使い方は、こうなります。 NSFetchedResultControllerは、各画面ごとに取得・保持しています。

f:id:ichiko_revjune:20140107112115p:plain

ソースコード

コードはgithub.comで公開しています。 実際のコードを確認する方はこちらからどうぞ。

ichiko/SingleTimeLogger

はじめまして

明けましておめでとうございます。 年も改まり、開発関連のブログを別立てすることにしました。

もともとは、水無月の余韻 ブログです。 今後は、開発関連の記事は、こちらのブログに記載していきます。

開発関連といっても、日々のプログラミングなどで調べたこと、成果物を勝手に解説、といった内容を予定しています。 備忘録的な性質が強いかもしれませんが、誰かの役に立つことがあれば幸いです。