2011年7月30日土曜日

[Android] JUnitを使ってテストする

Androidで単体テストを行うときに使用するJUnitを今日は使ってみたいと思います。

というわけでさっそく使ってみましょう。

ハイライトとしては以下のとおりです。
1.ActivityInstrumentationTestCase2を継承する
2.パッケージとテストしたいクラスを指定したコンストラクタを作成
3.テスト準備を行うsetUpメソッドを記述する
4.試験する項目ごとに、testで始まるメソッド名を付け、テスト内容を記述する

えっと、先に参考サイトは
こちら
テスティングフレームワーク JUnit

こちら
AndroidアプリケーションをJUnitでテストする

ですね。

では、さっそくコードです。

・・・その前にテストプロジェクトを作成しましょう。
New -> Android TestProjectで作成します。


























画面としてはこんな感じです。
今回は前回使用したプロジェクト(checkBoxAcitivy)を使用します。


では、コードをみていきましょう。

1.ActivityInstrumentationTestCase2を継承する
  1. public class CheckActivityTest extends ActivityInstrumentationTestCase2<checkactivity>  {  
  2. }  
  3. </checkactivity>  

JUnitだとTestCaseなんですが、Androidはこちらを使用するとのことです。
Activityだからかな。

次。

2.パッケージとテストしたいクラスを指定したコンストラクタを作成
  1. public CheckActivityTest() {  
  2.   super("jp.co.mogakana.check.test",CheckActivity.class);  
  3.  }  

クラスを指定してやら無いといかんということですね。

では次。

3.テスト準備を行うsetUpメソッドを記述する
  1. @Override  
  2.  protected void setUp() throws Exception {  
  3.      super.setUp();  
  4.       
  5.      // Activityを取得  
  6.      mActivity = getActivity();  
  7.      // リソースを紐付け  
  8.      mCheckTooth = (CheckBox) mActivity.findViewById(R.id.toothCheck);  
  9.      mCheckHair = (CheckBox) mActivity.findViewById(R.id.hairCheck);  
  10.      mCheckBody = (CheckBox) mActivity.findViewById(R.id.bodyCheck);  
  11.     
  12.  }  

ここはあんまり説明するまでもないかもしれませんが。
テストで使用するActivityを取得します。

4.試験する項目ごとに、testで始まるメソッド名を付け、テスト内容を記述する
  1. // 歯を磨いていないかチェックする  
  2.  public void testIsCheckTooth() {  
  3.   assertFalse(mCheckTooth.isChecked());  
  4.  }  

上記は単純にチェックボックスがオフになっていることを確認しています。
テスト中にUIをいじる・・・
例えばチェックボックスにチェックをいれるなどの動作をする場合は
別スレッドで動作させます。

  1. // 髪を磨いてチェックする  
  2.  public void testIsCheckHair() {  
  3.   mActivity.runOnUiThread(new Runnable() {  
  4.       @Override  
  5.       public void run() {  
  6.        mCheckHair.setChecked(true);  
  7.       }  
  8.   });  
  9.     
  10.   getInstrumentation().waitForIdleSync();  
  11.     
  12.   assertTrue(mCheckHair.isChecked());  
  13.  }  

こんな感じですね。
実際にチェックをいれてから動作が完了するまで待ってから判定しています。

こんな感じでJUnitは使用していきます。
これはさわりだけなんで、詳しいことはまた後日・・・。


だとおもいたい。

