2012年2月26日日曜日

【JUnit】データベースを操作するテスト【試してみた?】



先日作ったByte配列に変換したりその逆にしたりするメソッドを利用して、データベース周りを実装する。

割りと、参考サイトを見ていると実装の方法は同じなので今回つまった部分とか。

Blob型で保存をするので、PupSQLiteなどのビューアを利用してもデータの内容の確認ができない。そこで、正しくデータが保存できているのか等を確認するために、JUnitを利用することにする。

Byte配列とは出るけど、内容確認は無理




1:データベース操作クラスのテスト
  • データを挿入するinput
  • 削除するdelete
  • 全てのデータを得るfindAll
  • 任意のデータを得るfindById

それぞれのテストの実装は次の通り。
public class PartyDaoTest extends AndroidTestCase {
 DbHelper helper;
 PartyDao dao;

 Party party; //保存対象のデータ

 public PartyDaoTest() {
 }

 protected void setUp() throws Exception {
  super.setUp();

  helper = new DbHelper(getContext());
  dao = new PartyDao(helper.getReadableDatabase());

  setData();
 }


 protected void tearDown() throws Exception {
  super.tearDown();
 }

 public void testInsert() {
  assertNotNull("Should be not null if save data", dao.insert(party));
 }

 public void testFindAll() {
  dao.insert(party);
  
  assertTrue("Should be returned bigger than one.",
    dao.findAll().size() > 1);
 }

 public void testDelete() {
  assertNotNull("Shoudl be not null", dao.delete((int) dao.insert(party)));
 }

 public void testFindById() {
  int id = (int) dao.insert(party);
  Party p = dao.findById(id);
  
  assertEquals(party.getDate(), p.getDate());
 }
}

問題なくテストも成功するから多分、大丈夫。

2:利用するActivityのテスト

保存対象のデータ'Party'を新たに作ったIntentにputし,setActiviyIntentでActivityに渡す。

testSaveData()で、実際のテストを行なっている。ちなみに、テスト対象のsaveData()メソッドは、データを保存すると返り値としてデータのIDを返すと言う物。
public class SelectMemberActivityTest extends
  ActivityInstrumentationTestCase2<テスト対象のActivity> {

 Party party; //保存対象のデータ
 SelectMemberActivity mActivity;

 public SelectMemberActivityTest() {
  super("パッケージ名", テスト対象のActivity.class);

 }

 protected void setUp() throws Exception {
  super.setUp();
  Intent intent = new Intent(getInstrumentation().getContext(),
    テスト対象のActivity.class);
  party = setData();
  intent.putExtra("store_data", party);

  setActivityIntent(intent);
 }

 protected void tearDown() throws Exception {
  super.tearDown();
 }

 public void testSaveData() {
  assertNotNull("データを保存する.返り値がNull以外で成功とする", getActivity().saveData());
 }
}

さて、この簡単な実装だけど最初コンストラクタになぜか引数がついていてRuntimeExceptionが発生してた。気づいて修正するのにほぼ1日かかったって言うね・・・。ココみて直した。

さて、興味があるのでJUnitとか使ってますけど、決して今の開発スタイルはTDDとは言えないと思います。

そもそも、今回書いたテストも正しいテストと言えるのか分からない。その辺りは勉強なんだけど。

今風のソフトウェア開発の本を読めば多分書いてあるんだろうね。まあ、実践も一緒にやっていきたい所ではあるけれど。

多分今回書いたのはこのスライドで言うところの学習テストに当たるのかな。初めて使う機能だもんね、しっかりと抑えておきたい所ではある。

2012年2月24日金曜日

【Android】オブジェクトをByte配列にしたりその逆したり【作ったよ】

現在製作中のAndroidアプリでデータベースを利用することになっている。

カラムをいちいち作ってもいいんだけど、割りとクラスの構成が面倒くさいのでBlob型で保存することにした。

という訳で、オブジェクトをByte配列に変換したり戻したりするメソッドを実装しますか。

Byte配列に変換
 public byte[] toByte() {
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  try {
   ObjectOutputStream oos = new ObjectOutputStream(baos);
   oos.writeObject(this);
  } catch (IOException e) {
   // TODO: handle exception
   return null;
  }
  return baos.toByteArray();
 }


