2012年7月6日金曜日

性能評価するときに利用しているもののメモ

はじめに
複数のサーバを利用しての性能評価をよく行うのですが、複数のサーバでの性能評価だと、各サーバの端末を操作して各サーバで色々なログとってきたり設定値変えてまた実験したり…となかなか骨の折れる作業になります。
そのため、一度自分で簡単に実験をしてみたあとは自動化スクリプトを書いて放置!しているのですが、そのときよく利用するものを今後の自分のためにもメモしてみます。

パスワード認証なしのssh接続
複数のサーバ間でログのやりとり等していると、毎回パスワード入力するのがかなり面倒です。後述のsshでのコマンド実行のときにも便利ですし、実験に利用するサーバは基本的にパス無しsshにしちゃいます。
方法は簡単で、以下のとおり。

#接続元サーバにて、以下のコマンドを実行
$ ssh-keygen
$ cat id_rsa.pub >> authorized_key
#接続先サーバへ作成したid_rsaを持って行き、以下のコマンドを実行
$ eval `ssh-agent`
$ ssh-add id_rsa
ログアウト時にはeval `ssh-agent -k`を忘れずに!プロセスが残っちゃいます。
この方法では端末ごとに同じ処理を行う必要があり、さらに端末分だけssh-agentが乱立するという問題があります。気になる場合は、プロセスを使いまわすスクリプトを書くか利用するかしたほうがいいかもしれません。

sshでコマンド実行
sshってなんとなくログインするためのコマンドっていう印象がつよいんですが、ログイン先のサーバでコマンド実行もできるんですよね。前述のパスワード認証なしでのssh接続が可能になると、シェルスクリプトにsshでのコマンド実行命令を書き連ねるだけで自動化できて便利です。
方法は以下のとおり。
$ ssh USER@HOST_NAME "実行するコマンド"
sshって入力を待ってしまうので、バックグラウンドで動かしたい場合には以下の方法が必要になります。
$ ssh -n USER@HOST_NAME "COMMAND < /dev/null > /dev/null 2> /dev/null &"
色々調べてみたところ、-fオプションを付けてもできるのかな?今度やってみよう。
$ ssh -f USER@HOST_NAME "COMMAND"
expect
対話型のプログラムをログイン先サーバで自動で動かしたいとなると、sshのコマンド実行では微妙です。こういう場合はexpectを使います。
expectを使ったシェルスクリプトは以下のとおりです。
#!/bin/bash
 
# expectコマンドの前にしたい処理
 
expect -c "
set timeout -1
spawn ssh USER@HOST_NAME
expect \"Enter passphrase for key\"
send \"PASSWORD\n\"
expect \"Last login\"
send \"COMMAND\n\"
:
"
# expectコマンドの後にしたい処理

#!/usr/bin/expect
 
set timeout -1
spawn ssh USER@HOST_NAME
expect "Enter passphrase for key"
send "PASSWORD\n"
expect "Last login"
send "COMMAND\n"
interact
expectコマンドは、実行するコマンドをspawnの後に書き、その後のexpectに書かれている文字列の出力を待った後、sendに書かれている文字列を入力する形になります。 これで対話型プログラムの自動処理が可能になります。 また、最初のset timeoutはタイムアウト時間を設定できます。-1で無限待ちします。 expectだけなら後者を、他の命令も必要であれば前者を利用するとよいです。

さいごに
私が性能実験を自動化する際に主に利用するものを挙げてみました。
シェルスクリプトを本などで体系的に勉強したことがまだないので、もっと便利な方法がありそうな気がします…。
何か見つけたら、追記します。

2012年6月27日水曜日

Mac OS XでCassandraを動かしてみた

はじめに
ちょっとCassandraを試してみたいなと思い、自宅のMac(OS X 10.7.3)にCassandraを入れてみました。
せっかくなので動作確認までをメモしておきます。

ダウンロードと設定
Cassandraはこちらからダウンロードします。
2012/6/27現在ではapache-cassandra-1.1.1-bin.tar.gzが最新版のようです。
ダウンロードしたものは適当なフォルダに展開します。
#以降、展開先フォルダを$CASSANDRA_DIRと表現します。

次に設定ですが、基本的にこちらに書いてあるとおりです。
まず、$CASSANDRA_DIR/conf/cassandra.yaml 中のdata_file_directories, commitlog_directory, saved_caches_directoryの項目を、存在するパスに書き換え、initial_tokenの項目に0を指定します。
次に、$CASSANDRA_DIR/conf/log4j-server.properties 中のlog4j.appender.R.Fileの項目も同様に存在するパスに書き換えます。