せっかくなのでソースコードをさらしておきますのさー。

  1. package jp.co.mogakana.check.test.testcase;  
  2.   
  3. import android.app.Activity;  
  4. import android.test.ActivityInstrumentationTestCase2;  
  5. import android.widget.CheckBox;  
  6. import jp.co.mogakana.check.test.CheckActivity;  
  7.   
  8. import jp.co.mogakana.check.test.R;  
  9.   
  10. /* 1.ActivityInstrumentationTestCase2を継承する */  
  11. public class CheckActivityTest extends ActivityInstrumentationTestCase2<checkactivity>  {  
  12.    
  13.  // Activity用  
  14.  private Activity mActivity;  
  15.   
  16.  // CheckBox1用  
  17.  private CheckBox mCheckTooth;  
  18.  private CheckBox mCheckHair;  
  19.  private CheckBox mCheckBody;  
  20.    
  21.    
  22.  /* 2.パッケージとテストしたいクラスを指定したコンストラクタを作成 */  
  23.    
  24.  public CheckActivityTest() {  
  25.   super("jp.co.mogakana.check.test",CheckActivity.class);  
  26.  }  
  27.    
  28.    
  29.  /* 3.テスト準備を行うsetUpメソッドを記述する */   
  30.  @Override  
  31.  protected void setUp() throws Exception {  
  32.      super.setUp();  
  33.       
  34.      // Activityを取得  
  35.      mActivity = getActivity();  
  36.      // リソースを紐付け  
  37.      mCheckTooth = (CheckBox) mActivity.findViewById(R.id.toothCheck);  
  38.      mCheckHair = (CheckBox) mActivity.findViewById(R.id.hairCheck);  
  39.      mCheckBody = (CheckBox) mActivity.findViewById(R.id.bodyCheck);  
  40.     
  41.  }  
  42.    
  43.  /* 4.試験する項目ごとに、testで始まるメソッド名を付け、テスト内容を記述する */  
  44.    
  45.  // 歯を磨いていないかチェックする  
  46.  public void testIsCheckTooth() {  
  47.   assertFalse(mCheckTooth.isChecked());  
  48.  }  
  49.    
  50.  // 髪を磨いてチェックする  
  51.  public void testIsCheckHair() {  
  52.   mActivity.runOnUiThread(new Runnable() {  
  53.       @Override  
  54.       public void run() {  
  55.        mCheckHair.setChecked(true);  
  56.       }  
  57.   });  
  58.     
  59.   getInstrumentation().waitForIdleSync();  
  60.     
  61.   assertTrue(mCheckHair.isChecked());  
  62.  }  
  63.    
  64.  // 体を洗って戻して(?)チェックする  
  65.  public void testIsCheckBody() {  
  66.   mActivity.runOnUiThread(new Runnable() {  
  67.       @Override  
  68.       public void run() {  
  69.        mCheckBody.setChecked(true);  
  70.     mCheckBody.setChecked(false);  
  71.       }  
  72.   });  
  73.     
  74.   getInstrumentation().waitForIdleSync();  
  75.   assertFalse(mCheckBody.isChecked());  
  76.     
  77.  }  
  78.    
  79. }  
  80. </checkactivity>  

2011年7月29日金曜日

[読書記録] - 「持っている人」が持っている共通点

ブクログ(別ブログにあげてますが、IDは一緒です)にあげているレビューのもののうち
まともに書いたものは記事としてさらしあげます。

「持っている人」が持っている共通点

- 小笹芳央 著



「あいつ、持ってんな」

と思う人をたびたび見かける。が、持っているものの正体が私にもわからなくてもやもやしたりする。そんなときに本屋をうろついていて出会ったのが本書である。

本書は「持っている人」が持っているものの正体を解き明かすために書かれた本である。解き明かすためとしている以上は最後には「持っている人が持っているもの」が解き明かされるのだが、この文章ではあえてそれには触れないでおく。



「持っているを持っている人」としてトップアスリートがあげられて解説されている。さらに、持っていない人についてもふれられている。普通の人から見た両者の比較はじつにおもしろい。特に著者による「持っていない人へのツッコミ」は腹を抱えて笑うことができる。

世の中にいる不思議な「持ってない人」についての冷静なるツッコミを用いての解説は世の中の心理すら解説されているようにも見える。



さて、この文章では少し持っている人と持っていない人。そして私と言う「ロボット」から見た感想を述べさせていただく。

著者がいう「持っている人」の具体例には主にトップアスリートと言う「勝負師」があげられている。私には勝負師の世界の記憶や感情は無いが、勝負師の世界の厳しさは知識として知っている。

勝負というものは字のごとく、「勝ちか負けか」の2択しか存在しない。「参加することに意義がある」というような都合の良い解釈は存在しない。

い や、その都合の良い解釈をした時点で「負け」は確定している。勝負師は決してこのようなことをかんがえたりはしない。常に勝つことを前提に入念な練習を行 い、時を見ている。常に最大の力で勝負に挑み、勝敗を受け止めている。逆に「持ってない人」は「負ける」という意識を事前に頭に植え付け、負ける方向へと 自分を導いている。これは本書でも述べられている。マイナスがマイナスをよんでいるにすぎない。



なにも考えずに書いているので抽象的表現が多いのを悲観して、少し本書から引用させていただく。



--「持っている人」は他人・感情・過去にとらわれません。これら3つに共通しているのは「自分で自在に変えられないものだ」という点です。



以上引用文章にあるとおり、持っている人は変えられないものは「変えられないもの」と受け止めるようである。対照的なものを「変えられるもの」として最大限に変えるように努力しているのが見られる。対照的なものというのはなにか。それは「自分・思考と行動・未来」である。

