CircleCIでpythonテストを自動化する

CIとは

>継続的インテグレーション、CI（英: continuous integration）とは、すべての開発者の作業コピーを1日に数回、共有されたメインラインにマージすることである
(wikipedia)


インテグレーションと聞くと謎だが、要するにビルド、テスト、デプロイの作業を自動化する開発方式のことです。CIを導入することで、ソフトウェア開発を効率的に実施することができるらしい。

本記事ではCircleCIとGithubを連携させて、pythonの開発コードをpushすると自動でテストが実行されるような環境の構築を目指します。
参考記事: https://scotch.io/tutorials/continuous-integration-with-python-and-circle-ci


## ツール
アカウントを登録し、CircleCIとGithubを連携させておく。

- GitHub
- [Circle CI](https://circleci.com/ja/)

## 環境設定
- Python: 3.7


## プロジェクトの作成

下記のようにプロジェクトファイルを作成する。

フォルダ構成

```
+-- pyhton-ci
    +-- src
    |   +-- match.py
    +-- tests
        +-- math-test.py
```
```python:src/math.py
def addition(value1, value2):
    if not isinstance(value1, int) and not isinstance(value2, int):
        return 'Invalid input'
    else:
        return value1 + value2
```

```python:tests/math-test.py
import unittest
from src.math import addition

class MathTest(unittest.TestCase):
    def test_addition(self):
        actual = addition(3,4)
        expected = 8 # 実行結果と一致
        self.assertEqual(actual, expected)
```

コマンドラインからunittestを実行する

```
nosetests tests/math-test.py 
```
`AssertionError: 7 != 8`　が出力され、テストが失敗していることを確認する。




## CircleCI用ファイルの準備
プロジェクトに下記のファイルを追加する

```
+-- pyhton-ci
    +-- src
    |   +-- match.py
    +-- tests
    |   +-- math-test.py
    +-- requirements.txt
    +-- .circleci
        +-- config.yml
```

依存関係管理ファイル

```requirements.txt
nose==1.3.7
```

circleCIの設定ファイル

```
version: 2
jobs:
  build:
    working_directoyr: ~/python-ci
    docker:
      - image: circleci/python:3.6.4
    steps:
      - checkout
      - run:
          command: sudo pip install -r requirements.txt
      - run:
          command: nosetests tests/math-test.py
```

新規にGithubリポジトリを作成し、プロジェクトフォルダ全体をdevelopブランチにpushする。

```
git push origin develop
```

## CircleCIの設定
CircleCIの画面上で、Projects -> リポジトリを選択 -> Start Building -> Add Manually -> Start Building
と選択

![スクリーンショット 2020-06-15 19.08.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501910/083b8c70-c133-b82f-2c19-fa4433eecf11.png)


![スクリーンショット 2020-06-15 19.10.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501910/63e8b5ef-1006-5123-a5b9-008d9c9ed8eb.png)

Pipelines画面でテスト結果が表示される。
![スクリーンショット 2020-06-15 19.12.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501910/c3a61014-0a67-9c00-7a2c-3675c8a3addd.png)

## Github Status Checksの有効化
GithubリポジトリのSettings -> Branches タブ -> Add rule を選択

![スクリーンショット 2020-06-15 19.19.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501910/46466ace-0ca1-75c0-1f60-3d665298e836.png)

Branch name pattern に `develop` (開発ブランチ名)を入力し、

`Require status checks to pass before merging`
`Require branches to be up to date before merging`
にチェックをつける。
![スクリーンショット 2020-06-15 19.21.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501910/7e6499cb-961c-4436-c90c-048897998dc5.png)


適当に作業ブランチを切りdevelopにプルリクを送ってみる。
すると、プルリク画面で、下記のようなステータスチェックが行われる。
![スクリーンショット 2020-06-15 19.31.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501910/378e481d-356b-d6b2-99f3-516aec852db4.png)


テストコードを下記のように修正して再度pushする。

```python:math-test.py
class MathTest(unittest.TestCase):
    def test_addition(self):
        actual = addition(3,4)
        expected = 7 # 実行結果と一致
        self.assertEqual(actual, expected)
```


テストに通過していることが確認できた！
![スクリーンショット 2020-06-15 19.34.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501910/05625b5d-48c0-de8c-ad9d-0c825bb8f69d.png)