Monthly Archives: 3月 2017

2017-03-29

RedisとHBaseを試してみよう

こんにちは。GMOアドマーケティングのS.Kと申します。

皆様の職場ではどのタイプのNoSQLデータベースを使っていますか?

今回は私が日々の開発で使用しているHBaseと、
以前開発で使用していたRedisについて紹介させていただきます。
環境

 

I. Redis編

1. Redis

Redisはメモリー上で動作するkey-valueストア(KVS)形式のNoSQLです。

2. Redisのインストール

3. jedisの追加

JavaでRedisサーバにアクセスするためにはjedisというjarファイルのJavaライブラリーが必要です。
jedisをダウンロードしてjarファイルをライブラリーに追加してください。

Eclipseプロジェクトを選択して「Properties」>「Java Build Path」>「Add JARs」>「jedis-2.X.X.jar」>「OK」を選択します。

4. Java + Redis でhashタイプのデータを操作する

 

II. HBase編

1. HBase

HBaseはHDFS上に構築された列指向分散データベースで、大量のデータに対してスケール可能です。

2. インストール

3. pom.xmlの設定

pom.xmlのdependencyにHBaseのバージョン情報を追加する必要があります。

4. Java + HBase でデータを操作する

 

他のKVSデータベース情報は下記のページをご覧ください。
KVS vs RDB

 

まとめ

今回はRedisとHBaseの接続方法について紹介しました。
Redis・HBase共に簡単に導入できるので、
NoSQLを始める切っ掛けとして、ぜひ試していただければと思います。

今回の記事ではそれぞれの特徴や性能については紹介しませんでしたが、
実際にシステムに導入する際は以下の比較記事を参考にしてみて下さい。

System Properties Comparison HBase vs. Redis

2017-03-16

AMP HTMLプロジェクトをローカルで編集するまで

挨拶

こんにちは!エンジニアのH.Yです。

結構前からAMP(Accelerated Mobile Pages)を導入するページを多く見かけるようになってきましたね。

朝日新聞デジタルさんや毎日新聞さん等々…

弊社Yomerumoでも導入しております。ぜひご覧ください。

さて、AMPにはamp-adという広告描画の仕組みが提供されていますが、これは弊社GMOSSPも昨年4月から対応しております。

今回はこのamp-adにGMOSSPをどのようにして導入したのか?を書いていこうと思います。

前提

  • CentOS6.x系

開発環境準備

環境構築方法はこちらに書かれているのですが、私がどうしたか、を書きます。

ここまで終わったら

http://localhost:8000/examples.build/ads.amp.max.html

にアクセスすれば各社のテスト広告が確認できます。
Ctrl+Cで抜けられます。

開発

https://github.com/ampproject/amphtml/pull/2814

弊社は上記のようなリリースをを行っています。
JS等に変更があれば
gulp build
gulp serve
し直せば変更後の物が確認できるので、思ったよりもカジュアルに開発できます。

実際のリリースは自分のGitHubアカウントにプロジェクトをForkしたものをcloneして編集して
そこにPUSHを行った後本家AMPHTMLにプルリクエストを出しております。

終わりに

いかがでしたか?
みなさんも良ければよく知られたAMPをローカル環境で動かしてみてください!

Category: AMP

2017-03-13

Mockでユニットテストを簡単にしよう!

はじめに

こんにちは。NIKKOエンジニアのS.TKです。

皆さん、テストはしていますか?最近の開発手法であれば、ほぼ確実にテストが考慮されているので嫌でもしていますよね。ただ、テストって実は結構難しかったりします。特にテストコードを書くとなると、プロダクトコードの設計によってはかなり苦労させられます。

そこで、今回はユニットテスト(単体テスト)に焦点を当て、テストコードを楽に書くためにMock(モック)を利用する方法をご紹介します。私はGMO MARS DMPの開発・運用を担当していますが、今回ご紹介する内容は普段の業務で実践している内容になります。
言語はJavaで、テストフレームワークはJUnitを使うことにします。

ユニットテストを書こう

まず最初に、ユニットテストを書くことの意義について再確認してみたいと思います。今更感がすごいですが、ちょっとだけお付き合いください。

一番期待されるのは、やはり品質の向上でしょうか。誤りを早い段階で発見できますし、既存機能を変更する際に誤りを防止することができます。また、プロダクトコードをリファクタリングする際には、ユニットテストが誤り混入の防波堤の役割を果たしますので、機能面だけでなくコード面の品質も向上させることができます。

他にも、テストコードの書き方を工夫するとプロダクトコードの使い方を明示することができます。つまり、テスト対象クラスの使い方サンプルとしてテストコードを利用することができます。テストコードは実際に動作可能なので、ドキュメントよりも信頼性が高いはずです(テストコードが「古い」場合はテストがfailする可能性が高いため)。

さらに進めて考えると、設計の品質向上にも貢献します。ユニットテストの容易さで設計のマズさがある程度わかるためです。これについては、本稿で実感頂けるかと思います。

