新人教育

Selenium 関係ないっす。mixi 転載っす。すいません。
(Selenium だけ見たい人はカテゴリ化してるので、
そこにアンテナとかリンクはるといいと思うぉ)



今月末ぐらいから、
新入社員を教えることになるみたいなんだけど、
不安。


最近、コーチングの本買ったり、
教育論の本を立ち読みしたりして色々考える。


色々本読んだり、
自分の経験から思うのは、
結局ところ、どれだけすぐれた教育をしても、
大人を教えるのは、
難しい。


難しいっていうのは、
すでに20年とかそれぐらい生きてる人は、
確固たるアイデンティティを持っているので、
(逆に20年生きてある程度アイデンティティ持ってない人は、
 相当精神的に弱いとかアフォだとかって特性があると思う)
そのアイデンティティに影響しえるほどの影響を
俺が与えるなんておこがましい。


与えられる影響は、
無理やり数値化すると、せいぜい数パーセントから数十パーセントだろう。
あとは本人の資質。
(数十パーセント影響あったらすごいことだと思うけどね。
何故なら、それって複利になるんだから。)


む。そうか。
本人の資質でしかないもので
自分の教育能力が評価されてしまうのが不安なのかな。
などと今書いてて思った。


この本
http://www.amazon.co.jp/exec/obidos/ASIN/4774126535/250-7674052-4287460
まだ読んでないんだけど、書評を読んで同感したんだけど、


本書の結論は、「伸びる/伸びないは、仕事に対する姿勢と日々の習慣にある」と極めてシンプルだ。伸びない原因を「『わかりません』と言えないプライド」や「安易に解決策を求める姿勢」などにあるとする。逆に伸びる人は「素直にひたすら努力する」。単純なことだが、現実には、なかなかできない。


は激しく同意。



プログラムについて教えるんじゃなくて、
メタで、仕事に対する姿勢だとか、
日々学ぶ姿勢だとか、
Google の使い方だとか、
人に物を聞くときの態度だとか教えるのがいいのかなと思う。


もし、プログラムについて教えるとしたら、
ペアプロが最高だと思う。
(人によるかもしれないけど)


俺が初学者に教えたいのは、
「コードの細部に神が宿る」
ってことなんだよね。


世の中で綺麗って言われてるオープンソースのコードとか、
一緒に仕事してる素晴らしい人のコードを見ると、
細部に神が宿ってる。


この神が宿ってるっていうのは、
http://en.wikipedia.org/wiki/Code_smell
なんだよね。


匂い。
つまり感覚的なもの。
もちろん、
「長すぎるメソッド」(新入社員の頃の俺だなw。よく同期のI君に言われたwww)
とか、この記事にあるように
http://www.radiumsoftware.com/0603.html#060330
「"Object", "Handler", "Data" などがクラス名に見られる」
ことだったり、
昔から言われてることだったら、
「goto の乱用」
があったりすると、感覚によらないで、
定型的にコードに神が宿ってないと判断することも可能なんだけど、
最終的に、そのコードが美しいかどうか、神が宿ってるかどうかは、
匂い。
感覚だと思う。


その匂い感覚を教えるには、ペアプロが最適だと思う。


あるいは、課題だして、コードひたすら書かせて、
レビューするとかかな。
ただ、やっぱ現実解として、
教育に割けるコストってそんなに沢山無いからね。


とか書いてるけど、
偉そうに人に教えられる人間になってるかっていうと、、、orz。

firefox での type="file" の操作について

前このブログで「出来ない」とかはっきり書いてしまったような、
書いてしまわなかったような思い出があるのですが、
以下のようにすると、Selenium から type="file" のものを操作できるようです。

http://cakebaker.wordpress.com/2006/03/29/file-upload-with-selenium/

  • firefox の signed.applets.codebase_principal_support プロパティを true にして
  • スクリプトから netscape.security.PrivilegeManager.enablePrivilege(”UniversalFileRead”); を呼び出せとのこと。


まだ実際にやってないので、後で試すメソッド。

チェックボックスの状態のアサート

以下のような html があったとき

<html>
  <head>
    <title>チェックボックスを押す</title>
  </head>
  <body>
    <input type="checkbox" name="checkbox" checked/>チェックボックス
  </body>
