2014年11月9日日曜日

ソフトウェアテスト研修に参加してきました

新卒の会社でweb開発に携わるようになって4か月。

先月、ソフトウェアテスト研修というものに参加する機会があったので、習ったことをまとめておこうと思います。恥ずかしながら、「テストの一般原則」も十分に知りませんでした。普段、テストの手法や、その背後にある考え方について、体系立てて勉強する機会は多くなかったので、後で見返してさらに勉強できる…といいですが。笑

ちなみに、内容はこの参考図書に沿ってるということなので、詳細が気になったら確認してみようと思います。

【参考図書/リンク】
・『いちばんやさしいソフトウェアテストの本』


・『【この1冊でよくわかる】ソフトウェアテストの教科書 - 品質を決定づけるテスト工程の基本と実践』石原一宏、田中英和 著

・Qbook(キューブック) - ソフトウェアに関する品質向上のトータルサポートサイト 


研修でのキーメッセージはシンプルで、

「品質はユーザの満足度である」「V字モデルの初期段階でなるべく多くのバグを取り除こう」「完璧な文書化、自動化を目指すよりも、まずできる範囲で改善を始める」ということでした。

V字モデルの各段階で1回レビュー(上流での設計レビュー、下流でのテスト)をしたときに、上流と下流ではバグが取り除かれる割合がかなり違うこと、チーム内の役割に関わらず、全てのメンバーが品質作りに貢献できること、手書きでもいいから制御フロー図を書いておくこと、は改めて認識したいと思います。


【ソフトウェアの品質】
・"品質" = "ユーザの満足度"
・基本要求、変動要求、潜在要求
ある製品に対するユーザの要求を、この3つに分類して整理することで、不要な機能を追加したり、逆に必要不可欠な機能で不具合を起こしたりして品質を下げてしまうことを防ぐ。

※ 要求の中身は、当然、時代によって変わる可能性がある。


例: テレビ
基本要求…その製品が最低限満たしているべき要求→画面が表示されること。
変動要求…ユーザによって、満たされていて欲しいかどうかが変わる要求→数字ボタンでチャンネルを変えられること(矢印ボタンだけで十分な人もいるかもしれない)。BSが見れること。
潜在要求…もし満たされていたら非常に満足度の高い要求→2つ以上の番組を同時に表示できる

・Verification(検証)とValidation(妥当性評価)という2つの視点
「検証」は「製品が仕様書を実現しているか」という開発者の視点、「妥当性評価」は「製品がユーザの要求を満たしているかどうか」というユーザの視点から、ソフトウェア製品を検討する。

