PHP + phpunit + php-webdriver + docker-selenium でブラウザテスト　①環境構築

## 目次
PHP + phpunit + php-webdriver + docker-selenium でブラウザテスト　①環境構築
[PHP + phpunit + php-webdriver + docker-selenium でブラウザテスト　②テスト実行、エラー対策](https://qiita.com/haruna-nagayoshi/items/bcf61a3e161f3ee10d83)

## 概要
seleniumに自動でブラウザテストをしてもらって楽したい。
どうせならDockerで環境構築したい。
これを実現するために調べてわかったこと、詰まっていることをまとめました。

#### 注意
- [phpunit/phpunit-selenium](https://github.com/giorgiosironi/phpunit-selenium)というライブラリでもブラウザテストを実行できるようですが、やり方がわからなかったため深く調べていません。
- phpunitも、テストコードの書き方も、詳しくありません。勉強中です。詳しくないので、あとから見返すために丁寧に書きます。


## 動作確認環境
下記の環境で動作することを確認しました。

```
Windows10 Pro
PhpStorm 2019.2.3
Docker Desktop 2.1.0.5
Docker 19.03.5
PHP 7.2 (dockerコンテナ)
composer 1.9.1 (dockerコンテナ)
Google Chrome 78.0.3904.70 (dockerコンテナ)　※1
Selenium Grid 3.141.59 (dockerコンテナ)  ※2
```

※1　chromeコンテナ内で、`google-chrome --version` で確認できる。もしくは※2の方法でも可能。
※2　コンソール画面で確認できる。
 `http://localhost:{割り当てたポート番号}/grid/console` 



## Dockerで環境構築
#### Dockerについて補足
DockerコマンドやDockerfileなどについては細かく説明しません。以下の記事を参照してください。
[Dockerで環境構築するための最低限の概念理解](https://qiita.com/minato-naka/items/e9cd026747693759800c)
[Dockerで環境構築するための最低限のコマンドを一通り実践する](https://qiita.com/minato-naka/items/e1f91e1df2c4fe7411dc)


#### docker-compose.ymlを作成
ルートディレクトリ配下にdocker-composer.ymlを作成します。
(docker-compose.ymlや後述のDockerfileのディレクトリ配置を変更する場合、
docker-compose.ymlの `build`や`volumes` を修正する必要があることを忘れないでください。私はよく忘れる...)

```
sample/
 	└─ docker-compose.yml
```

```yaml
version: "3"
services:
  selenium-hub:
    image: selenium/hub:3.141.59-xenon
    container_name: selenium-hub
    ports:
      - 4444:4444  # ポート番号は競合しなければ好きな番号でOK。ただしnodeのHUB_PORTと一致させる。

  chrome:
    image: selenium/node-chrome-debug:3.141.59-xenon
    container_name: chrome
    ports:
      - 5900:5900  # ポート番号は競合しなければ好きな番号でOK 
    links:
      - selenium-hub
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444

  php:
    container_name: php
    build: ./docker/php
    volumes:
      - .:/var/www/html
    working_dir: /var/www/html
    entrypoint: php

  composer:
    container_name: composer
    build: ./docker/composer
    volumes:
      - .:/var/www/html
    working_dir: /var/www/html
    entrypoint: composer
```

selenium-hub、chromeのnodeコンテナは、[docker-selenium](https://github.com/SeleniumHQ/docker-selenium)のイメージを利用しました。
VNCサーバでSeleniumが実際に動いている様子を見る必要がない場合は、`node-chrome`イメージを使います。
[サイボウズエンジニアのブログ　Docker で Selenium Grid の環境構築をもっと楽に！](https://blog.cybozu.io/entry/8113https://blog.cybozu.io/entry/8113)より
>VNC サーバーが入っていると、Selenium テストが流れている様子を確認するのに便利なので、今回は debug 版のイメージを使用します。




※この記事ではChromeのnodeを使って説明します。Firefoxでテストしたい場合はFirefoxのイメージを使えばOK
※[調べている間にイメージのバージョン(元素記号)が変わっている...。](https://github.com/SeleniumHQ/docker-selenium/commits/master/README.md)Chromeのバージョンアップなどに合わせているんだろうか。
2019年12月25日時点の最新バージョンは`3.141.59-yttrium`。




次に、phpコンテナ・composerコンテナの基になるDockerfileを作成します。

```
sample/
 	├─ docker-compose.yml
	└─ docker/
		　└─ composer
			└─ Dockerfile
		　└─ php
	 		└─ Dockerfile　
```



#### php/Dockerfile

```dockerfile
FROM php:7.2

WORKDIR /tmp
RUN apt-get update && \
     apt-get install -y \
         curl libzip-dev zlib1g zlib1g-dev \
         && docker-php-ext-install zip

RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
RUN composer self-update
RUN composer global require hirak/prestissimo

VOLUME ["/var/www/html"]
WORKDIR /var/www/html

ENTRYPOINT ["composer"]
CMD ["--help"]
```



#### composer/Dockerfile

※後ほどphp-webdriverをcomposer requireする際、「zipエクステンションが必要です」と言われるので先に追加しておきます。

```dockerfile
FROM php:7.2
RUN apt-get update && \
     apt-get install -y \
         curl libzip-dev zlib1g zlib1g-dev \
         && docker-php-ext-install zip
```


ここまで作成したら、環境が整ったかどうか確認します。
docker-compose.ymlが置いてあるディレクトリ(ここではルートディレクトリ直下)で、以下のコマンドをたたき、dockerコンテナを起動します。

```
$ docker-compose up -d --build
```

dockerコンテナが無事に起動したら、
`http://localhost:{selenium-hubコンテナで設定したポート番号}/grid/console`
にアクセスします。

今回の例では、
http://localhost:4444/grid/console
です。

画像のようなコンソール画面が表示されればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253650/ff057160-8baf-c9f9-96ed-4587df4958b9.png)
これで、Dockerコンテナの準備が完了しました。

#### 参考

[docker-selenium](https://github.com/SeleniumHQ/docker-selenium)
[サイボウズエンジニアのブログ　Docker で Selenium Grid の環境構築をもっと楽に！](https://blog.cybozu.io/entry/8113https://blog.cybozu.io/entry/8113)
[docker-selenium 使って見た](https://qiita.com/yutachaos/items/4a1da5d55a3bf0df889e)
[docker-selenium+phpで簡単E２Eテスト環境構築](http://tech.innovation.co.jp/2019/02/22/docker-selenium-with-php.html)
[備忘録　Dockerを利用してSeleniumのテスト環境を作る＆WebDriverを使ってみる。](https://gyagya1111.blogspot.com/2016/04/dockerseleniumwebdriver.html)
[Dockerコンテナのフロントテスト環境構築（Selenium-Grid×docker-compose）](https://qiita.com/nishimu0507/items/89fc9cb020199ccdf5cb)
[Selenium 環境構築](https://qiita.com/Qiwitaro/items/8e8b3124aa92c7997782)

## phpunitとphp-webdriverをインストール
#### composer require
PHPでユニットテストを行うにはphpunitが必要です。
また、PHPでSeleniumを動かし、ブラウザを操作するには専用のドライバーが必要です。
公式ではPHP用のドライバーがないので、 [facebook/php-webdriver](https://github.com/facebook/php-webdriver)を使います。
ルートディレクトリ直下でcomposer requireします。

```
$ docker-compose run --rm composer require phpunit/phpunit --dev
$ docker-compose run --rm composer require facebook/webdriver --dev
```

`composer.json`、`composer.lock` が自動で生成され、2つのライブラリがインストールされました。

```
sample/
	├─ composer.json　←これと
	├─ composer.lock　←これ
 	├─ docker-compose.yml
	└─ docker/
		　└─ composer
			└─ Dockerfile
		　└─ php
	 		└─ Dockerfile　
```

#### phpunit.xml.distを作成
phpunitは、XML 設定ファイルを使って[設定を変更できます](https://phpunit.readthedocs.io/ja/latest/configuration.html)。
`phpunit.xml.dist`というファイルを作成し、ルートディレクトリ直下に配置してください。

```
sample/
	├─ composer.json
	├─ composer.lock
 	├─ docker-compose.yml
	├─ phpunit.xml.dist　←これ
	└─ docker/
		　└─ composer
			└─ Dockerfile
		　└─ php
	 		└─ Dockerfile　
```

```xml
<?xml version="1.0" encoding="UTF-8"?>

<phpunit bootstrap="tests/bootstrap.php"
         backupGlobals="false"
         backupStaticAttributes="false"
         verbose="true"
         colors="true">
    <testsuites>
        <testsuite name="app">
            <directory suffix="Test.php">tests</directory>
        </testsuite>
    </testsuites>
</phpunit>
```

ドキュメントを確認しながら、必要であれば設定を加えます。
ここでは、下記の項目について設定しました。設定しなくてもたぶん動きます(未確認)。

| 項目                   | 内容                                                         |
| ---------------------- | ------------------------------------------------------------ |
| backupGlobals          | trueのとき、グローバル変数の保存や復元を、すべてのテストで完全に無効にする。デフォルトはfalse。 |
| backupStaticAttributes | trueのとき、宣言されたクラス内のすべての static プロパティの値をバックアップしてからテストを始め、 テストが終わった後でそれらの値を復元することができる。 |
| verbose                | trueのとき、より詳細な情報を出力する。例えば、 未完成のテストや省略したテストの名前が表示される。 |
| colors                 | 出力結果に色を使用する。                                     |



#### bootstrap.phpを作成
`bootstrap.php`というファイルを作成し、testsディレクトリ直下に配置してください。

```
sample/
	├─ composer.json
	├─ composer.lock
 	├─ docker-compose.yml
	├─ phpunit.xml.dist
	├─ docker/
	│	　└─ composer
	│		└─ Dockerfile
	│	　└─ php
	│ 		└─ Dockerfile　
	└─ tests/
　　　　　　└─ bootstrap.php/ ←これ

```

```php
<?php

$loader = require dirname(__DIR__).'/vendor/autoload.php';

```



クラスなど追加したらcomposer install してください。
(どのタイミングでcomposer installしないといけないか忘れた。ファイルは作ったのにテスト実行時に「クラスが無い」とか言われたらcomposer installしたり、namespaceが正しいかどうか確認してください)

```
$ docker-compose run --rm composer install
```

phpunitとphp-webdriverの準備ができたら、あとはテストコードを書いて実行するだけです。


## 次
[PHP + phpunit + php-webdriver + docker-selenium でブラウザテスト　②テスト実行、エラー対策](https://qiita.com/haruna-nagayoshi/items/bcf61a3e161f3ee10d83)