ユニットテストでよく発生する問題

さて、ユニットテストの大切さを再確認したところで、実際にテストコードを書いてみると……これが案外難しいものです。テスト対象クラスに外部リソースにアクセスする処理や実行環境に依存する処理があり、自分のローカル環境でテストが動かせない……というのはありがちです。

たとえば、下記のようなidからユーザ名を取得するような簡単なクラスで考えてみます。ユーザの情報はDBに格納されているため、DBに接続してデータを取得する処理が必要になります。

このクラスのユニットテストを実行することを考えると、自分のローカル環境にDBをつくるかDB接続の設定を行う必要があります。また、実際にユニットテストを実行させると、DBとの接続やテストデータ投入でかなりの時間がかかってしまいます。

Mockを使おう

このような場合、Mockを使うと上手く解決ができます。

Mockとは、簡単に言うとクラスの動作をシミュレートするためのオブジェクトです。テスト対象クラスが呼び出している(=依存している)クラスをMockで差し替え、Mockの動作内容を定義することで、望むテスト条件を容易に作ることができます。

Mockを扱うライブラリは各言語に色々存在していますが、Java言語で有名所ですとMockitoというライブラリがあります。Mockitoは1系と2系がありますが、今回は1系を扱います。

実際、Mockitoはどんな感じで使うのかというと、下記のようになります。

プロダクトコードがこちら。

テストコードがこちら。

テストコードの8行目がMockオブジェクトを作成している箇所で、11行目でそのMockの動作を規定しています。この例ですと、「isSomething()メソッドが引数100で呼ばれた時にtrueを返す」ことを定めています。そして、このテストケースではisSomething()がtrueを返してきた場合にテスト対象メソッドが正しく-1を返していることをテストしています。

このように、Mockを使うとテスト対象クラスが依存しているクラスの動作をシミュレートし、テストケースの事前条件を容易に整えることが可能となります。

Mockを実際に使ってみる

では、前述のSomeServiceのテストコードをMockを使って書いてみます。

早速、依存しているクラスをMockに差し替えてやりましょう!……依存クラスがないですね。これではMockに差し替えられません。

このようなケースは特にレガシーコードではよくあることです。以下で順を追ってプロダクトコードを修正し、Mockで差し替えられる設計にしましょう。

責務外の処理は別クラスに移譲しよう

まずDBにアクセスしている部分はSomeServiceの責務とは外れているので、別クラスに移譲してしまいましょう。たとえば、UserMapperクラスとでもしてしまいましょう。

実際に修正すると下記のようになります。

これで面倒なDBアクセス部分は別クラスになりましたので、簡単にテストコードが書け……ませんね。これだとUserMapperをインスタンス化した際に結局DBアクセスが発生してしまいますし、Mockで差し替えることもできません。

依存するオブジェクトは外部から注入できるようにしよう

では次に、UserMapperオブジェクトをインスタンス化する部分をクラス外に持って行ってしまいましょう。つまり、SomeServiceを使う側がUserMapperをインスタンス化し、それをSomeServiceに「注入」してあげることにします。注入方法はコンストラクタで良いでしょう。

やっとできました。これでDBアクセス部分をMockで差し替えることができます。

Mockでユニットテストを簡単に書こう

修正後のSomeServiceで、Mockを使って実際にテストコードを書いてみます。この場合はUserMapperが依存しているクラスなので、このクラスのMockを注入してあげればOKですね。具体的なテストコードは下記のようになります。

DBアクセスを担当するUserMapperクラスをMockにしているため、DB接続ができない環境でも問題なく動作します。これで自分のローカル環境でもガンガンテストを動かせますね!

このように、Mockを使ってあげると、余計な処理を省いて本当にテストしたい内容だけをテストコードとして書くことができます。

ユニットテストと設計の関係

前述のような依存するインスタンスを外部から注入する設計は、一般にDI(Dependency Injection)として知られています。DIコンテナも多数存在しており、有名どころではSpringなどがあげられます。
DIできるように設計しておくと、ユニットテストでMockを容易に注入できるため、テストコードがとても書きやすくなります。逆に、テストコードが書きにくいと感じたら、プロダクトコードの設計がマズイ可能性が高いです。ユニットテストによって設計の品質が向上するというのはまさにこの点を指しています。

おわりに

本稿では、ユニットテストを簡単にするためにMockを使う方法を紹介してきました。途中から設計の話も混ざってきましたが、これはユニットテストがある意味では設計作業でもあるためです。ユニットテストの容易さとクラスの使い勝手の良さは大抵の場合イコールになるものです。
この例ではJava言語を使っていますが、大抵の言語でこの考え方は通用します。皆さんも、プロダクトコードを書く時に「このコードのテストはどうやって書けば良いだろうか」という点を意識してみるのは如何でしょうか。

2017-03-09

Dockerを試してみた