・V字モデル
(上流)要件定義、基本設計、詳細設計
(下流)単体テスト、結合テスト、システムテスト
からなる、IT製品開発手法の一つ。(図は http://ja.m.wikipedia.org/wiki/Vモデル を参照)
・1:10:100の法則
数字は、V字モデルの各段階でバグを取り除くのに必要なコストの割合を表す。この数字から、上流過程でバグを取り除くことがいかに大事か分かる。

・静的テスト/ 動的テスト
上流過程での設計レビュー/ 下流過程でのテストがそれぞれ対応する。


【ブラックボックステスト】
仕様に基づいて、製品の振る舞いを確かめるテスト。
・境界値分析
境界値とは、出力が変わる入力値のこと。
例: 19 を入力すると「未成年」が出力され、20を入力すると「成人」が出力される。

・同値クラス分割
同値クラスは、出力が同じになる入力値の集合。
例: 0〜19、20〜はそれぞれ同値クラス。
→それぞれの同値クラスから、代表値を選んでテストの入力値とする。

・状態遷移テスト
状態遷移図: システムが、複数の状態をどのように遷移するのかを表現した図。
→仕様からテストに必要な情報の抽出ができる
→仕様を図として表現できるので、全体像の把握が容易
状態遷移表: 状態とイベントをマトリクスで表現したもの。
→状態とイベントの組み合わせが過不足ないか確認しやすい
→ある状態から別の状態への無効なパスが明らかになる

・回帰テスト、スモークテスト、簡略テスト、構成テスト、非機能テスト


【ホワイトボックステスト】
プログラムの情報処理フローに基づいて振る舞いを確かめるテスト。

・モジュールの相関や、ソフトウェアの内部構造を図に残すことは重要
・coverage(網羅率): システム全体のパスをどの程度カバーしたか
C0カバレッジ (ステートメントカバレッジ): モジュール中の全てのステートメントが、テスト中に少なくとも1回実行されている。
C1カバレッジ (デシジョンカバレッジ): 全ての分岐(例: if文)が、テスト中に少なくとも1回実行されている。
C2カバレッジ (複合コンディションカバレッジ): 条件文の全ての真/偽の組み合わせが少なくとも1回実行されている。

・制御フローテスト
プログラムを基に制御フローグラフを作成する静的テスト。
・データフローテスト
(静的) 机上で 制御フローグラフを使用し、定義→使用→消滅の流れが正しいかどうか判断する。
(動的) プログラムにデータを入力し、実行して出力結果の整合性を判断する。

・サイクロマチック数 C 
プログラムがどの程度複雑かを表す
制御フロー図において、C = (エッジの数) - (ノードの数) + 2
Cは、直列の組み合わせにおいて可能な、モジュールを通過する全てのパスを生成できる、基礎パスの最小数。→C1カバレッジの最小テストケース数と一致。



2013年1月11日金曜日

LDAについて


トピックモデル(今回はLDA: 潜在的ディリクレ配分法)について、今後自分で実装したり研究に生かしたりしたいと思ったので、
すごく簡単な例で考えてみました。(肝心なD(ディリクレ分布)についてはスルーしている・・・汗)
何か間違いとか指摘とかあれば教えて頂けると嬉しいです。

トピック
同じ文書内で使われる確率が高いような、似た意味を持つ単語の集まり。
例えば政治のトピックなら、「選挙」「国会」「内閣」が出やすい。
トピックモデルでは、文書のトピック(文書で、どのトピックがどのくらい出やすいか)と、
トピックの単語(トピックで、どの単語がどのくらい出やすいか)を求める。
参考URL: http://sucrose.hatenablog.com/entry/20120322/p1

以下、具体例を用いて具体的に流れを追ってみる。
参考URL: http://blog.echen.me/2011/08/22/introduction-to-latent-dirichlet-allocation/

・最初に観測されるのは、この文書群だけ。
(1) I like to eat broccoli and bananas.
(2) I ate a banana and spinach smoothie for breakfast.
(3) Chinchillas and kittens are cute.
(4) My sister adopted a kitten yesterday.
(5) Look at this cute hamster munching on a piece of broccoli.

自然言語処理(例:aとかtheとか意味なさそうなの(stop words)は除く。全て原形にしてカウント。)の後、文書群はこんな感じに。
(1) like eat broccoli banana.
(2) eat banana spinach smoothie breakfast.
(3) chinchilla kitten cute.
(4) sister adopt kitten yesterday.
(5) look cute hamster munch piece broccoli.

・トピックの数K=2にする、と事前に決める。topic1とtopic2。

・(参考)処理後の文書群に含まれる単語(とその頻度)。
これが、topic1やtopic2を単語の多項分布で表現する時の次元になる。
like
eat              2
broccoli     2
banana     2
spinach
smoothie
breakfast
chinchilla
kitten          2
cute          2
sister
adopt
yesterday
look
hamster
munch
piece

・各文書内の各単語に、トピックのうちの1つをランダムにassignする。(今回は手で適当に決めました)
(1) like(topic2) eat(topic1) broccoli(topic1) bananas(topic2).(4単語)
(2) eat(topic1) banana(topic2) spinach(topic1) smoothie(topic2) breakfast(topic1).(5単語)
(3) chinchilla(topic1) kitten(topic2) cute(topic2).(3単語)
(4) sister(topic2) adopt(topic1) kitten(topic2) yesterday(topic1).(4単語)
(5) look(topic1) cute(topic2) hamster(topic1) munch(topic1) piece(topic2) broccoli(topic1).(6単語)

【文書をトピック(の多項分布)で表現する】(初期値)
          topic1               topic2
(1)     2/4= 50%          2/4= 50%
(2)     3/5= 60%          2/5= 40%
(3)     1/3= 33.3%       2/3= 66.7%
(4)     2/4= 50%          2/4= 50%
(5)     4/6= 66.7%       2/6= 33.3%

【トピックを単語(の多項分布)で表現する】(初期値)
               like               eat               broccoli          ...          piece
topic1     0%               2/12= 16.7%  2/12= 16.7%                 0%                (topic1の出現回数、12回)
topic2     1/10= 10%      0%               0%                             1/10= 10%     (topic2の出現回数、10回)

・初期値を改善するため...
for each document d:
     for each word w:
          (ex) 2回目のループは、d=(1)、w = "eat" (topic1).

          for each topic t:
               * 対象の単語w以外へのトピックの割り当ては全て正しいという仮定の下、それら(対象の単語w以外の全ての単語)を用いて以下を計算する(Gibbsサンプリング)。
               (a) compute p(topic t | doc d) (文書dの中で、現在トピックtに割り当てられている単語の割合。)
               (b) compute p(word w | topic t) (全文書中で、トピックtに割り当てられた単語のうち、それがwである割合。)
               (c) (a)*(b)の値を計算。(文書からトピックが選ばれる確率)*(トピックから単語が選ばれる確率)
          wに、(c)の値が最大だったトピックtを(新たに)割り当てる。

          (ex) w = "eat" (topic1)の場合。
          (a)
          [topic1] p(topic1 | doc (1)) = 1/3
          [topic2] p(topic2 | doc (1)) = 2/3
          (b)
          [topic1] p(word "eat" | topic1) = 1/11(文書(2)のeatがカウントされる。)
          [topic2] p(word "eat" | topic2) = 0/10
          (c)
          [topic1] (1/3)*(1/11) = 1/33
          [topic2] (2/3)*(0/10) = 0
          topic1 の方が大きいので、wはtopic1 に割り当てる。(この場合は割り当てが変わらない。)

・これを繰り返すと、安定な状態に収束する。

みたい。

・「(b)の分子がゼロになってしまう。」という問題が。
全体的に単語の出現回数が低い例だったので、eatという単語も文書群中で2回しか現れなかったし、
1回しか現れない単語等は、自分自身を除けば他にどこにも現れないので、分子がゼロになる問題が生じる。
補正項入れるんだったかな。
(a)や(b)の計算には、実際にはディリクレ分布を使うはずなので、ひとまずここでアップロードして、
また勉強して分かったら記事書きたいと思います。

2012年11月29日木曜日

複数リストの各要素の平均値

複数リストの対応する要素同士に対していっぺんに処理をしたい。
リストの内包表記を使ってみた。

listA = [1.0, 2.0, 3.0]
listB = [4.0, 5.0, 6.0]
# 各要素の平均を取る。
M = [(x+y)/2 for count_x,x in enumerate(listA) for count_y,y in enumerate(listB) if count_x==count_y]
# 各要素を掛け合わせた値
N = [x*y for count_x,x in enumerate(listA) for count_y,y in enumerate(listB) if count_x==count_y]

結果:
M = [2.5, 3.5, 4.5]
N = [4.0, 10.0, 18.0]
特に後者は、ベクトルの内積を取るような時に使えるのかな、と思ったり。

Pythonのソート


Pythonでdict型のデータを作った時、キーではなく値でソートしたかった時に調べたメモ。

list.sort()とsorted()

x = [1,9,2,0,7]
y = [1,9,2,0,7]
x.sort()
x
sorted(y)
結果:sort()関数ではリスト自体が変更される。
x = [0,1,2,7,9]
y = [1,9,2,0,7]

というわけで、今回はsorted()を使ってリスト自体は変更しなかった。

dic = {"Yamada":"10", "Takeda":"50", "Itoh": "30", "Kinoshita": "20"}

結果:
dic = {'Kinoshita': '20', 'Takeda': '50', 'Yamada': '10', 'Itoh': '30'}
sorted(dic.items(), cmp=lambda x, y:cmp(int(x), int(y)), key=lambda x:x[1], reverse=True)
= [('Takeda', '50'), ('Itoh', '30'), ('Kinoshita', '20'), ('Yamada', '10')]

key=lambda x:x[1]のところで、どのオブジェクトで比較するのか指定できる。今回はx[1]と指定して、値で比較できる様になった。
cmp引数についても、比較するための関数を定義することで、文字列として与えられた数値をintに変換して比較できている。

参考URL: http://mglab.blogspot.jp/2008/06/python-sortsorted_3738.html

2012年10月10日水曜日

世界は回る、僕がいようといなくとも。でも僕はここにいて、ここで頑張る。


またまた、久しぶりの更新。
今週末合宿でお会いしたKさんに触発されたというのもあり、またおそらく長文を書こうと意気込みすぎると長続きしないと分かったので、無理せずにつらつらと。

交換留学先のスイスから帰国して早1か月強。9月最初の10日間は、夢のように幸せな時間を過ごし、その後は、ドイツ語検定B2というプチイベントをはさみつつ(合格してよかった)、一応研究室に行って研究の方向性を考えていた。データの提示順序に応じたアイデアの質の研究、というのが目下念頭にあるワードだけど、果たしてうまく研究にできるのか。というか、どうせなので一度くらい国際学会とかでも発表してみたいもんだ。。。できればヨーロッパで。

10月に入ると授業が始まるが、単位はほぼ揃っている(+留学時のものが使える)ので、今学期は1、2コマしか取らずに研究をすると思う。ドイツ語やComputer Science関係の授業があれば取りたかったけど。去年同期が取っていて面白そうだった「メディア情報学」は見当たらなかった。就活も、多少は手を動かしてみようと思う。

ここ2回の週末は、それぞれ別の意味でお世話になった組織での合宿に参加させてもらった。

9月末は、本郷時代に入ったバドミントンサークルの秋合宿。毎年、ここで運営(執行)の代替わりが行われている。自分が執行をしていたのはもう2年前になるが、その時に新入生として来てくれた人たちや、自分の下の代の人が勧誘してくれた人たちが役目を立派に果たして引退する勇姿を見るのは、なかなか感慨深いものがある。もっとも、彼らが執行をしている間自分はスイスで留学していたので、最後の最後だけ顔を出した感じなのだが。同期と旧交(というほど時間は経ってないけど)を温めたこと、何人かの先輩たちときちんとお話できたこと(一方できちんとお話できなかった方も多いが)、引退する期の人たちからスピーチ後の乾杯に呼ばれなかったこと(練習に1回しか行かずに呼ばれるようなミラクルはさすがに無理でしたw)が印象的であった。

10月最初の3連休は、学部時代に奨学金を頂いた財団の秋合宿。こちらは、年に一度、現役生+お手伝いのOB/OG数名が読書会や人生設計の討論などをしたり、交流を深めたりする場。学部時代には、先輩・同期・後輩の優秀さ・輝かしさに打ちのめされつつも、なんとか自分なりに頑張った記憶がある。今回は、社会経験はないながらも初めてOBとして参加させて頂いた。OBとして本領を発揮するべきだったのは、「あなたの知らない世界」と題するOB/OGスピーチ(ちらっと話に出た「チャンス発見学」に興味のある方は、こちらをどうぞ。http://www.panda.sys.t.u-tokyo.ac.jp/ )、現役生の討論会でのファシリテーション、懇親会、3日目のゲームの企画実行、がメインだったと思う。しかし、言うほど簡単ではなかった。辛うじて及第点かなと思えるゲームの企画実行に関しても、先輩OB/OGにご心配をかけた(結果オーライではあったけども)。別に不必要にネガティブになっているわけではない。反省はしているが、自分が現役生の時にOB/OGの方々に期待していた働きを、今の自分ができていなかった、という事実に思い至っただけだ。つまり、現状辛かろうが幸せだろうが、自分が選んで来た道と今後選ぶであろう道に対して自信を持っていて、自分の立ち位置から見えるものをしっかりと後輩に伝える事で、何らかの示唆を与えることは、3連休中の自分には完璧にはできなかったことだ。「示唆を与える」ことができたかどうかは自分が判断することではないが、「今後選ぶ道に対して自信を持ち、自分の立ち位置から見えるものをしっかりと伝える」というのは、やはりしばらく自分が目指していくべきものだと思う。同期のS君とも夕日で染まる海岸沿いで話したが、人生における長期的目標を具体的なレベルで示すのは自分には難しかった。多くの人のペーパーを読んでいても、ありきたりな(抽象的な)記述に留まってしまうように思える。自分はその事自体に「負い目」を感じて学部時代を過ごしてきたが、「負い目」を感じて動かないよりは、目の前の事をきちんとこなすことによって、少なからず何か見えてくることを信じてもいいのではないか。「一生この仕事を頑張って行きたい」と言える人は幸せかもしれないが、それを見て卑屈になると、話が全く進まない。研究にしても就活にしても、9月後半少し手を動かしただけで、多少は見えて来たものもある。ある意味、OBとして本領を発揮できるのは、もうちょっと先のことなのかもしれないと思った3連休だった。

それにしても、自分は後輩の面倒を見るのが苦手なのかもしれない。好きなのだけども。それ相応の「余裕」を持ち合わせていないのかもしれない。上に書いた様な愚痴ばっかり聞かされても後輩は寄ってこないと思うので、面と向かって話す時は、なるべく明るく振る舞う様にしている。後輩のYさんに「そんな風に悩んでるとは知らなかった」と言われたこともあるので、まあある程度は成功してるんだ、と思いたい(笑)

* Facebook連携、うまくいくのかな。。。

2012年5月22日火曜日

ことば2

また間隔が随分空いてしまった。。。ほぼ半年ですか(笑)
bloggerのUIが結構変わっている。
今日は祝日でも何でもなく、普通の月曜日だけど、こういう記事をたまたま見かけて、何か書こうかなと思った(単純なんです)。

どうやったら質問を思いつけるの?

詳細には立ち入らないけど、この方のエントリを興味深く読ませてもらった。
言葉の使い方、メモの取り方っていう方法論もそうだけど、
質問の仕方によって答えが違うという事実を明確に意識していたか、微妙。
今学期は授業も来週で終わってしまうけど、気をつけてみたい。

そもそも半年振りに自分のブログのページに飛んで来たのは(と言いながら多少後付け感はあるけど)、最近人と話す機会が少なかったというのが一つ。
セメスタープロジェクトをやっているけど個人作業の要素が大きく、授業も(上述の様に心がけ次第だけど)発言の機会は少ない。タンデムとか友人で集まる際にはもちろん話すけど、自分が伝えるべきテーマを熱意を持って伝える、また相手のそれに向き合う、みたいなのが足りてなかった気がした。

そういうのを、今日の授業の小プレゼンと例のブログで思い出した次第。
高々課題の進捗を発表するプレゼンで「自分の伝えるべきテーマ」とはなんぞ?という話だけども、
課題に対してこういう観察をし、こういう理由でこういうアプローチを取り、こういう結果が出た、だからどうなんだよ、っていうのをもう少し伝えられたら良かったし、他人のプレゼンに関しても、少しくらい突っ込んで行けば良かったのかもしれない。

これは些細な例だったけども、これに限らず、自分の意見を熱意を持って伝えることの難しさよ。。。

1) 自分の意見を持つこと
2) それを言葉で表現すること
3) (そこに熱意がこもること)
4) それを相手の理解できる言葉で相手に伝えること
5) 相手がそれを受け止めて理解すること