実行
Cassandraサーバの実行は以下で行えます。
./bin/cassandra -f
Cassandraクライアントの実行は、以下で行えます。
./bin/cassandra-cli -h [サーバアドレス] -p [ポート番号]

2012年6月22日金曜日

溜まっているGmailを一気に既読にするRubyスクリプト


未読メールって、すぐに溜まりません?
私はいくつかのGmailアカウントを使い分けているんですが、 特にサービス登録用のアカウントにメールが溜まって溜まって…。

で、ちょっと調べてみたのですが、IMAPメールの処理がRubyで簡単にできそうだったので、あまり経験ありませんがRubyで書いてみました。 

require 'net/imap'
require 'kconv'
 
def mail_check(account, password)
    imap = Net::IMAP.new('imap.gmail.com', 993, true)
    imap.login(account, password)
    imap.select(Net::IMAP.encode_utf7("INBOX"))
 
    ids = imap.search(["UNSEEN"])
    if ids.length > 0 then
        imap.fetch(ids, ["ENVELOPE"]).each {|mail|
        if mail.attr["ENVELOPE"].subject.nil? then
            next
        else
            puts(mail.attr["ENVELOPE"].subject.toutf8)
                imap.store(ids, '+FLAGS', [:Seen] )
        end
        }
    end
end
 
mail_check("ユーザ名", "パスワード")

未読(UNSEEN)メールを読み込み、既読を示すSEENフラグを立てるだけのスクリプトになります。
進行状況が分からないとやきもきしてしまうので、処理したメールのタイトルも表示するようにしました。
#ちなみに、imap.store(ids, '-FLAGS', [:Seen] )とすると、既読メールを未読に変更することができます。
#既読メールが一気に未読になっていくのは、なかなか見ない光景なので楽しいです。

かなり溜め込んでいたのでそこそこ時間がかかっちゃったのですが、一気に既読になってすっきりしました。
意外と簡単にIMAPメールって操作できるんですねー。

2012年5月24日木曜日

CodecademyのJavaScriptコースを一通りやり終えたので、感想書いてみる

はじめに

Web上でプログラミングが学べるCodecademyに関して以前紹介記事を書きました
あの時から今まで少しずつやってきて、やっと現時点で公開されているJavaScriptのコース全てを完了しました。
せっかく一区切りがついたということで、感想など書いてみます。
ちなみに、開始時点でのJavaScriptの経験はほとんどない状態から始めました。

よいと感じた点
  1. Webサービスなので環境構築しなくても勉強できる
    環境構築しなくても良いのは、気軽で良いと思います。
    コーディングもプログラムの実行も一つのWebページで完結しているので
    エディタをどうするかとか、考えずにプログラミングのお勉強が開始できます。
    ※でも、ある程度慣れた人なら使い慣れた環境が使えないので
    ※不自由を感じたりするような気もします。一長一短でしょうか。
  2. 進捗状況やバッジがあってやる気に繋がる
    やっぱり進捗状況やバッジがあると、進める活力になります。

いまいちと感じた点
  1. 問題のクオリティにムラがある
    問題を作成している人がバラバラなので
    問題間のクオリティの差が激しい印象を受けました。
  2. カリキュラム構成が微妙と感じる
    問題の作り手がバラバラなので、前に見たことあるような問題がまた出てきたり、
    全体的な流れがいまいちだと感じました。
    やっぱり本のように系統だてられた内容で学ぶほうが、初心者には適していると思いました。
  3. 解答の通過条件がひどいものが存在する
    もうなおっているかもしれませんが、変数名が想定されているものでないと通らないという問題があって、さすがにQ&Aを覗かないとわかりませんでした。
    ただ、これも問題を作る側・採用する側の問題なのかなと思います。
    問題の不備で勉強時間を無駄に減らすこともないので、もしハマったらすぐにQ&Aを覗いてみるくらいでもいいと思います。
    ※すぐに解答をみるっていうのも、学習的にどうなんだという気もしますが。
まとめ
環境構築もいらず、気軽にはじめることができるため一見初心者向けにも見えるのですが、カリキュラム構成がきっちりしていないほか、解答通過条件が厳しいものも存在し、やっぱりプログラミングが初めてという方が学習するには難しいんじゃないかなと思いました。
他の言語を触ったことのある方で、JavaScriptの記法等学びたいという方が向いてるんじゃないでしょうか。
多少カリキュラム構成が気持ち悪くても終えることができると思います。