バイト配列から変換
 public static Party byteToParty(byte[] b) {
  Party p = null;
  try {
   p = (Party) new ObjectInputStream(new ByteArrayInputStream(b))
     .readObject();
  } catch (OptionalDataException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (StreamCorruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (ClassNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return p;
 }


JUnit使って動作確認。テストケースはこれで。
 public void testToByte() {
  byte[] b = party.toByte();
  assertNotNull(b);
 }

 public void testByteToParty() {
  byte[] b = party.toByte();
  Party p = Party.byteToParty(b);
  assertEquals(p.getDate(), date);
  assertEquals(p.getTime(), time);
  assertEquals(p.getPlace(), place);
  assertEquals(p.getperson(), person);
  assertEquals(p.getKeyword(), keyword);
  assertEquals(p.getPlaceBy(), placeBy);
 }

問題なくテストを通ったから良いでしょう。

2012年2月17日金曜日

【Monaca】駅索リベンジ【作った】


最寄り駅を選択して、前と次の駅を出す
Monacaを使って、駅索をリベンジしてみることにした。

JSによるプログラミングはTitaniumを使ったことがあるけれど、

アレとは違って、HTML5によって記述するタイプ

スクリーンショットは左。

今回利用したWebAPIはHeartRails Express

まあ、駅に関してやりたい事が大抵やれるのでは無いかと思われ。

前回作った駅索のトレース+パワーアップ的なことをやっていくつもり。

明日のデブサミでMonacaの人に 作りました~ って自慢するんだー



2012年2月12日日曜日

【使ってみた】ComiceOSをインストール【Mac風】


 何となく気になったので、ComiceOSをVMWarePlayerにインストールしてみた。

設定は、大雑把に
メモリ 4GB
プロセッサのコア数 2
ネットワークアダプタ ブリッジ

さて、早速起動・・・と思ったら、起動中にフリーズしている様子。

慌てず騒がずCtrL+Alt+F1でターミナルを立ち上げて、ログイン。
startxコマンドで、X Windows Systemを起動する
$startxで起動。

多分、仮想マシンで立ち上げているから起きる問題だとは思う。

紹介元にもあるように、UbuntuをベースにしたOS。というか、Xは前のGnomeをベースにDocを追加したり、アイコンを変えたと言う物。
アイコンもMacOSX風(というかそのまま)

Launchpadも再現


面白いのは、AppStoreを模したPearStoreを持っている点だろうか。と言うか、アイコンがそのまんまだけど大丈夫か?

これがPearStoreだ!!ほしいアプリを選んでInstallをクリックするだけ

現在のバージョンでは、それだけとしか言いようが無い。

例えば、Applicationディレクトリからゴミ箱に捨てる方法でアンインストールはできない。

消せないEmacs


というか、中途半端にGNOMEなので逆に困る。つい、右上にシステムのセッティング関連のアイコンが並んでいる気がしてしまう。

仮想デスクトップも使えないっぽい(多分)。一つのデスクトップをターミナル専用にするのが好みなんだが、それも許されないのか。

格好良さで言えば、オリジナルのGnomeShellの方が格好いいんでは? と思えなくもない。

しかし、現状で最新のUbuntu11.10で動くソフトウェアが動くと言った使い勝手の良さはいいと思う。

Mac環境の無いユーザに勧めることはできないけど、一風変わったUIで他人に差を付けたいLinuxユーザが使うのは有りか。

面白そうなので、フォーラムを除いてみてプロジェクトに貢献したい。

ところで、最近ReactOSもアップデートされた記憶がある。そっちも使ってみよう。

2012年2月5日日曜日

【Android】複数のメールアドレスに対して送信するIntentを作りたい

Intentから、メールを送信するのはやり方としては様々なサイトに書かれていましたが、複数のメールアドレスに対して送る方法が無かったのでメモ。

具体的には、extra data を EXTRA_EMAILに、そしてToアドレスをStringの配列にする必用があったとのこと。

参考にしたサイトはこちら

今作っているアプリは、ListViewで選択をしたメールアドレスに対してメールを送信するので

1.ArrayListにToアドレスを保存

2.配列に変換

3.putExtra

な感じ。

コードは以下。
ArrayList toList = new ArrayList();
    Intent intent = new Intent(Intent.ACTION_SEND);
    for (Member member : memberList) {
     if (member.isJoin()) {
      toList.add(member.getMail());
     }
    }
    intent.putExtra(Intent.EXTRA_EMAIL,
      (String[]) toList.toArray(new String[0]));
    intent.putExtra(Intent.EXTRA_TEXT, "メール本文");
    intent.putExtra(Intent.EXTRA_SUBJECT, "メールタイトル");
    intent.setType("message/rfc822");
    startActivity(Intent.createChooser(intent,
      "choose email client"));


当然だけど、putExtraはArrayList型を引数にしてあげても動く。お陰で詰まってた。ArrayListでも大丈夫だろう、と勘違い。