自動テストのすばらしさをSelenium初心者にも分かるように伝えるメソッド

# はじめに
* Seleniumを触ったことがない人に実演しながらすばらしさを伝える
* 本文書は教える側の人向けに書いています
* 使用するアプリケーションは最初から稼動しているものとします
 * 開発言語はPHP(なんでもよかったのですが...)
 * はじめは１ファイルのみの構成(必要に応じて分けても可)
* Jenkins(CIツール)やSeleniumWebdriver(本格的なテストツール)などはここでは使用しない
* 自動で画面が動いていることを体感してもらうのが目的のため、単体テストはここでは作成しない
* [実習のカリキュラム](https://qiita.com/oh_rusty_nail/items/98313e35e1bee2f80a92#%E5%AE%9F%E7%BF%92%E3%81%AE%E3%82%AB%E3%83%AA%E3%82%AD%E3%83%A5%E3%83%A9%E3%83%A0)の第１〜４章までをペアプロで進めるスタイル(ドライバー/ナビゲータに分かれて15分交代制とか)
* わからなければその度にググる！

# 事例
* 私が指導者側としてこの記事のメソッドどおりにやってみた感触をお伝えします
* 第３章の後半もしくは第４章に突入すると「お～！」とか「できたできた！」などの声があがってきました
* C言語などの知識もなく普段はWindows、よく使うブラウザはIEという方だったのですが、軽く助言するだけでできるようになってました
* その簡単さ、誰にでもとっつきやすいところがSeleniumのいいところなのですよね～

# 使用するアプリケーション
* 以下のPHPサンプルアプリを使わせていただく
 * http://www.phpbook.jp/appli/keijiban/index4.html
* シンプルな掲示板ですね
* 今回はこれにほんの少しだけ手を加えて使用
* 尚、POSTしたものはファイルにためておくだけと(DB不要)

# 実習をするための事前準備

## クライアント側
* Firefox
 * インストールされていなければ入れてください
 * アプリケーションの閲覧とSeleniumでのテストをするために使用します
* [Firebug](https://addons.mozilla.org/ja/firefox/addon/firebug/)
 * HTMLの要素を調べるのに使用します
* [Selenium IDE](http://www.seleniumhq.org/download/)
 * Seleniumを使って自動テストを作成/実行するのに使用します

## サーバ側
* 今回はEC2(Amazon Linux)を使用して環境構築をやりますが、自前のcentでもなんでも可です

### PHP(最新)とapacheのインストール
* mysqlは使わないかもしれないですが...

```
$ sudo yum remove php-* httpd-*
$ sudo yum install httpd24 php54 php54-mysql -y
$ php -v #バージョン確認
PHP 5.4.30 (cli) (built: Jul  9 2014 21:40:37)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies
$ sudo /etc/init.d/httpd start
$ sudo /etc/init.d/httpd status #起動確認
Starting httpd: [ OK ]
```

### PHPファイル配置
* /var/www/html以下にフォルダ作成など

```
$ cd /var/www/html
$ sudo mkdir board
$ sudo chown ec2-user.ec2-user board
$ touch board.txt #記録用ファイル
$ chmod 666 board.txt

```

* あとはindex.phpを配置するだけ
 * 配置する際には権限を正しく設定してください

```php:index.php
<?php
<html>
<head><title>掲示板</title></head>
<body>
<h2>掲示板</h2>
<form method="POST" action="<?php print($_SERVER['PHP_SELF']) ?>">
  <div><label for='name'>投稿者 </label><input type="text" name="personal_name" id='name'></div>
  <div><textarea name="contents" rows="8" cols="40"></textarea></div>
  <input type="submit" name="btn1" value="投稿する">
</form>

<?php
if($_SERVER["REQUEST_METHOD"] == "POST"){
  writeData();
}
readData();

function readData(){
  $file = 'board.txt';
  $fp = fopen($file, 'rb');
  if ($fp){
    if (flock($fp, LOCK_SH)){
      while (!feof($fp)) {
        $buffer = fgets($fp);
        print($buffer);
      }
      flock($fp, LOCK_UN);
    } else {
      print('ファイルロックに失敗しました');
    }
  }
  fclose($fp);
}

function writeData(){
  $personal_name = $_POST['personal_name'];
  $contents = $_POST['contents'];
  $contents = nl2br($contents);
  $file = 'board.txt';
  $fp = fopen($file, 'wb');
  $data = <<<"DATA"
<hr>
<div class='name'>☆$personal_name</div>
<div class='contents'>$contents</div>
DATA;
  if ($fp){
    if (flock($fp, LOCK_EX)){
      if (fwrite($fp,  $data) === FALSE){
        print('ファイル書き込みに失敗しました');
      }
      flock($fp, LOCK_UN);
    } else {
       print('ファイルロックに失敗しました');
    }
  }
  fclose($fp);
}
?>
</body>
</html>
?>
```

* ついでに、章が進む度に毎回ブログを消すのがめんどくさいのでスクリプトを配置しておくと楽です
 * ご利用の際は実行権限も付けてくださいね

```:delete_borad.sh
#!/bin/bash

FILE="board.txt"
rm -fr $FILE
touch $FILE
chmod 666 $FILE
```

# 実習のカリキュラム
## 第１章
### テストを書かないで作ったアプリにはバグが潜んでいた
* １件のバグが見つかる
 * 他にもバグがあるのではないかと疑いたくなる
* 書かないコードにバグはない⇒書いたコードにはバグの存在を疑うべき
* バグを修正して第２章へ

#### 潜んでいたバグの正体
* 仕様など書いていないので一見バグではないともおもうかもしれませんが、掲示板ってどんどん書き込み増えますよね
* 見ての通りindex.php内の記録ファイルの書き込みが"wb"になっているので上書きされません
* 一回書き込みしただけでは分からないんですが、２度目書き込むとすぐ分かっちゃいますね^q^
* というしょうもないバグを見つけたところで第２章へ

## 第２章
### 手動テストって大変！！
* 機能を追加するとともにテストする項目を作成してみる
 * あくまでここでは手動でテストをする前提
* 何をテストすればよいのか思いつくテストをどんどん書き下ろしてもらう
* すべて手動でテストして疲れるのが目的
 * 「え、このテストを機能追加する度にやるの？」と感じる

#### 追加する機能
* 1. 題名を追加する

```php:index.php
...
<form method="POST" action="<?php print($_SERVER['PHP_SELF']) ?>">
  <div><label for='name'>投稿者 </label><input type="text" name="personal_name" id='name'></div>
  <div><label for='title'>題名 </label><input type="text" name="title" id='title'></div> <!-- この行を追加 -->
  <div><textarea name="contents" rows="8" cols="40"></textarea></div>
  <input type="submit" name="btn1" value="投稿する">
</form>

...
# function writeData(){内に以下の行を追加
$title = $_POST['title'];
<div class='title'>$title</div>
...
```

* 2. 投稿時に自動でタイムスタンプを付ける

```php:index.php
...
  #以下2行を追加
  date_default_timezone_set('Asia/Tokyo');
  $timestamp = date("Y/m/d H:i:s"); 
  $data = <<<"DATA"
<hr>
<div class='name'>☆$personal_name</div>
<div class='title'>$title</div>
<div class='contents'>$contents</div>
<div class='timestamp'>$timestamp</div> <!-- この行を追加 -->
...
```

#### 実施するテストの例
* 題名の入力欄が表示されていること
* 投稿後の確認として、入力した題名が掲示板の表示に追加されていること
* タイムスタンプが日本時間の表記になっていること
* 投稿した時間と一致していること
* などなど...最低限こんな感じで！

## 第３章
### 手動⇒自動テストにシフトしよう
* 第１章と第２章までのテストを自動化してみる
* ここで使うテストツールはSeleniumIDE
 * 時間はかけずに手軽にやりたいため
* 以下のようテストを作ってみる
 * 第１章の投稿以外の部分のテストの一部を自動化 

```HTML:test.html
<tr>
	<td>verifyTitle</td>
	<td>掲示板</td>
	<td></td>
</tr>
<tr>
	<td>verifyText</td>
	<td>css=h2</td>
	<td>掲示板</td>
</tr>
<tr>
	<td>verifyText</td>
	<td>css=label[for='name']</td>
	<td>投稿者</td>
</tr>
<tr>
	<td>verifyElementPresent</td>
	<td>css=input#name</td>
	<td></td>
</tr>
<tr>
	<td>verifyElementPresent</td>
	<td>css=input[type='submit']</td>
	<td></td>
</tr>
```

* こんな感じでコツコツ作っていきます
* CSSのセレクタについては[[覚え書き] CSS再入門～セレクタ～](http://qiita.com/oh_rusty_nail/items/e522fe74bc3547b3e826)を参考にしてください
* Seleniumのコマンドについては[これだけはおさえておきたい！Selenium IDEのコマンド](http://qiita.com/oh_rusty_nail/items/c59d4345d5372213128f)を参考にしてください

## 第４章
### 機能実装するときにはテスト作成も併せてやりましょう
* 機能追加を何個か行い、どんどんテストを増やしていく
* ある程度機能が追加できたら作ったテストをドカンとまわしてみる
* 「はやっ！」と感じることができればバンザイ☆

#### 追加する機能
* あとは好きなだけ機能追加して、テストも追加していってという流れ
 * faviconを設定してみるのもよし
 * スタイルを変えてカラフルにしてみるのもよし
 * iframeで別のサイトの何かを表示させてみるのもよし...

# ～ただの宣伝～
* [全国のSeleniumer必読](http://qiita.com/oh_rusty_nail/items/b8ba525d31ea7c522856)
* Seleniumerといっていますが、Selenium, SauceLabs, Travis, Jenkinsに関するノウハウ書いているのでよかったら参考にしてみてください