関連記事
 Codecademyを始めてみました

2012年4月24日火曜日

C++のテストフレームワーク Boost.Testを試してみた

はじめに 
これまでCppUnit, googletestとC++のテストフレームワークを試してきました。
今回はBoost.Testを試してみます。
実行環境は、Mac OS X(ver. 10.7.3), Boost(var. 1.49.0)です。

ダウンロードとインストール
Macユーザーなら、Macportsでインストールすることができます。
$ sudo port install jam
$ sudo port install boost
インストール後は、環境変数を設定しておきましょう。
Boostのインストールに関しては、こちらのサイトさんが大変参考になりました。

テストプログラムを書いてみる
今回もテスト対象のプログラムはFizzBuzz問題としました。 
//FizzBuzz.h
#include <string>
 
class FizzBuzz {
  public:
    std::string Print(int n);
};
//FizzBuzz.cpp
#include <sstream>
#include "FizzBuzz.h"
 
using namespace std;
 
string FizzBuzz::Print(int n) {
  ostringstream sout;
  if(n % 3 == 0) sout << "Fizz";
  if(n % 5 == 0) sout << "Buzz";
  if(n % 3 != 0 && n % 5 != 0) sout << n;
  return sout.str();
}
Boost.Testではテストプログラムは以下のように書くと良いみたいです。
//FizzBuzzTest.cpp

//Macの場合は以下の記載がが必要(後述)
#define BOOST_TEST_DYN_LINK 
//Main関数を用意する必要がなくなる
#define BOOST_TEST_MAIN 
//テスト名を定義する
#define BOOST_TEST_MODULE FizzBuzzTest 
#include <boost/test/unit_test.hpp>
#include "FizzBuzz.h"

//Fixture
struct FizzBuzzFixture {
    FizzBuzzFixture() {
        this->fb_ = new FizzBuzz();
    }
    ~FizzBuzzFixture() {
        delete this->fb_;
    }
    FizzBuzz* fb_;
};

//一連のテスト群にFixtureを適用する場合は下記のように書く
//第一引数がテスト群の名前、第二引数が使用するFixtureの名前
BOOST_FIXTURE_TEST_SUITE(FizzBuzz, FizzBuzzFixture)
 
BOOST_AUTO_TEST_CASE( testFizz )
{
    BOOST_CHECK_EQUAL( "Fizz", fb_->Print(3) );
}
 
BOOST_AUTO_TEST_CASE( testBuzz )
{
    BOOST_CHECK_EQUAL( "Buzz", fb_->Print(5) );
}
 
BOOST_AUTO_TEST_CASE( testFizzBuzz )
{
    BOOST_CHECK_EQUAL( "FizzBuzz", fb_->Print(15) );
}
 
BOOST_AUTO_TEST_CASE( testOther )
{
    BOOST_CHECK_EQUAL( "2", fb_->Print(2) );
}
BOOST_AUTO_TEST_SUITE_END();

Fixtureに関しては、上記のSuiteに適用する以外にも、
BOOST_GLOBAL_FIXTURE(fixure_name)
とすることで全体に適用できたり、
BOOST_FIXTURE_TEST_CASE( test_case_name, fixture_name )
{
    //test
}
とすることで、個別に適用することができるみたいです。
#詳しくはこちらを参照してください。
また、
#define BOOST_TEST_DYN_LINK
に関してですが、Macの場合、これを書かずにコンパイルしようとすると以下のようなエラーが出ます。
Undefined symbols for architecture x86_64:
  "_main", referenced from:
      start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Macは静的リンクがサポートされていないことが原因みたいです。
こちらを参考にさせて頂きました。

コンパイルは以下で行います。
$ g++ FizzBuzz.cpp FizzBuzzTest.cpp -o FizzBuzzTest -lboost_unit_test_framework

テストプログラムを実行してみる
まず、普通に実行してみると以下のような出力となります。
$ ./FizzBuzzTest
Running 4 test cases...

*** No errors detected

うーん、シンプルすぎる…と思ったのですが、 Boost.Testの場合色々オプションを指定することができるみたいです。
$ ./FizzBuzzTest --report_level=detailed --show_progress=yes --build_info=yes