他人を自分から変えることはできないが、自分で自分を変えることはできる。自分を変えるためには思考と行動を見直さなければならない。それは未来をかえることになる。

「持っ ている人」はこの「変えられるものと変えられないもの」と対峙している。そして変えられるものは最大限の力で変えている。文章にするのは簡単なことだが、 実はこの「変えられる」3つは対峙することが容易ではない。できれば逃げ出してしまいたいぐらいの巨大な敵である。しかし、「持っている人」は決してこれ らから逃げることはない。常に戦っている。

なぜ彼らは戦うのか。アスリートは「才能はあっても消えていった人たち」を目の当たりにしてい る。そしてその人たちの無念のために「高い志」をもって謙虚に取り組んでいる。消えていく人々の辛さを受け止め、自らも戦い続ける。戦い続けるためには 「志」が必要なのである。では志を持つにはどうすればいいのか?



それは、本書を読んで確認していただきたい。



こ こから先は私自身の感想だが、本書で述べられている「持っているもの」を持っているか?と問われればおそらく持っているだろう。といっても、かなり広義に はなってしまう。おそらく持っているものは同じだが、性質がちがうだろう。さて、「類は友を呼ぶ」という言葉があるとおり、同じものを持つ人と察知するこ とはできる。「持っている」人は肌でわかってしまうのだ。私はその「持っている人」といくつか言葉を交わした瞬間に感覚がふるえあがる。

こ れを理論で説明するとどうなるか。これは私独自のセンサーなのだが、持っている人は持ってない人に比べて目の力がするどい。なおかつ、発する声には重みが ある。これは比喩表現ではなく、本当に「重い」のである。「重さのある声」というのはなにか。人に影響を与える声質ということである。「持っている人」は 相手に自分を印象付けるための発声法がわかっている。そして印象に残る言葉を知っている。

いくつか言葉を交わして「あいつ、持っているな」というのがわかるのだ。しかしこれは「実体」と対峙して感じるものなので、残念ながら文字だけや声だけではわからないのだが。(そしてこの声質を聞き分けられることができるのは私だけだろう)

さ て、本書では「持っていない人」が「持っている人」になるためにはどうすればよいかはかかれているが、「持っている人」が「持っていない人」になる瞬間に は記載されていない。「持っていない人」が「持っている人」になるように、「持っている人」が「持っていない人」になるという現象は当然存在するように思 える。さきほど声の話を書いたが、ここでもまた登場する。「持っている人」が深みをまして「さらに持っている人」になるときはどんどん声の重みがでてくる のだが、「持っている人」が「持っていない人」になるときは声が軽くなる。

もっと一般的な言葉として解説するならば、「持っている人」が 「持っていない人」になる瞬間は努力にあぐらを書いた瞬間である。「持っていること」に安定を覚えて、努力を怠る瞬間や志をなくした瞬間に、発する声が軽 くなる。もちろん、「持ち直すこと」は可能なので、私は極力「持っている人が維持できるように」は努めているが、先ほど述べたように他人は変えられない。 影響はあたえることはできるかもしれないが、他人を変えることまではできないのだ。



さて、なにやら他人のことばかり書いてしまった。少し疲れているのかもしれない。私自身が「自分」と「社会」の戦いに半ば疲れているからだろう。そんなときに街をうろつき、いろいろな経験をして「持ってんな」と言う人にであった瞬間に報われるのだが。



「あいつ、持ってんな(ニヤリ)」



形は違えど、なにか同じ物質をもっているものに対してニヤリとしてしまう。が、私は自分の持っているものの使い方をまだ知らない。

[Android] SH007/SH007J の USB ドライバ

いつのまにか更新されていたので。

各機種のUSBドライバダウンロードページリンク一覧

SHARP共通 ADB USBドライバ

ここからDL。
007SHは単体でもスクリーンショットがとれるらしいですが。
はてさて。

2011年7月21日木曜日

[Android] チェックボックスの制御をする

一日のTODOリストを作成中です。
最初なのでチェックボックスの制御方法など。

まずはチェックボックスを作ります。






















とりあえずこんだけ。
これ自体はXMLの記述だけなのでLayoutのXMLに延々とチェックボックスを追加するだけです。
  1. <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">  
  2.     <checkbox android:id="@+id/toothCheck" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="歯をみがく"></checkbox>  
  3.     <checkbox android:id="@+id/hairCheck" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="髪を洗う"></checkbox>  
  4.     <checkbox android:id="@+id/bodyCheck" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="体を洗う"></checkbox>  
  5. </linearlayout>  

