PythonでUI自動化テストを実装してみた

# やりたいこと
webアプリケーションのUIテストを自動化したい
(人の手で同じようなテストを何度も行うのは避けたい...)

# 今回やること
今回はGoogleの検索エリアにあるテキストボックスに
任意の文字列を入力し値を比較するテストを実装してみます

# 動作環境
- macOS 10.15.1(Catlina)
- Chrome 78.0.3904.108（Official Build） （64 ビット）

# 開発環境
- Python 2.7
- Python3 3.6.2
- pytest 4.6.6
- selenium 3.141.0
- Atom

# 手順
1.準備(ここが一番大変だった)
2.テストコード実装
3.テストコード実行

# 準備
## 1.Python, Python3をインストール
Pythonインストールについてはprogateさんがわかりやすく書いてくださっているので、こちらを参考にしてください。
(他力本願)
[Pythonの開発環境を用意しよう！（Mac）](https://prog-8.com/docs/python-env)

## 2.pytestをインストール
pytestはPythonのテストフレームワークの一つです
unittestなど他のフレームワークと比較して、テストに失敗した原因が分かりやすいそうです

以下のコマンドをターミナルに入力します
`pip install -U pytest`
詳細は[こちら](https://dev2prod.site/python/python-pytest-tutorial/)
(他力本g)

## 3.seleniumをインストール
seleniumは、Webアプリケーションの画面操作を自動化するツールです
主に画面テストの自動化やWeb上での単純作業に使用します

以下のコマンドをターミナルに入力します
`pip install selenium`

## 4.ChromeDriverをダウンロード
ChromeDriverとは、Google Chromeを操作するために必要なドライバ（ソフト）です
今回はChromeを操作した結果をテストするため、ソースコードからChromeを操作するためにChromeDriverが必須です
(Chromeでない場合は別のソフトが必要になります)

[こちら](https://sites.google.com/a/chromium.org/chromedriver/downloads)から
**自分が使用しているChromeに合ったバージョンのChromeDriver**をダウンロードします
Chromeのバージョンは以下の手順で確認できます
`Chromeを開く → 「⌘+,」で設定を開く → サイドバーから「Chromeについて」を開く`
![Screenshot 2019-12-07_15-10-19-707.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509577/2f876e6c-4fa8-aad0-86e2-f3afc8ea2471.png)

## 5.ChromeDriverを任意の場所に移動
Macでダウンロードした場合は、「ダウンロード」にあると思います
ですが、ChromeDriverを使用するためにはソースコード上からパスを指定する必要があります
そのため、パスで指定しやすい場所に置いておくのがいいと思います
今回はわかりやすくするために、**プロジェクト配下にChromeDriverを移動しておきます**
(私はここで躓き2時間以上ハマりました😇)
<img width="469" alt="スクリーンショット 2019-12-07 15.16.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509577/72e6eea4-52fd-a3cf-c26f-326d26836651.png">


これで準備はOKです！！
素晴らしい！！

# テストコード実装
いよいよテストコードを書いていきます
1つ1つ解説していきますが、**あとで完成形をまとめて記載します**

## 1.必要なモジュールをファイルに追加します

```python:test_google.py
import os
from selenium import webdriver
```

## 2.テストを実行するための関数を作成します
pytestは関数名の前に`test_`と記述することでテストコードと認識し、テストを実行します。

```python:test_google.py
# 関数名の前に"test_"をつける
def test_google():
    print("test")
```

## 3.ChromeDriverをインスタンス化して、テスト対象を取得します
プロジェクト配下にあるchromedriverを相対パスで参照してインスタンス化します
※プロジェクト配下外にある場合、chromedriverのパスは異なります

テスト対象の取得ですが、今回のテスト対象はGoogleの検索エリアにあるテキストボックスです

```python:test_google.py
def test_google():
    # chromedriverをインスタンス化
    driver = webdriver.Chrome('./chromedriver') # ここのパスは人によって異なる場合があります
    # googleのページを取得
    driver.get('https://google.com')
    # 検索エリアのテキストボックスをインスタンス化
   textbox = driver.find_element_by_name('q') # 'q'はテスト対象によって異なります
```

テスト対象のnameを知る方法は**Chromeの検証機能**を使用して確認します
1. `⌘+option+C`で検証機能を起動する
2. 検索エリアにカーソルを合わせる
3. コード内の`name`を確認する
<img width="1440" alt="スクリーンショット 2019-12-07 15.59.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509577/8c4e37e5-8e04-e483-48c5-35ad342ae5b0.png">



## 4.テキストボックスに任意の文字列を入力します
```python:test_google.py
def test_google():
    driver = webdriver.Chrome('./chromedriver') # ここのパスは任意です
    driver.get('https://google.com')
    textbox = driver.find_element_by_name('q')
    # ここから追加する
    # テキストボックスを一度クリアにする
    textbox.clear()
    # テキストボックスに任意の文字列を入力する
    textbox.send_keys('hogehoge')
```

## 5.テキストボックスの値と正しい値を比較します
`get_attribute('value')`でテキストボックスの値を取得し、`assert`を利用して値を比較をします

```python:test_google.py
def test_google():
    driver = webdriver.Chrome('./chromedriver') # ここのパスは任意です
    driver.get('https://google.com')
    textbox = driver.find_element_by_name('q')
    textbox.clear()
    textbox.send_keys('hogehoge')
    # ここから追加する
    # テキストボックスの値と正しい値を比較する
    assert textbox.get_attribute('value') == 'hogehoge'
```

## 6.Chromeを閉じます
テストを実行後にはChromeを閉じます

```python:test_google.py
def test_google():
    driver = webdriver.Chrome('./chromedriver') # ここのパスは任意です
    driver.get('https://google.com')
    textbox = driver.find_element_by_name('q')
    textbox.clear()
    textbox.send_keys('hogehoge')
    assert textbox.get_attribute('value') == 'hogehoge'
    # ここから追加する
    # Chromeを閉じる
    driver.close()
```

これで完成!!
素晴らしい!!part2

## 完成形
```python:test_google.py
def test_google():
    driver = webdriver.Chrome('./chromedriver')
    driver.get('https://google.com')
    textbox = driver.find_element_by_name('q')
    textbox.clear()
    textbox.send_keys('hogehoge')
    assert textbox.get_attribute('value') == 'hogehoge'
    driver.close()
```

# テストコード実行
ターミナル上でプロジェクトファイルまで移動します
以下のコマンドを使用してテストを実行します
`pytest test_google_text.py`
pytestの後に実行したいテストが書かれているファイルを記述します

```terminal:実行結果
=============================== test session starts ================================
platform darwin -- Python 2.7.15, pytest-4.6.6, py-1.8.0, pluggy-0.13.0
rootdir: /Users/local/python_env
collected 1 item

test_google_text.py .            [100%]

============================= 1 passed in 4.16 seconds =============================
```
## 注意
テスト実行中に以下のような警告が表示された場合は、Macの設定を変更する必要があります
<img width="421" alt="スクリーンショット 2019-12-07 16.31.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509577/ffd19e1e-89f1-df47-f98e-bfb1c505c460.png">

**解決策**
`「システム環境開発」 → 「セキュリティーとプライバシー」 → 「一般」 → 「このまま開く」`
<img width="665" alt="スクリーンショット 2019-12-07 16.33.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509577/dd844bf4-e65e-b3d6-8777-cf8096e85ee4.png">


# 参考記事
[Selenium + pytestを使ってUI自動テストを書いてみる](http://siro-uma.hatenablog.com/entry/2018/12/25/222823)
[Selenium ＋ pytest でブラウザの自動テスト：その１　ブラウザを起動して閉じる](https://yoshikiito.net/blog/archives/2390/)