0% 10 20 30 40 50 60 70 80 90 100%
|----|----|----|----|----|----|----|----|----|----|
Running 4 test cases...
Platform: Mac OS
Compiler: GNU C++ version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
STL : GNU libstdc++ version 20070719
Boost : 1.49.0
***************************************************

Test suite "FizzBuzzTest" passed with:
4 assertions out of 4 passed
4 test cases out of 4 passed

Test suite "FizzBuzz" passed with:
4 assertions out of 4 passed
4 test cases out of 4 passed

Test case "testFizz" passed with:
1 assertion out of 1 passed

Test case "testBuzz" passed with:
1 assertion out of 1 passed

Test case "testFizzBuzz" passed with:
1 assertion out of 1 passed

Test case "testOther" passed with:
1 assertion out of 1 passed

前回googletestに関する記事を書きましたが、 テストの記述量も記載方法もBoost.Testとgoogletestではそこまで大きくは異なってない印象を受けるのでどちらがいいかは各々のお好みでよさそうです。
私は出力がgoogletestの方が好みなので、googletestを利用しています。

相変わらず大した内容でもありませんが、今回のソースコードはこちらにまとめましたので、参考にどうぞ。

2012年4月5日木曜日

リファクタリング―プログラムの体質改善テクニック を読んでみました

数カ月前書いた自分のコード、全く意味がわからない…。
ちょっとした機能を追加したいだけなのに、乱雑に書かれたコードを読み返すのに時間がかかる。
やっとのことでコードを読み解いてみれば、改変が必要な箇所が散乱してる…。

ソフトウェア開発に携わったことのある人なら、こういう経験をしたこともあるのではないでしょうか?かくいう私も、過去に自分が書いたコードによく苦しめられている一人です。そういった方々におすすめなのが、こちらの本。

リファクタリング―プログラムの体質改善テクニック (Object Technology Series)
マーチン ファウラー
ピアソンエデュケーション
売り上げランキング: 6279

私はかれこれ、プログラミングを始めてから9年ほど経過しているのですが、もっと早く読んでいればよかった!の一言につきます。

リファクタリングとは、プログラム振る舞いを変えずに、プログラムを可読性や拡張性が向上するように整理することです(リファクタリングに関する詳しい話はこちらをご参照ください)。この本には、リファクタリングの意義や方法、そして各種ケースに応じたリファクタリング手順が記されています。

プログラムを整理する必要があることは、きっとリファクタリングという言葉を知らない方でも認識しているんじゃないかと思います。でも、実際にリファクタリングするとなると工数もかかるし、新たにバグを生み出すかもしれない。そんな心配事に対して、リファクタリングは(もちろん例外はあるのでしょうが、)プログラムへの投資だということ、そしてテストコードを用意した上で少しずつ変更を施すことで、バグを生み出さずにリファクタリング可能だということを、この本は教えてくれます。

ソフトウェア開発に関わる全ての方々にお勧めします。コードは全てJavaで書かれているので、オブジェクト指向の知識があると、なお楽しめるかと思います。

それにしても、この本を読んだあとに書いたプログラムは、なんだかいつもより綺麗に見える!…気がします。リファクタリングの上達には、一にも二にも経験なのでしょうが、この本を読んだだけで、なんとなく一気に上達した気分になれるのが不思議です。

2012年3月27日火曜日

C++のテストフレームワーク googletestを試してみた

はじめに
前回の記事ではテスト環境を構築するため、C++用テストフレームワークCppUnitを試しました。今回は、こちらもC++用テストフレームワークとして有名なgoogletestを試してみます。

googletestを使う準備をする
準備は以下のコマンドから。
cmakeが必要なので、あらかじめ入れておく必要があります。


$ svn checkout http://googletest.googlecode.com/svn/trunk/ googletest
$ cd googletest
$ mkdir mybuild
$ cd mybuild/
$ cmake ..
$ make
一連のコマンドで、libgtest.a, libgtest_main.aが出来上がります。
  
テストプログラムを書いてみる
CppUnitとの比較のため、今回もテスト対象のプログラムはFizzBuzz問題としました。
//FizzBuzz.h
#include <string>
 
class FizzBuzz {
  public:
    std::string Print(int n);
};
//FizzBuzz.cpp
#include <sstream>
#include "FizzBuzz.h"
 
using namespace std;
 