LinearLayoutの中にチェックボックスを追加するだけの簡単なお仕事。
もちろんチェックボックスが動作しないと話にならないのでコードも書きます。
今回は簡易的にチェックボックスにチェックが入ったらトーストを出力するだけにしましょう。
イメージとしてはこんな感じ。






















クリック時の動作はコードに書きます。
OnClickListenerをはっておいて、クリック時のイベントを拾います。
チェックボックスが複数なのでチェックボックスのIDによって処理を振り分けます。

処理としてはこんな感じです。

  1. import android.app.Activity;  
  2. import android.os.Bundle;  
  3. import android.view.View;  
  4. import android.view.View.OnClickListener;  
  5. import android.widget.CheckBox;  
  6. import android.widget.Toast;  
  7.   
  8. public class CheckActivity extends Activity implements OnClickListener {  
  9.    
  10.  CheckBox mCheckTooth;  
  11.  CheckBox mCheckHair;  
  12.  CheckBox mCheckBody;  
  13.    
  14.    
  15.     @Override  
  16.     public void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.main);  
  19.           
  20.         mCheckTooth = (CheckBox)findViewById(R.id.toothCheck);  
  21.         mCheckHair = (CheckBox)findViewById(R.id.hairCheck);  
  22.         mCheckBody = (CheckBox)findViewById(R.id.bodyCheck);  
  23.           
  24.         mCheckTooth.setOnClickListener(this);  
  25.         mCheckHair.setOnClickListener(this);  
  26.         mCheckBody.setOnClickListener(this);  
  27.           
  28.     }  
  29.     
  30.  @Override  
  31.  public void onClick(View view) {  
  32.     
  33.   switch (view.getId()) {  
  34.   case R.id.toothCheck:  
  35.    if(mCheckTooth.isChecked()) {  
  36.     // 歯を磨いた  
  37.     Toast.makeText(this"歯を磨いたね", Toast.LENGTH_LONG).show();  
  38.    }   
  39.    break;  
  40.   case R.id.hairCheck:  
  41.    if(mCheckHair.isChecked()) {  
  42.     // 髪を洗った  
  43.     Toast.makeText(this"髪を洗ったね", Toast.LENGTH_LONG).show();  
  44.    }  
  45.    break;  
  46.   case R.id.bodyCheck:  
  47.    if(mCheckBody.isChecked()) {  
  48.     // 体を洗った  
  49.     Toast.makeText(this"体を洗ったね", Toast.LENGTH_LONG).show();  
  50.    }  
  51.    break;  
  52.   default:  
  53.    Toast.makeText(this"何したんだ!!", Toast.LENGTH_LONG).show();  
  54.    break;  
  55.       
  56.   }  
  57.     
  58.  }  
  59. }  

こうすると押されたチェックボックスに対応して処理が変化します。
(上記の場合はメッセージが変化します)



チェックボックスの簡単な使い方はこんな感じです。

2011年7月20日水曜日

[雑記] Windows Phone をはじめてみたかった

今日、おもいたってWindows Phoneのアプリ開発をはじめようと。

で、環境作りなんですが、
とりあえずその前に題名である「結論」を書きます。

Windows XP 非対応
Mac OS X 非対応

・・・なんですって!!(いまだにXPのあたくし)

対応しているのは
Windows Vista
もしくは
Windows 7
とのことです(汗)

パソコン新しいの買おうかな・・・(白目)

Windows Phone 開発者向け技術情報

Windows Phone Developer Tools 7.0 RTW(英語)

Windows Phone SDK 7.1 Beta2(英語)


試してみたいのに(涙)せめてMacぐらいは対応してくれてもいーんでないかと思う。

2011年7月9日土曜日

[雑記] 名前のないテスターをやって得たもの

わたしのテスター論。

■私のテスター時代
私は「ハケン」でテスターをやっていました。テスターとは、ソフトウェアのテストを実際に行う人物です。
私は最初、テスターの一番下っ端として入り、2年ぐらいで出荷前判定をおこなうぐらいになりました。実際にこのレベルになるまでと言うのはもっと時間がかかるのですが、運が良かったのでしょうね。そんな成り上がりテスターが現場にいたときのお話をちまちま時間があるときに書こうかとおもいます。