はじめまして。GMOインサイトのS.Oです。
昨年の10月ぐらいから土日の休み中に、Dockerを使ってみました。


目的

【個人的な場合】

  • パソコンとインターネットがあればどこでも開発環境を構築できるようにしたい。
    ※ パソコンに依存しない開発環境を整えたい
  • 稼働中のアプリを別環境下でも正常に稼働するかどうかのテストを容易したい
    例) PHP5.6のアプリをPHP7でテストしたいなど…
  • いろいろなミドルウェアを気軽に触ってみたい

【会社で使う場合】

  • 関係するメンバーに、同じ開発環境を提供できるようにしたい。

構成イメージ

完成図

パソコン内部は、以下のような構成になります。

PC構成


 環境条件


仮想マシンの選択

いろいろなやり方があると思いますが、簡単な方法として以下の2通りから選択しました。

  1. Virtualbox + Vagrant
  2. Docker Toolbox

私の環境(Mac Book Air)では、Virtualboxが既に稼働していたので①の方法で進めます
( 仮想環境に慣れていない方は、②の方法を選択した方がいいかも… )


環境構築 – 仮想マシンを準備する

仮想化ソフトとコードを扱うためGitをインストールする

サーバ構築は、Vagrant Cloudからイメージをダウンロードして使う。
※ すでにDockerとdocker-composeはインストール済み

[構成イメージ ]
vagrant

[ファイル構成(ホストOS)]

下記のGitHubに必要なファイルや手順をまとめました。
※ GitHub: reflet/vagrant-centos-7.2
     https://github.com/reflet/vagrant-centos-7.2

  1. Vagrantを起動して、SSH接続する

コンテナ作成 – Apache

Dockerfileにてコンテナを作成します
( サーバの作成方法です。 サーバ環境を構築する場合は、この作業は必要なし 

[構成イメージ ]
docker
[ファイル構成(仮想マシン)]

作成したDockerfileや使い方の手順については、下記のGitHubにまとめました(細かい話は省略)。
※ GitHub: reflet/docker-debian-httpd
    https://github.com/reflet/docker-debian-httpd

  1. コンテナのイメージを作成する
  2. コンテナを起動し、接続する
  3. Dockerfile調整
    ※ Dockerfileを修正し、2と3を繰り返し、完成後、 githubへpush。
  4. tagを発行し、Docker-hubへイメージをpushする

以上


コンテナ作成 – PHP7

Dockerfileにてコンテナを作成します
( サーバの作成方法です。 サーバ環境を構築する場合は、この作業は必要なし )

[構成イメージ ]
docker

[ファイル構成(仮想マシン)]

作成したDockerfileや使い方の手順については、下記のGitHubにまとめました(細かい話は省略)。

※ GitHub: reflet/docker-debian-php
    https://github.com/reflet/docker-debian-php

  1. コンテナのイメージを作成する
  2. コンテナの起動し、接続する (自動削除)
  3. Dockerfile調整
    ※ Dockerfileを修正し、2と3を繰り返し、完成後、 githubへpush。
  4. tagを発行し、Docker-hubへイメージをpushする

以上


サーバを構築する

上記で作成したApacheとPHPのコンテナを使ってサーバを構成する。
サーバの構成はコマンド1つで自動で行えるようにdocker-composeを利用します。

[構成イメージ ]
docker-compose

[ファイル構成]

サーバ構築に使うファイルについては、下記のGitHubにまとめました(細かい話は省略)。
※ GitHub: reflet/server-debian-httpd-php7
    https://github.com/reflet/server-debian-httpd-php7

  1. ファイルを配置する
    githubから必要なファイルとフォルダを取得します
  2. 起動方法について( RUN )
    下記のコマンドにてコンテナを起動します (port 80 is available)
  3. テストについて( TEST )
    下記コマンドにて、結果が返ってきたら問題ありません。
  4. 各コンテナへ接続( EXEC )
    コンテナ内に入って操作したい場合は、下記コマンドにて接続ください。
    ※ 操作を終了する場合は、「exit」でコンソールを抜けられます。

以上


アプリケーションを配置してみる

PHPのフレームワーク(lumen)を設置してみます。
[ファイル構成]

Lumenのコードについては、下記のGitHubにまとめました(細かい話は省略)。
※ GitHub: reflet/app-lumen
    https://github.com/reflet/app-lumen

  1. コードを配置する
    GitHubからコードをクローンすることで配置します。
  2. Lumen(本体)をインストールする
    composerを使ってLumen本体と各種ライブラリを配置します。

以上


まとめ

長々と作成手順まで書いてしまいましたが、
実際サーバを構築するする作業としては、下記の作業を1回行うだけとなります。

  1. Dockerが使える環境を用意する
  2. サーバを構築する

あとは、出来上がったサーバ内にどのようなアプリを配置するかということだけです。

今後は、ApacheとPHP7だけでなく、nginx, mysql, php5.6, redis, td-agent, glusterfsなども
作っていきたいと思います。