string FizzBuzz::Print(int n) {
  ostringstream sout;
  if(n % 3 == 0) sout << "Fizz";
  if(n % 5 == 0) sout << "Buzz";
  if(n % 3 != 0 && n % 5 != 0) sout << n;
  return sout.str();
}

次にテストプログラムを書きます。
googletestの場合には、出来上がったlibgtest_main.aを利用することで、Main関数を作成しなくても良いみたいです。
//FizzBuzzTest.cpp
#include "FizzBuzz.h"
#include "gtest/gtest.h"
 
class FizzBuzzTest : public ::testing::Test {
 protected:
 
  FizzBuzzTest() {
  }
 
  virtual ~FizzBuzzTest() {
  }
 
  virtual void SetUp() {
    this->fb_ = new FizzBuzz();
  }
 
  virtual void TearDown() {
    delete this->fb_;
  }
 
  FizzBuzz* fb_;
};
 
TEST_F(FizzBuzzTest, testFizz) {
  EXPECT_EQ("Fizz", fb_->Print(3));
}
 
TEST_F(FizzBuzzTest, testBuzz) {
  EXPECT_EQ("Buzz", fb_->Print(5));
}
 
TEST_F(FizzBuzzTest, testFizzBuzz) {
  EXPECT_EQ("FizzBuzz", fb_->Print(15));
}
 
TEST_F(FizzBuzzTest, testOther) {
  EXPECT_EQ("2", fb_->Print(2));
}

コンストラクタとデストラクタ、SetUpとTearDownは、テストケースを実行する前後の処理を定義する関数です。コンストラクタ→SetUp→テスト関数→TearDown→デストラクタの順に呼び出されます。使い分けとしては、例外処理を扱う場合はSetUp/TearDownを使うべきとのこと(詳細はこちら)。
前回の記事と同様に、3を引数としたときには"Fizz"を、5を引数にしたときには"Buzz"を、15を引数にしたときには "FizzBuzz"を、2を"2"を出力することを確認する4つのテストケースを作成しました。

$ g++ -I{$GOOGLE_TEST_DIR}/include FizzBuzz.cpp FizzBuzzTest.cpp {$GOOGLE_TEST_DIR}/mybuild/libgtest.a {$GOOGLE_TEST_DIR}/mybuild/libgtest_main.a -o FizzBuzzTest
$ ./FizzBuzzTest
Running main() from gtest_main.cc