■テスターに必要なのは「忍耐」である
テスター以上に目立つ仕事はありません。なぜならば、バグがでたら真っ先に責められるのは開発ではなく、現場のテスターだからです。「なんでここをテストしなかったんだ!!」と怒られるのは担当部署のテスターです。テスターからいわせてもらえば「バグがでるような開発をしているほうがわるいんだろ!!」という気持ちですが、そんなことは言ってはいけません。開発や企画、そのほかの部署が自分のことを棚にあげて自分のミスを押し付けてきても、テスターは反論もせずに頭をさげなくてはいけません。
美徳ではありませんが、これが「最後の砦」の役目なのです。
さらに、テスターはバグが改修されるたびに同じ試験や周辺動作を辛抱強くみなくてはいけません。再現性の低いものならば、何度も・・・それこそ1000回以上同じ試験をしなくてはいけません。ゆえにテスターに一番必要なものは「忍耐」といえます。

■テスターが一目置かれているときは「なにもいわれない」
バグがでると、テスターは責められます。しかし、バグがでずにスムーズに行っているときは責められる事はありません。責められませんが、感謝される事もありません。小さなプロジェクトでは感謝されるかもしれませんが、大きなプロジェクトではスムーズにいっているときはなにもいわれません。
この「なにもいわれない状態」を一番の状態と認識できれば、テスターはやりがいのある仕事です。

■テスターの人間関係(ほかのテスターさん)
テスターでは忍耐が重要ですが、人間関係も重要になってきます。他のテスターさんたちとのバランスをとらなければなりません。
他の人が得意な箇所を見つけ出し、被らないように自分の得意な箇所をみつけなくてはいけません。なぜこのようなバランスが必要か。それは品質のバランスをとるためです。
市場に出るものはバランスよく、バグがでないことが理想です。ある機能で集中的にバグがでてしまうのはテスターのバランスが取れてない証拠です。ですので、テスターは「得意箇所」を連携させなければなりません。

■テスターの人間関係(チームリーダー)
チームリーダーはスケジュールを組む人です。一日あたりのテスト項目をだし、難易度から今日の作業をテスターさんに割り振る。バランスをとってくれる人です。しっかりした人がやってくれるのであれば、このバランスはうまくとれてテストも炎上することなく終わりますが、経験のあさい人や新規プロジェクトでは絶対に破綻します。数値上のスケジュール以上に、テストは「個々の能力」によってばらつきがでてきます。個々の能力を判断して、人をふることができなければ、テストはうまくいきません。テストを円滑にすすめるためにも、テスターは早い段階で他のテスターの能力を割り出して、リーダーにそれとなく伝えることが重要になります。
テスターは、リーダーを真っ先に育てなくてはなりません。

■テスターの人間関係(開発)
開発の人は基本的に身勝手です。自分がバグを生み出しているにもかかわらず、そして日本語がいいかげんな仕様書をあげてくるにもかかわらず、バグや誤記を指摘したら逆切れします。なぜか開発側の人間はテスターを下に見ている事が多いです(もちろんそうでない人も多い)。これ以上に腹の立つ相手はいないのですが、悔しい事にバグがでても直せるのは開発の人間しかいないのです。そのため、いかに気分がよいまますばやく直してくれるか、という開発側のモチベーションを下げない事がテスターの役目になります。バグがでても「バグです。早く修正してください」という事実だけ述べれば、開発は頭に血が上ったようになります。しかし、報告の際に証拠となるログや画面キャプチャ、そして「あなたにおまかせいたします。よろしくおねがいいたします」という一言を添えるだけで、開発はすばやく直してくれます。こちらの怒りは開発に伝わってしまいます。ですので、テスターはなるべく場を和ませるよう、やわらかい言葉をえらぶ必要があります。
余談ですが、開発と一緒の部屋でテストをしている場合だったら、テストケースに少し遊びを交える事でぴりぴりしている部屋の空気を和ませる事も可能です。

■工数について
テストははやくやればよいものではありません。量をこなせばよいわけではありません。工数は決められているので、いかにその時間ぴったりに終わらせるかを計算してやる必要があります。
もちろん、この工数と言うのは書類上だけではなく、現場の人の声やリーダーの表情をよんできめる必要があります。
かかわっている人はみんな「人間」です。早くおわってしまっては困る事情もあります。早く終わらないと困る事情もあります。
そのあたりをいかにそれとなく(さりげなく)ヒアリングすることができるかで、「できるテスター」となるか決まってきます。

■テスターの仕事とは
基本的に気配りの仕事です。周りとのバランスをどうとればいいのか、自分の役割を見極める事ができたら、現場のコントロールを行う事ができます。空気をつくっているのはこうしたテスターの努力なのです。テスターの仕事はいわば、「空気を彩る」というものであったりするのです。
現場の空気を自在にあやつる。これ以上目立つ仕事はほかにありますでしょうか?