</html>


チェックボックスの状態(チェックされているかされていないかを見る場合に、
以下のような Selenium でチェックが可能である。

<html>
<head><title>New Test</title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
	<td>open</td>
	<td>file:///C:/test.html</td>
	<td></td>
</tr>
<tr>
	<td>assertValue</td>
	<td>name=checkbox</td>
	<td>on</td>
</tr>
<tr>
	<td>click</td>
	<td>//input[@name='checkbox']</td>
	<td></td>
</tr>
<tr>
	<td>assertValue</td>
	<td>name=checkbox</td>
	<td>off</td>
</tr>

</tbody></table>
</body>
</html>

Selenium IDE の使い方

http://cl.pocari.org/2006-02-15-3.html


Selenium IDE いいねー。


今の自分のプロジェクトが Recorder ではじめちゃったので、
まだ IDE 本格的に触ってないんだけど、
Recorder と比較すると、
右クリからいけるメニューが増えてたり、
TestRunner の all・walk・step 実行が選べるのが変わってるのかな。
あー、あと Log Console 超いいわ。


IDE/Recorder の使い方の個人的感想としては、
・基本的な操作を IDE で Record
・操作の基本セットが出来たら、そのソースをコピペしてスクリプト作成
って感じかしら。


あと、IDE/Recorder はサーバーにスクリプト上げなくて良いという利点が。
さらに、サーバーに上がってるとセキュリティ上の問題で、
スクリプトが動かないっていう問題が多々あるんだけど、
IDE/Recorderから動かすとその問題がクリアされて、
ウマー
って事が沢山あるー。


今のプロジェクトのSeleniumスクリプトで、
画面のキャプチャ取ってる。


その方法についてはあとで書く(必殺あとで書くメソッド)

Selenium の新しいコマンドを作る

Selenium には標準で素晴らしいコマンドが沢山存在している。


なので基本的にはそのコマンドを組み合わせて、
テストを行っていけば良い。


が、当然、標準のコマンドだけでは、
「〜のテストできんー」ってのはある。


つい最近仕事であったのは、
「ある画面にエラーメッセージが出るのだが、
同じメッセージが2個出ることを確認しないといけない。
それを自動化するにはどうしたらいいか?」
ってものだった。


Selenium の標準のコマンドには、
assertTextPresent というコマンドがある。
このコマンドは、html 形式だと

<tr>
    <td>assertTextPresent</td>
    <td>hoge</td>
    <td></td>
</tr>


という形で記述し、
第一引数の「hoge」がページ内に存在するか assert (検証)し、
存在しなかったらテストに失敗した状態にするというものである。


hoge」という文字列がページ内に2回現れることを、
この assertTextPresent では検証できない。
1個だけ存在しても、2個存在しても、3個存在してもエラーにはならないからだ。


というわけで、「hoge」がページ内に2個だけ存在することを確かめるためのコマンドを作った。
(Selenium Recoder をプロジェクトで使ってるので、
Selenium のバージョン0.6 だけで動作確認しました。
多分、Selenium 0.7 でも動くと思いますが)

/* 
 * assertTextPresentCount 
 */ 
Selenium.prototype.assertTextPresentCount = function(expectedTextReg, count) { 
    var allText = this.page().bodyText(); 
     
    if (allText.match(expectedTextReg, "g").length != count) { 
        Assert.fail("Page text not adapt"); 
    } 
};


Selenium.prototype はおまじないと思ってくれ(乱暴w)。
俺のつたない JavaScript の知識から言うと、
Selenium クラスのオブジェクトの prototype フィールドに新しいメソッドを付け加えてる。多分。
この辺りは、JavaScript だなーって感じで、
JavaScript のプロトタイプベースのオブジェクト指向
動的なメソッド、フィールドの追加の概念を理解してないと
「ハァ???」って感じのコードだろうけど。
まぁ、こういう形でかけばいいと覚えればよいと思ふ。
俺もよくわかってないしwww


このコード書くにあたっては、
Selenium のソースの selenium-api.js の assertTextPresent のコードを参照した。

/*
 * Asserts that the specified text is present in the page content.
 */
Selenium.prototype.assertTextPresent = function(expectedText) {
    var allText = this.page().bodyText();

    if(allText == "") {
        Assert.fail("Page text not found");
    } else if(allText.indexOf(expectedText) == -1) {
        Assert.fail("'" + expectedText + "' not found in page text.");
    }
};


こいつが何してるかっていうと、

function(expectedText)

は、コマンドの引数を expectedText という名前で受け取るという意味。


html のコマンドの

<tr>
    <td>assertTextPresent</td>
    <td>hoge</td>
    <td></td>
</tr>

hoge」という文字列が expectedText に入る。


んで、prototype 君には、page() というメソッドがあって、
これは現在表示中のページの情報が返ってくる(これを CurrentPage オブジェクトと呼ぼう)。


CurrentPage オブジェクト君は、表示されてる html の body 部(多分)を返す
bodyText メソッドを持ってるので、それを呼ぶ事で、
allText 変数にページの text が入る

    if(allText == "") {
        Assert.fail("Page text not found");
    } else if(allText.indexOf(expectedText) == -1) {
        Assert.fail("'" + expectedText + "' not found in page text.");
    }


Assert.fail は TestRunner で実行中のスクリプトを止めて、
ブラウザ上に赤く表示させるための処理。

else if(allText.indexOf(expectedText) == -1) は、
indexOf メソッドで、
ページの文字列中に expectedText (hoge) が現れる位置を取得。
文字列中に hoge が存在しなかったら、
indexOf メソッドは -1 を返す。


これが true になるってことは、
ページの中に hoge がないってことだから、
次の Assert.fail が呼ばれて、
TestRunner が赤くなるってすんぽー。


翻って、
俺が作った拡張コマンドは

/* 
 * assertTextPresentCount 
 */ 
Selenium.prototype.assertTextPresentCount = function(expectedTextReg, count) { 
    var allText = this.page().bodyText(); 
     
    if (allText.match(expectedTextReg, "g").length != count) { 
        Assert.fail("Page text not adapt"); 
    } 
};

ほぼ assertTextPresent コマンドをパクッってるんだけど
まず、
function(expectedTextReg, count)
で引数を2個取るように定義。


html の書き方としては、

<tr>
    <td>assertTextPresentCount</td>
    <td>hoge</td>
    <td>2</td>
</tr>

と書く。


これにより、
expectedTextReg に 「hoge」が入り、
count に 「2」が入る。


ページのテキスト受け取る部分は、assertTextPresent と一緒。



if (allText.match(expectedTextReg, "g").length != count)
のところで、
文字列の match メソッドを呼ぶ。
allText に expectedTextReg であらわす正規表現に適合する文字列の配列を
"g" オプションを指定することで、
適合する文字列全てを配列として返す。
そしてその配列の個数が count と合わなかったらエラー。


んで、このコマンド使いたいときは、
このソースを、user-extension.js に書いて、
サーバーで動かすなら、TestRunner.html から見える場所に user-extension.js 置くか、
Selenium Recorder(IDE も) から動かすなら、
File - Opetion の user-extension.js の設定を、
ローカルフォルダの user-extension.js の場所に設定すれば良い。


ま、こんな感じ。
酔っ払ってるわりにはしっかり書けたよね?!wwww


後日、Selenium 公式の拡張の仕方んところの日本語訳でもしてみんよー。

Cobertura の読み方

Selenium Blog とか名乗っといて Selenium 以外の話題書くのは、個人的にどうかなと思うのですが、テスト系で便利なものについての話題は多少書きたいので、カテゴリ分けます。


テストを行う上で重要な指針の一つがカバレッジ率だと思うのですが、
(その昔、「カバレッジ率100パーセント目標」とか言ってた人がいたときは、なんていうか自分の耳が壊れたかなとか思いましたが。)
そのカバレッジを行うための Cobertura というオープンソースのツールがあります。


そんな Covertura ですが、読み方が良く分からなかった。
今日、人に説明しようとして、どうにもこうにも手が出ませんでしたwwwwwwww


コヴェルトゥーラって読みらしいです。多分。
coverage をスペイン語にした単語だとか。


あー。良かった。
人に「カバーチュラ」とか心の中で発音してましたwwwwwwwww


追記:
Cobertura はまだはてなのキーワードになってないみたい。
誰か登録して欲しい脳。