[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from FizzBuzzTest
[ RUN      ] FizzBuzzTest.testFizz
[       OK ] FizzBuzzTest.testFizz (0 ms)
[ RUN      ] FizzBuzzTest.testBuzz
[       OK ] FizzBuzzTest.testBuzz (0 ms)
[ RUN      ] FizzBuzzTest.testFizzBuzz
[       OK ] FizzBuzzTest.testFizzBuzz (0 ms)
[ RUN      ] FizzBuzzTest.testOther
[       OK ] FizzBuzzTest.testOther (0 ms)
[----------] 4 tests from FizzBuzzTest (0 ms total)

[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (0 ms total)
[  PASSED  ] 4 tests.

できました!
ここでは表現できていないのですが、実際にはテストが通れば緑文字、そうでなければ赤文字でコンソール上に結果が出ます。

相変わらず大した内容でもありませんが、今回のソースコードはこちらにまとめましたので、参考にどうぞ。 

CppUnitとの比較
ちょっと試しただけなので比較するほど使いこめてはいないのですが、
  • googletestの方が記述量が少ない
  • googletestのほうがアサーションが豊富
    CppUnitが10個程度なのに比べてgoogletestは40個以上?
    (数えてみたのですが多かったので途中で断念しました。)
  • 成功で緑、失敗で赤表示が嬉しい
と感じたので、この2つの中で選ぶのなら、個人的にはgoogletestをお勧めします。  

さいごに
今回参考にしたサイトは以下です。
http://d.hatena.ne.jp/snaka72/20110720
http://opencv.jp/googletestdocs/index.html

2012年3月24日土曜日

C++のテストフレームワーク CppUnitを試してみた

はじめに
前回の記事でアジャイルサムライの感想を書きました。今回は少しでも読んだ内容を活かすため、テスト駆動開発ができるよう、テスト環境を構築してみることにします。
私はC++を主に使っているので、C++のテストフレームワークを色々探してみました。以下が見つけたC++用テストフレームワークの一例です。
色々探した中でよく名前が挙がっていたのが、CppUnit, googletest, Boost.Testあたりでした。今回はCppUnitを利用してみます。

ダウンロードとインストール
http://sourceforge.net/projects/cppunit/から、cppunit-1.12.1.tar.gzをダウンロードして、解凍&インストール。
$ tar zxvf cppunit-1.12.1.tar.gz
$ cd cppunit-1.12.1
$ ./configure
$ make
$ sudo make install

テストプログラムを書いてみる
テストプログラムを書くにあたって、テスト対象のプログラムが必要です。
今回は適当に、FizzBuzz問題のプログラムを書いてみました。
入力した数字によって対応した文字列を返すPrint関数を持つ、FizzBuzzクラスを作りました。

//FizzBuzz.h
#include <string>
 
class FizzBuzz {
  public:
    std::string Print(int n);
};
//FizzBuzz.cpp
#include <sstream>
#include "FizzBuzz.h"
 
using namespace std;
 
string FizzBuzz::Print(int n) {
  ostringstream sout;
  if(n % 3 == 0) sout << "Fizz";
  if(n % 5 == 0) sout << "Buzz";
  if(n % 3 != 0 && n % 5 != 0) sout << n;
  return sout.str();
}

まず、テストプログラムのMain関数を用意します。
Main関数はテンプレなので、基本的には改変する必要がありません。

//TestMain.cpp
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/TestRunner.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/CompilerOutputter.h>
 
using namespace CPPUNIT_NS;
 
int main(int argc, char **argv) {
  /* テストコントローラの生成 */
  TestResult controller;
  TestResultCollector result;
  controller.addListener(&result);
 
  BriefTestProgressListener progress;
  controller.addListener(&progress);
 
  /* テストを追加して、テストの実行 */
  TestRunner runner;
  runner.addTest(TestFactoryRegistry::getRegistry().makeTest());
  runner.run(controller);
 
  CompilerOutputter outputter(&result, stdCOut());
  outputter.write();
 
  return result.wasSuccessful() ? 0 : 1;
} 
次に、テストクラスを用意します。
//FizzBuzzTest.cpp
#include "FizzBuzz.h"
#include <cppunit/extensions/HelperMacros.h>
 
using namespace CPPUNIT_NS;
 
class FizzBuzzTest : public TestFixture {
  CPPUNIT_TEST_SUITE( FizzBuzzTest );
  
  /* ここから、テストケースを設定 */
  CPPUNIT_TEST( testFizz );
  CPPUNIT_TEST( testBuzz );
  CPPUNIT_TEST( testFizzBuzz );
  CPPUNIT_TEST( testOther );
  /* ここまで */
  
  CPPUNIT_TEST_SUITE_END();
 
  FizzBuzz* fb_;
  void testFizz();
  void testBuzz();
  void testFizzBuzz();
  void testOther();
 
public:
  void setUp() {
    this->fb_ = new FizzBuzz();
  }
  void tearDown() {
    delete this->fb_;
  }
};
 
/* ここから、テストケースを記述 */
void FizzBuzzTest::testFizz()
{
    std::string s = "Fizz";
    CPPUNIT_ASSERT_EQUAL(s, fb_->Print(3));
}
 
void FizzBuzzTest::testBuzz()
{
    std::string s = "Buzz";
    CPPUNIT_ASSERT_EQUAL(s, fb_->Print(5));
}
 
void FizzBuzzTest::testFizzBuzz()
{
    std::string s = "FizzBuzz";
    CPPUNIT_ASSERT_EQUAL(s, fb_->Print(15));
}
 
void FizzBuzzTest::testOther()
{
    std::string s = "2";
    CPPUNIT_ASSERT_EQUAL(s, fb_->Print(2));
}
/* ここまで、テストケースの記述 */
 
CPPUNIT_TEST_SUITE_REGISTRATION(FizzBuzzTest);
テストする関数を定義して、その関数をテストケースとして設定していくだけです。また、setUPとtearDownは、テストケースを実行する前後の処理を定義する関数です。このため、各テストケースは影響しあいません。
今回のテストでは、3を引数としたときには"Fizz"を、5を引数にしたときには"Buzz"を、15を引数にしたときには "FizzBuzz"を、2を"2"を出力することを確認する4つのテストケースを作成しました。

$ g++ TestMain.cpp FizzBuzzTest.cpp FizzBuzz.cpp -lcppunit -o FizzBuzzTest
$ ./FizzBuzzTest
FizzBuzzTest::testFizz : OK
FizzBuzzTest::testBuzz : OK
FizzBuzzTest::testFizzBuzz : OK
FizzBuzzTest::testOther : OK
OK (4)
できました!
 大した内容でもありませんが、今回のソースコードはこちらにまとめましたので、参考にどうぞ。 

さいごに

参考にしたサイトは以下です。
http://www.atmarkit.co.jp/fdotnet/cpptest/cpptest02/cpptest02_01.html
http://d.hatena.ne.jp/echizen_tm/20120127/1327675864 

関連記事
C++のテストフレームワーク googletestを試してみた

2012年3月16日金曜日

アジャイルサムライ-達人開発者への道- を読んでみました

仕事がIT関係の研究なので、開発するとしても一人でプロトタイプを作ったりかデモを作ったりするだけなのですが、新人の頃、研修として開発現場に参加した経験があります。その開発現場では、ウォーターフォール・モデルで開発していたんですが、何かと手戻りはするし、変更につぐ変更でテストした部分までやり直しになるしで、あまりいい思い出がありません。

そこで、もう少しいい開発手法はないのかしら?と思い、最近よく見かけるアジャイル開発を学んでみることにしました。読んだ本は以下です。技術書にしては気軽に読める内容で、ひと通り読むだけなら3時間程度で終えることができました。

アジャイルサムライ−達人開発者への道−
Jonathan Rasmusson
オーム社
売り上げランキング: 1060

こうした開発手法の本を読むのは初めてだったのですが、つまるところ、コミュニケーションに関する本なのかなという印象を持ちました。顧客との間、また開発チームとの間の齟齬をできるだけ減らしていくことに着目した開発手法なのかな、と。

作るものが美術作品や途中経過が目に見えてわかるし、完成作品の予想がつくけれど、ソフトウェアは意識してデモとかプロトタイプとか作っていかないと、最後まで予想がつきません。その中で、顧客や開発チーム間での齟齬を減らすためには、早い段階から動くものを作って見せることが解決策の一つである、というのがアジャイル開発の中核なのかなと感じました。そして、早い段階から動くものを作って見せるとなると、優先順位の高いものから開発していく必要はあるし、常にテストしておかないといけないし…ということで、
イテレーションや継続的インテグレーションといった方法が適しているのだと思います。

せっかく本を読んだので、アジャイル開発を試してみたいなと思ったのですが、仕事では実験用のプロトタイプを作ったりするくらいしか、ソフトウェア開発の機会がないのですよね。アジャイル開発を試すのはしばらく置いておいて、まずは手始めに、ひとりでもできるテスト駆動開発を読んでお勉強しようかなと思います。

2012年3月11日日曜日

Codecademyを始めてみました

Codacademyを毎日少しずつやっています。
Codacademyは、チュートリアル形式でJavascriptを学べるWebサービスです。
良いところとしては、進捗度が細かく表示されたり、進めていくとバッジがもらえたりするところかなと思います。
進める意欲が湧くので、なかなか長続きしない私でも続いています。

なかなか面白いサービスだと思います。
英語の勉強にもなりますし、興味がありましたら、ぜひ。

MacでGit

はてなブックマークを眺めていたら、こんな記事を発見。

○非エンジニア向けGitの使い方
http://blog.katty.in/758

お恥ずかしながら、Gitをこれまでバックアップ程度にしか使っていなかったな…と思い、自宅のMacでgit環境を構築してみることにしました。
また、DropBox(http://www.dropbox.com/)も使ってみたいなーと思っていたので、良い機会なのでDropboxを利用したGit環境の構築をしてみました。
以下が参考URLです。メモメモ。

○最速で Git を Mac にインストールして基本的なコマンドを使う方法
http://weble.org/2011/02/14/git-mac-install

○Mac OS 10.6 に MacPorts を入れる際に役に立ったサイト
http://weble.org/2010/06/17/macports

○gitとDropboxでお手軽・無料のSource Hostingを実現する
http://naoki.sato.name/lab/archives/38

Frameworkの追加

iPhoneアプリ開発中によく忘れるのでメモ。
Frameworkに追加するとき(Xcode4.2.1)は
TARGET → Build Phases → Link Binary With Libraries → +


MacからWindowsへリモートデスクトップ接続

メモ書き。

○ソフトウェアをダウンロード
http://www.microsoft.com/japan/mac/
↑のダウンロード->Remote Desktop

○Windowsで右クリック
control+shift+クリック

○シャットダウンしたいとき
control+option+fn+→キー