最近、4), 5)が求められないせい(せいなのか?)で1)〜3)が曖昧に済まされている気がする。トピックは特に問わないけど、自分がどう生きてどう死にたいのか、それに基づいて今何をするのが最善なのか、とか、もうちょっと軽い話とか。

まあ難しいんだけど、自分の中で思ってる事をしっかり言葉にして、自分でも理解できる形にして、相手とそれをぶつけ合っていきたい。その中で、自分のテーマなるものも明確にするしかないし、何が自分にとって最善かも分かるんだろう。

僕が僕であるために。(なんてカッコつけたけどあんまり関係ない)

2011年11月24日木曜日

ことば1

お久しぶりです!
日本は今日は勤労感謝の日ですね!うらやましい(笑)
今日は短く、シャワー中にふと思い浮かんだ言葉を。

「もし自分が世界で一番不幸せな人間だと思ったとしても、それでも自分はきっと一番幸せな人間のはず、なぜなら自分は考えられる限り最高に幸せな人たちに囲まれているから。」
英語とどっちの方が伝わるかな。。。
"If you think you are the unhappiest person in the world, but still you should be the happiest person ever, because you are surrounded by the best possible combination of the happiest fellows."

まあこじつけと言われればそれまでなんですが。ふと頭に浮かんだので書いてみたくなりました。

「世界で一番不幸せ」とまでいかなくても、多かれ少なかれ自分の不幸を嘆く時ってある気がします。Unhappyということばを使ったけど、なんとなく落ち込んだ時全般でもいいかもしれません。

何かがうまくいかなくて落ち込んだ時、手を動かし続けて状況改善に向けて努力する、流れに身を任せて一旦沈むとこまで沈む、いろいろあるけど、自分が"不幸せ"な状況、というか全てがうまく行っているわけじゃない事実は認めた上で、それでも自分は"幸せ"な状況にいることを思い出し、なんとか頑張っていきたいな、と素直に思えたシャワータイムでした。

ちなみに今は別にそんなに落ち込む様なことも少なく元気に頑張っているんですけど、本当に落ち込んだときもポジティブに考えられるようになりたいですね◎