WebAPIを叩くPythonのコードをGitLab CIでunittest

# はじめに
webAPIにアクセスするプログラムのテストをGitLab CIでやってみた。
pip installしたものをimportしてるってだけで、想像以上にめんどくさかった。
地味なつまづきが多かったので、試行錯誤の結果を残しておく。

# コード
OpenWeatherMapのAPIを叩くコードをテストした。
[Сurrent weather and forecast - OpenWeatherMap](https://openweathermap.org/)
現実的な数字を返してくるかを確認するテスト。
requests.getは成功していること前提。

```python:openweather.py
import requests
import json


def get_weather():
    city_name = "Kobe"
    API_KEY = "xxx"
    api = "http://api.openweathermap.org/data/2.5/weather?units=metric&q={city}&APPID=\
{key}"

    url = api.format(city = city_name, key = API_KEY)
    # print(url)                                                                       
    response = requests.get(url)
    data = response.json()
    jsonText = json.dumps(data, indent=4)
    # print(jsonText)                                                                  
    temp = data['main']['temp']
    # print(temp)                                                                      
    # humi = data['main']['humidity']                                                  
    # print(humi)                                                                      
    # return jsonText                                                                  
    return temp

if __name__ == '__main__':
    print(get_weather())
```

```python:tests/test_openweather.py
import unittest
import openweather

class TestCalc(unittest.TestCase):

    def test_openweather(self):
        self.assertTrue(openweather.get_weather() < +50)
        self.assertTrue(openweather.get_weather() > -10)
```

# 試行錯誤
テストのファイルとログを試行錯誤の時系列にそって残しておく。

```yaml:.gitlab-ci.yml
stages:
  - test

test:
  stage: test
  script: python3 -m unittest tests/test_openweather.py

```

```
Running with gitlab-runner 11.1.0 (081978aa)
  on docker-auto-scale 4e4528ca
Using Docker executor with image ruby:2.5 ...
Pulling docker image ruby:2.5 ...
Using docker image sha256:1d8640b852eb145393da754ec38a4153edcf473a249448b7a271cea5f06016fa for ruby:2.5 ...
Running on runner-4e4528ca-project-7759319-concurrent-0 via runner-4e4528ca-srm-1533402388-348344c6...
Cloning repository...
Cloning into '/builds/iton/ow'...
Checking out cbcdd5a1 as master...
Skipping Git submodules setup
$ python3 -m unittest tests/test_openweather.py
E
======================================================================
ERROR: test_openweather (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_openweather
Traceback (most recent call last):
  File "/usr/lib/python3.5/unittest/loader.py", line 153, in loadTestsFromName
    module = __import__(module_name)
  File "/builds/iton/ow/tests/test_openweather.py", line 2, in <module>
    import openweather
  File "/builds/iton/ow/openweather.py", line 1, in <module>
    import requests
ImportError: No module named 'requests'


----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)
ERROR: Job failed: exit code 1
```

requestsがないって言われたので、pip installしてテストするようにした。

```yaml:.gitlab-ci.yml
stages:
  - test

test:
  stage: test
  script:
    - pip install requests
    - python3 -m unittest tests/test_openweather.py
```

```
Running with gitlab-runner 11.1.0 (081978aa)
  on docker-auto-scale 0277ea0f
Using Docker executor with image ruby:2.5 ...
Pulling docker image ruby:2.5 ...
Using docker image sha256:1d8640b852eb145393da754ec38a4153edcf473a249448b7a271cea5f06016fa for ruby:2.5 ...
Running on runner-0277ea0f-project-7759319-concurrent-0 via runner-0277ea0f-srm-1533402567-ac7664ff...
Cloning repository...
Cloning into '/builds/iton/ow'...
Checking out 97de2258 as master...
Skipping Git submodules setup
$ pip install requests
/bin/bash: line 65: pip: command not found
ERROR: Job failed: exit code 1
```

pipがないって言われた。

```yaml:.gitlab-ci.yml
stages:
  - test

test:
  stage: test
  script:
    - apt-get install python-pip
    - pip install requests
    - python3 -m unittest tests/test_openweather.py
```

```
Running with gitlab-runner 11.1.0 (081978aa)
  on docker-auto-scale 4e4528ca
Using Docker executor with image ruby:2.5 ...
Pulling docker image ruby:2.5 ...
Using docker image sha256:1d8640b852eb145393da754ec38a4153edcf473a249448b7a271cea5f06016fa for ruby:2.5 ...
Running on runner-4e4528ca-project-7759319-concurrent-0 via runner-4e4528ca-srm-1533403142-d6281454...
Cloning repository...
Cloning into '/builds/iton/ow'...
Checking out c41e97ef as master...
Skipping Git submodules setup
$ apt-get install python-pip
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package python-pip
ERROR: Job failed: exit code 1
```

python-devもいるみたい。

```yaml:.gitlab-ci.yml
stages:
  - test

test:
  stage: test
  script:
    - apt-get update
    - apt-get install python-dev python-pip
    - pip install requests
    - python3 -m unittest tests/test_openweather.py
```

```
Running with gitlab-runner 11.1.0 (081978aa)
  on docker-auto-scale 0277ea0f
Using Docker executor with image ruby:2.5 ...
Pulling docker image ruby:2.5 ...
Using docker image sha256:1d8640b852eb145393da754ec38a4153edcf473a249448b7a271cea5f06016fa for ruby:2.5 ...
Running on runner-0277ea0f-project-7759319-concurrent-0 via runner-0277ea0f-srm-1533403386-34810022...
Cloning repository...
Cloning into '/builds/iton/ow'...
Checking out 0349a9e7 as master...
Skipping Git submodules setup
$ apt-get update
Get:1 http://security.debian.org/debian-security stretch/updates InRelease [94.3 kB]
Ign:2 http://deb.debian.org/debian stretch InRelease
Get:3 http://deb.debian.org/debian stretch-updates InRelease [91.0 kB]
Get:4 http://deb.debian.org/debian stretch Release [118 kB]
Get:5 http://deb.debian.org/debian stretch Release.gpg [2434 B]
Get:6 http://security.debian.org/debian-security stretch/updates/main amd64 Packages [384 kB]
Get:7 http://deb.debian.org/debian stretch-updates/main amd64 Packages [5148 B]
Get:8 http://deb.debian.org/debian stretch/main amd64 Packages [7099 kB]
Fetched 7794 kB in 2s (3461 kB/s)
Reading package lists...
$ apt-get install python-dev python-pip
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  build-essential dbus dpkg-dev fakeroot libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libapparmor1
  libdbus-glib-1-2 libfakeroot libpython-all-dev libpython-dev libpython2.7
  libpython2.7-dev python-all python-all-dev python-cffi-backend python-crypto
  python-cryptography python-dbus python-enum34 python-gi python-idna
  python-ipaddress python-keyring python-keyrings.alt python-pip-whl
  python-pkg-resources python-pyasn1 python-secretstorage python-setuptools
  python-wheel python-xdg python2.7-dev
Suggested packages:
  default-dbus-session-bus | dbus-session-bus debian-keyring python-crypto-dbg
  python-crypto-doc python-cryptography-doc python-cryptography-vectors
  python-dbus-dbg python-dbus-doc python-enum34-doc python-gi-cairo
  gnome-keyring libkf5wallet-bin gir1.2-gnomekeyring-1.0 python-fs
  python-gdata python-kde4 python-keyczar doc-base python-secretstorage-doc
  python-setuptools-doc
The following NEW packages will be installed:
  build-essential dbus dpkg-dev fakeroot libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libapparmor1
  libdbus-glib-1-2 libfakeroot libpython-all-dev libpython-dev libpython2.7
  libpython2.7-dev python-all python-all-dev python-cffi-backend python-crypto
  python-cryptography python-dbus python-dev python-enum34 python-gi
  python-idna python-ipaddress python-keyring python-keyrings.alt python-pip
  python-pip-whl python-pkg-resources python-pyasn1 python-secretstorage
  python-setuptools python-wheel python-xdg python2.7-dev
0 upgraded, 36 newly installed, 0 to remove and 0 not upgraded.
Need to get 35.5 MB of archives.
After this operation, 59.3 MB of additional disk space will be used.
Do you want to continue? [Y/n] Abort.
ERROR: Job failed: exit code 1
```

`-y`を入れてYを入力しなくてすむようにした。

```yaml:.gitlab-ci.yml
stages:
  - test

test:
  stage: test
  script:
    - apt-get update
    - apt-get install -y python-dev python-pip
    - pip install requests
    - python3 -m unittest tests/test_openweather.py
```

```
Running with gitlab-runner 11.1.0 (081978aa)
  on docker-auto-scale 4e4528ca
Using Docker executor with image ruby:2.5 ...
Pulling docker image ruby:2.5 ...
Using docker image sha256:1d8640b852eb145393da754ec38a4153edcf473a249448b7a271cea5f06016fa for ruby:2.5 ...
Running on runner-4e4528ca-project-7759319-concurrent-0 via runner-4e4528ca-srm-1533403581-d6970e26...
Cloning repository...
Cloning into '/builds/iton/ow'...
Checking out 04115dd4 as master...
Skipping Git submodules setup
$ apt-get update
Get:1 http://security.debian.org/debian-security stretch/updates InRelease [94.3 kB]
Ign:2 http://deb.debian.org/debian stretch InRelease
Get:3 http://deb.debian.org/debian stretch-updates InRelease [91.0 kB]
Get:4 http://deb.debian.org/debian stretch Release [118 kB]
Get:5 http://deb.debian.org/debian stretch Release.gpg [2434 B]
Get:6 http://security.debian.org/debian-security stretch/updates/main amd64 Packages [384 kB]
Get:7 http://deb.debian.org/debian stretch-updates/main amd64 Packages [5148 B]
Get:8 http://deb.debian.org/debian stretch/main amd64 Packages [7099 kB]
Fetched 7794 kB in 1s (4926 kB/s)
Reading package lists...
$ apt-get install -y python-dev python-pip
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  build-essential dbus dpkg-dev fakeroot libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libapparmor1
  libdbus-glib-1-2 libfakeroot libpython-all-dev libpython-dev libpython2.7
  libpython2.7-dev python-all python-all-dev python-cffi-backend python-crypto
  python-cryptography python-dbus python-enum34 python-gi python-idna
  python-ipaddress python-keyring python-keyrings.alt python-pip-whl
  python-pkg-resources python-pyasn1 python-secretstorage python-setuptools
  python-wheel python-xdg python2.7-dev
Suggested packages:
  default-dbus-session-bus | dbus-session-bus debian-keyring python-crypto-dbg
  python-crypto-doc python-cryptography-doc python-cryptography-vectors
  python-dbus-dbg python-dbus-doc python-enum34-doc python-gi-cairo
  gnome-keyring libkf5wallet-bin gir1.2-gnomekeyring-1.0 python-fs
  python-gdata python-kde4 python-keyczar doc-base python-secretstorage-doc
  python-setuptools-doc
The following NEW packages will be installed:
  build-essential dbus dpkg-dev fakeroot libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libapparmor1
  libdbus-glib-1-2 libfakeroot libpython-all-dev libpython-dev libpython2.7
  libpython2.7-dev python-all python-all-dev python-cffi-backend python-crypto
  python-cryptography python-dbus python-dev python-enum34 python-gi
  python-idna python-ipaddress python-keyring python-keyrings.alt python-pip
  python-pip-whl python-pkg-resources python-pyasn1 python-secretstorage
  python-setuptools python-wheel python-xdg python2.7-dev
0 upgraded, 36 newly installed, 0 to remove and 0 not upgraded.
Need to get 35.5 MB of archives.
After this operation, 59.3 MB of additional disk space will be used.
Get:1 http://deb.debian.org/debian stretch/main amd64 libapparmor1 amd64 2.11.0-3+deb9u2 [78.9 kB]
Get:2 http://deb.debian.org/debian stretch/main amd64 dbus amd64 1.10.26-0+deb9u1 [210 kB]
Get:3 http://deb.debian.org/debian stretch/main amd64 dpkg-dev all 1.18.25 [1595 kB]
Get:4 http://deb.debian.org/debian stretch/main amd64 build-essential amd64 12.3 [7346 B]
Get:5 http://deb.debian.org/debian stretch/main amd64 libfakeroot amd64 1.21-3.1 [45.7 kB]
Get:6 http://deb.debian.org/debian stretch/main amd64 fakeroot amd64 1.21-3.1 [85.6 kB]
Get:7 http://deb.debian.org/debian stretch/main amd64 libalgorithm-diff-perl all 1.19.03-1 [48.7 kB]
Get:8 http://deb.debian.org/debian stretch/main amd64 libalgorithm-diff-xs-perl amd64 0.04-4+b2 [11.6 kB]
Get:9 http://deb.debian.org/debian stretch/main amd64 libalgorithm-merge-perl all 0.08-3 [12.7 kB]
Get:10 http://deb.debian.org/debian stretch/main amd64 libdbus-glib-1-2 amd64 0.108-2 [206 kB]
Get:11 http://deb.debian.org/debian stretch/main amd64 libpython2.7 amd64 2.7.13-2+deb9u2 [1072 kB]
Get:12 http://deb.debian.org/debian stretch/main amd64 libpython2.7-dev amd64 2.7.13-2+deb9u2 [28.2 MB]
Get:13 http://deb.debian.org/debian stretch/main amd64 libpython-dev amd64 2.7.13-2 [20.1 kB]
Get:14 http://deb.debian.org/debian stretch/main amd64 libpython-all-dev amd64 2.7.13-2 [960 B]
Get:15 http://deb.debian.org/debian stretch/main amd64 python-all amd64 2.7.13-2 [942 B]
Get:16 http://deb.debian.org/debian stretch/main amd64 python2.7-dev amd64 2.7.13-2+deb9u2 [290 kB]
Get:17 http://deb.debian.org/debian stretch/main amd64 python-dev amd64 2.7.13-2 [1126 B]
Get:18 http://deb.debian.org/debian stretch/main amd64 python-all-dev amd64 2.7.13-2 [962 B]
Get:19 http://deb.debian.org/debian stretch/main amd64 python-cffi-backend amd64 1.9.1-2 [69.0 kB]
Get:20 http://deb.debian.org/debian stretch/main amd64 python-crypto amd64 2.6.1-7 [259 kB]
Get:21 http://deb.debian.org/debian stretch/main amd64 python-enum34 all 1.1.6-1 [35.0 kB]
Get:22 http://deb.debian.org/debian stretch/main amd64 python-idna all 2.2-1 [32.6 kB]
Get:23 http://deb.debian.org/debian stretch/main amd64 python-ipaddress all 1.0.17-1 [18.1 kB]
Get:24 http://deb.debian.org/debian stretch/main amd64 python-pyasn1 all 0.1.9-2 [51.8 kB]
Get:25 http://deb.debian.org/debian stretch/main amd64 python-pkg-resources all 33.1.1-1 [166 kB]
Get:26 http://deb.debian.org/debian stretch/main amd64 python-setuptools all 33.1.1-1 [297 kB]
Get:27 http://deb.debian.org/debian stretch/main amd64 python-cryptography amd64 1.7.1-3 [211 kB]
Get:28 http://deb.debian.org/debian stretch/main amd64 python-dbus amd64 1.2.4-1+b1 [185 kB]
Get:29 http://deb.debian.org/debian stretch/main amd64 python-gi amd64 3.22.0-2 [515 kB]
Get:30 http://deb.debian.org/debian stretch/main amd64 python-secretstorage all 2.3.1-2 [13.8 kB]
Get:31 http://deb.debian.org/debian stretch/main amd64 python-keyring all 10.1-1 [40.7 kB]
Get:32 http://deb.debian.org/debian stretch/main amd64 python-keyrings.alt all 1.3-1 [16.4 kB]
Get:33 http://deb.debian.org/debian stretch/main amd64 python-pip-whl all 9.0.1-2 [1406 kB]
Get:34 http://deb.debian.org/debian stretch/main amd64 python-pip all 9.0.1-2 [179 kB]
Get:35 http://deb.debian.org/debian stretch/main amd64 python-wheel all 0.29.0-2 [51.7 kB]
Get:36 http://deb.debian.org/debian stretch/main amd64 python-xdg all 0.25-4 [35.8 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 35.5 MB in 0s (68.5 MB/s)
Selecting previously unselected package libapparmor1:amd64.
(Reading database ... 
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 29375 files and directories currently installed.)
Preparing to unpack .../00-libapparmor1_2.11.0-3+deb9u2_amd64.deb ...
Unpacking libapparmor1:amd64 (2.11.0-3+deb9u2) ...
Selecting previously unselected package dbus.
Preparing to unpack .../01-dbus_1.10.26-0+deb9u1_amd64.deb ...
Unpacking dbus (1.10.26-0+deb9u1) ...
Selecting previously unselected package dpkg-dev.
Preparing to unpack .../02-dpkg-dev_1.18.25_all.deb ...
Unpacking dpkg-dev (1.18.25) ...
Selecting previously unselected package build-essential.
Preparing to unpack .../03-build-essential_12.3_amd64.deb ...
Unpacking build-essential (12.3) ...
Selecting previously unselected package libfakeroot:amd64.
Preparing to unpack .../04-libfakeroot_1.21-3.1_amd64.deb ...
Unpacking libfakeroot:amd64 (1.21-3.1) ...
Selecting previously unselected package fakeroot.
Preparing to unpack .../05-fakeroot_1.21-3.1_amd64.deb ...
Unpacking fakeroot (1.21-3.1) ...
Selecting previously unselected package libalgorithm-diff-perl.
Preparing to unpack .../06-libalgorithm-diff-perl_1.19.03-1_all.deb ...
Unpacking libalgorithm-diff-perl (1.19.03-1) ...
Selecting previously unselected package libalgorithm-diff-xs-perl.
Preparing to unpack .../07-libalgorithm-diff-xs-perl_0.04-4+b2_amd64.deb ...
Unpacking libalgorithm-diff-xs-perl (0.04-4+b2) ...
Selecting previously unselected package libalgorithm-merge-perl.
Preparing to unpack .../08-libalgorithm-merge-perl_0.08-3_all.deb ...
Unpacking libalgorithm-merge-perl (0.08-3) ...
Selecting previously unselected package libdbus-glib-1-2:amd64.
Preparing to unpack .../09-libdbus-glib-1-2_0.108-2_amd64.deb ...
Unpacking libdbus-glib-1-2:amd64 (0.108-2) ...
Selecting previously unselected package libpython2.7:amd64.
Preparing to unpack .../10-libpython2.7_2.7.13-2+deb9u2_amd64.deb ...
Unpacking libpython2.7:amd64 (2.7.13-2+deb9u2) ...
Selecting previously unselected package libpython2.7-dev:amd64.
Preparing to unpack .../11-libpython2.7-dev_2.7.13-2+deb9u2_amd64.deb ...
Unpacking libpython2.7-dev:amd64 (2.7.13-2+deb9u2) ...
Selecting previously unselected package libpython-dev:amd64.
Preparing to unpack .../12-libpython-dev_2.7.13-2_amd64.deb ...
Unpacking libpython-dev:amd64 (2.7.13-2) ...
Selecting previously unselected package libpython-all-dev:amd64.
Preparing to unpack .../13-libpython-all-dev_2.7.13-2_amd64.deb ...
Unpacking libpython-all-dev:amd64 (2.7.13-2) ...
Selecting previously unselected package python-all.
Preparing to unpack .../14-python-all_2.7.13-2_amd64.deb ...
Unpacking python-all (2.7.13-2) ...
Selecting previously unselected package python2.7-dev.
Preparing to unpack .../15-python2.7-dev_2.7.13-2+deb9u2_amd64.deb ...
Unpacking python2.7-dev (2.7.13-2+deb9u2) ...
Selecting previously unselected package python-dev.
Preparing to unpack .../16-python-dev_2.7.13-2_amd64.deb ...
Unpacking python-dev (2.7.13-2) ...
Selecting previously unselected package python-all-dev.
Preparing to unpack .../17-python-all-dev_2.7.13-2_amd64.deb ...
Unpacking python-all-dev (2.7.13-2) ...
Selecting previously unselected package python-cffi-backend.
Preparing to unpack .../18-python-cffi-backend_1.9.1-2_amd64.deb ...
Unpacking python-cffi-backend (1.9.1-2) ...
Selecting previously unselected package python-crypto.
Preparing to unpack .../19-python-crypto_2.6.1-7_amd64.deb ...
Unpacking python-crypto (2.6.1-7) ...
Selecting previously unselected package python-enum34.
Preparing to unpack .../20-python-enum34_1.1.6-1_all.deb ...
Unpacking python-enum34 (1.1.6-1) ...
Selecting previously unselected package python-idna.
Preparing to unpack .../21-python-idna_2.2-1_all.deb ...
Unpacking python-idna (2.2-1) ...
Selecting previously unselected package python-ipaddress.
Preparing to unpack .../22-python-ipaddress_1.0.17-1_all.deb ...
Unpacking python-ipaddress (1.0.17-1) ...
Selecting previously unselected package python-pyasn1.
Preparing to unpack .../23-python-pyasn1_0.1.9-2_all.deb ...
Unpacking python-pyasn1 (0.1.9-2) ...
Selecting previously unselected package python-pkg-resources.
Preparing to unpack .../24-python-pkg-resources_33.1.1-1_all.deb ...
Unpacking python-pkg-resources (33.1.1-1) ...
Selecting previously unselected package python-setuptools.
Preparing to unpack .../25-python-setuptools_33.1.1-1_all.deb ...
Unpacking python-setuptools (33.1.1-1) ...
Selecting previously unselected package python-cryptography.
Preparing to unpack .../26-python-cryptography_1.7.1-3_amd64.deb ...
Unpacking python-cryptography (1.7.1-3) ...
Selecting previously unselected package python-dbus.
Preparing to unpack .../27-python-dbus_1.2.4-1+b1_amd64.deb ...
Unpacking python-dbus (1.2.4-1+b1) ...
Selecting previously unselected package python-gi.
Preparing to unpack .../28-python-gi_3.22.0-2_amd64.deb ...
Unpacking python-gi (3.22.0-2) ...
Selecting previously unselected package python-secretstorage.
Preparing to unpack .../29-python-secretstorage_2.3.1-2_all.deb ...
Unpacking python-secretstorage (2.3.1-2) ...
Selecting previously unselected package python-keyring.
Preparing to unpack .../30-python-keyring_10.1-1_all.deb ...
Unpacking python-keyring (10.1-1) ...
Selecting previously unselected package python-keyrings.alt.
Preparing to unpack .../31-python-keyrings.alt_1.3-1_all.deb ...
Unpacking python-keyrings.alt (1.3-1) ...
Selecting previously unselected package python-pip-whl.
Preparing to unpack .../32-python-pip-whl_9.0.1-2_all.deb ...
Unpacking python-pip-whl (9.0.1-2) ...
Selecting previously unselected package python-pip.
Preparing to unpack .../33-python-pip_9.0.1-2_all.deb ...
Unpacking python-pip (9.0.1-2) ...
Selecting previously unselected package python-wheel.
Preparing to unpack .../34-python-wheel_0.29.0-2_all.deb ...
Unpacking python-wheel (0.29.0-2) ...
Selecting previously unselected package python-xdg.
Preparing to unpack .../35-python-xdg_0.25-4_all.deb ...
Unpacking python-xdg (0.25-4) ...
Setting up python-idna (2.2-1) ...
Setting up python-pip-whl (9.0.1-2) ...
Setting up python-crypto (2.6.1-7) ...
Setting up libdbus-glib-1-2:amd64 (0.108-2) ...
Setting up python-pyasn1 (0.1.9-2) ...
Setting up python-wheel (0.29.0-2) ...
Setting up python-pkg-resources (33.1.1-1) ...
Setting up python-keyrings.alt (1.3-1) ...
Setting up python-cffi-backend (1.9.1-2) ...
Setting up python-gi (3.22.0-2) ...
Setting up dpkg-dev (1.18.25) ...
Processing triggers for libc-bin (2.24-11+deb9u3) ...
Setting up libapparmor1:amd64 (2.11.0-3+deb9u2) ...
Setting up libfakeroot:amd64 (1.21-3.1) ...
Setting up python-enum34 (1.1.6-1) ...
Setting up libpython2.7:amd64 (2.7.13-2+deb9u2) ...
Setting up libalgorithm-diff-perl (1.19.03-1) ...
Setting up libpython2.7-dev:amd64 (2.7.13-2+deb9u2) ...
Setting up dbus (1.10.26-0+deb9u1) ...
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
Setting up python-dbus (1.2.4-1+b1) ...
Remove stale byte-compiled files...
Setting up python-ipaddress (1.0.17-1) ...
Setting up python-pip (9.0.1-2) ...
Setting up python2.7-dev (2.7.13-2+deb9u2) ...
Setting up python-all (2.7.13-2) ...
Setting up python-xdg (0.25-4) ...
Setting up libpython-dev:amd64 (2.7.13-2) ...
Setting up python-setuptools (33.1.1-1) ...
Setting up build-essential (12.3) ...
Setting up python-dev (2.7.13-2) ...
Setting up libpython-all-dev:amd64 (2.7.13-2) ...
Setting up fakeroot (1.21-3.1) ...
update-alternatives: using /usr/bin/fakeroot-sysv to provide /usr/bin/fakeroot (fakeroot) in auto mode
Setting up libalgorithm-merge-perl (0.08-3) ...
Setting up libalgorithm-diff-xs-perl (0.04-4+b2) ...
Setting up python-all-dev (2.7.13-2) ...
Setting up python-cryptography (1.7.1-3) ...
Setting up python-secretstorage (2.3.1-2) ...
Setting up python-keyring (10.1-1) ...
Processing triggers for libc-bin (2.24-11+deb9u3) ...
$ pip install requests
Collecting requests
  Downloading https://files.pythonhosted.org/packages/65/47/7e02164a2a3db50ed6d8a6ab1d6d60b69c4c3fdf57a284257925dfc12bda/requests-2.19.1-py2.py3-none-any.whl (91kB)
Collecting idna<2.8,>=2.5 (from requests)
  Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB)
Collecting urllib3<1.24,>=1.21.1 (from requests)
  Downloading https://files.pythonhosted.org/packages/bd/c9/6fdd990019071a4a32a5e7cb78a1d92c53851ef4f56f62a3486e6a7d8ffb/urllib3-1.23-py2.py3-none-any.whl (133kB)
Collecting chardet<3.1.0,>=3.0.2 (from requests)
  Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)
Collecting certifi>=2017.4.17 (from requests)
  Downloading https://files.pythonhosted.org/packages/7c/e6/92ad559b7192d846975fc916b65f667c7b8c3a32bea7372340bfe9a15fa5/certifi-2018.4.16-py2.py3-none-any.whl (150kB)
Installing collected packages: idna, urllib3, chardet, certifi, requests
  Found existing installation: idna 2.2
    Not uninstalling idna at /usr/lib/python2.7/dist-packages, outside environment /usr
Successfully installed certifi-2018.4.16 chardet-3.0.4 idna-2.7 requests-2.19.1 urllib3-1.23
$ python3 -m unittest tests/test_openweather.py
E
======================================================================
ERROR: test_openweather (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_openweather
Traceback (most recent call last):
  File "/usr/lib/python3.5/unittest/loader.py", line 153, in loadTestsFromName
    module = __import__(module_name)
  File "/builds/iton/ow/tests/test_openweather.py", line 2, in <module>
    import openweather
  File "/builds/iton/ow/openweather.py", line 1, in <module>
    import requests
ImportError: No module named 'requests'


----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)
ERROR: Job failed: exit code 1
```

pipはpython2やったか…。python3に合わせた。

```yaml:.gitlab-ci.yml
stages:
  - test

test:
  stage: test
  script:
    - apt-get update
    - apt-get install -y python3-dev python3-pip
    - pip3 install requests
    - python3 -m unittest tests/test_openweather.py
```

```
Running with gitlab-runner 11.1.0 (081978aa)
  on docker-auto-scale 4e4528ca
Using Docker executor with image ruby:2.5 ...
Pulling docker image ruby:2.5 ...
Using docker image sha256:1d8640b852eb145393da754ec38a4153edcf473a249448b7a271cea5f06016fa for ruby:2.5 ...
Running on runner-4e4528ca-project-7759319-concurrent-0 via runner-4e4528ca-srm-1533403916-e66f9222...
Cloning repository...
Cloning into '/builds/iton/ow'...
Checking out 6e1d0f86 as master...
Skipping Git submodules setup
$ apt-get update
Get:1 http://security.debian.org/debian-security stretch/updates InRelease [94.3 kB]
Ign:2 http://deb.debian.org/debian stretch InRelease
Get:3 http://deb.debian.org/debian stretch-updates InRelease [91.0 kB]
Get:4 http://deb.debian.org/debian stretch Release [118 kB]
Get:5 http://deb.debian.org/debian stretch Release.gpg [2434 B]
Get:6 http://security.debian.org/debian-security stretch/updates/main amd64 Packages [384 kB]
Get:7 http://deb.debian.org/debian stretch-updates/main amd64 Packages [5148 B]
Get:8 http://deb.debian.org/debian stretch/main amd64 Packages [7099 kB]
Fetched 7794 kB in 1s (4146 kB/s)
Reading package lists...
$ apt-get install -y python3-dev python3-pip
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
  build-essential dbus dpkg-dev fakeroot libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libapparmor1
  libdbus-glib-1-2 libfakeroot libpython3-dev libpython3.5 libpython3.5-dev
  python-pip-whl python3-cffi-backend python3-crypto python3-cryptography
  python3-dbus python3-gi python3-idna python3-keyring python3-keyrings.alt
  python3-pkg-resources python3-pyasn1 python3-secretstorage
  python3-setuptools python3-six python3-wheel python3-xdg python3.5-dev
Suggested packages:
  default-dbus-session-bus | dbus-session-bus debian-keyring
  python3-crypto-dbg python-crypto-doc python-cryptography-doc
  python3-cryptography-vectors python-dbus-doc python3-dbus-dbg gnome-keyring
  libkf5wallet-bin gir1.2-gnomekeyring-1.0 python3-pykde4 doc-base
  python-secretstorage-doc python-setuptools-doc
The following NEW packages will be installed:
  build-essential dbus dpkg-dev fakeroot libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libapparmor1
  libdbus-glib-1-2 libfakeroot libpython3-dev libpython3.5 libpython3.5-dev
  python-pip-whl python3-cffi-backend python3-crypto python3-cryptography
  python3-dbus python3-dev python3-gi python3-idna python3-keyring
  python3-keyrings.alt python3-pip python3-pkg-resources python3-pyasn1
  python3-secretstorage python3-setuptools python3-six python3-wheel
  python3-xdg python3.5-dev
0 upgraded, 32 newly installed, 0 to remove and 0 not upgraded.
Need to get 45.2 MB of archives.
After this operation, 72.7 MB of additional disk space will be used.
Get:1 http://deb.debian.org/debian stretch/main amd64 libapparmor1 amd64 2.11.0-3+deb9u2 [78.9 kB]
Get:2 http://deb.debian.org/debian stretch/main amd64 dbus amd64 1.10.26-0+deb9u1 [210 kB]
Get:3 http://deb.debian.org/debian stretch/main amd64 dpkg-dev all 1.18.25 [1595 kB]
Get:4 http://deb.debian.org/debian stretch/main amd64 build-essential amd64 12.3 [7346 B]
Get:5 http://deb.debian.org/debian stretch/main amd64 libfakeroot amd64 1.21-3.1 [45.7 kB]
Get:6 http://deb.debian.org/debian stretch/main amd64 fakeroot amd64 1.21-3.1 [85.6 kB]
Get:7 http://deb.debian.org/debian stretch/main amd64 libalgorithm-diff-perl all 1.19.03-1 [48.7 kB]
Get:8 http://deb.debian.org/debian stretch/main amd64 libalgorithm-diff-xs-perl amd64 0.04-4+b2 [11.6 kB]
Get:9 http://deb.debian.org/debian stretch/main amd64 libalgorithm-merge-perl all 0.08-3 [12.7 kB]
Get:10 http://deb.debian.org/debian stretch/main amd64 libdbus-glib-1-2 amd64 0.108-2 [206 kB]
Get:11 http://deb.debian.org/debian stretch/main amd64 libpython3.5 amd64 3.5.3-1 [1371 kB]
Get:12 http://deb.debian.org/debian stretch/main amd64 libpython3.5-dev amd64 3.5.3-1 [37.7 MB]
Get:13 http://deb.debian.org/debian stretch/main amd64 libpython3-dev amd64 3.5.3-1 [18.7 kB]
Get:14 http://deb.debian.org/debian stretch/main amd64 python-pip-whl all 9.0.1-2 [1406 kB]
Get:15 http://deb.debian.org/debian stretch/main amd64 python3-cffi-backend amd64 1.9.1-2 [70.1 kB]
Get:16 http://deb.debian.org/debian stretch/main amd64 python3-crypto amd64 2.6.1-7 [259 kB]
Get:17 http://deb.debian.org/debian stretch/main amd64 python3-idna all 2.2-1 [32.7 kB]
Get:18 http://deb.debian.org/debian stretch/main amd64 python3-pyasn1 all 0.1.9-2 [34.5 kB]
Get:19 http://deb.debian.org/debian stretch/main amd64 python3-pkg-resources all 33.1.1-1 [137 kB]
Get:20 http://deb.debian.org/debian stretch/main amd64 python3-setuptools all 33.1.1-1 [215 kB]
Get:21 http://deb.debian.org/debian stretch/main amd64 python3-six all 1.10.0-3 [14.4 kB]
Get:22 http://deb.debian.org/debian stretch/main amd64 python3-cryptography amd64 1.7.1-3 [210 kB]
Get:23 http://deb.debian.org/debian stretch/main amd64 python3-dbus amd64 1.2.4-1+b1 [184 kB]
Get:24 http://deb.debian.org/debian stretch/main amd64 python3.5-dev amd64 3.5.3-1 [413 kB]
Get:25 http://deb.debian.org/debian stretch/main amd64 python3-dev amd64 3.5.3-1 [1154 B]
Get:26 http://deb.debian.org/debian stretch/main amd64 python3-gi amd64 3.22.0-2 [473 kB]
Get:27 http://deb.debian.org/debian stretch/main amd64 python3-secretstorage all 2.3.1-2 [14.2 kB]
Get:28 http://deb.debian.org/debian stretch/main amd64 python3-keyring all 10.1-1 [36.8 kB]
Get:29 http://deb.debian.org/debian stretch/main amd64 python3-keyrings.alt all 1.3-1 [16.2 kB]
Get:30 http://deb.debian.org/debian stretch/main amd64 python3-pip all 9.0.1-2 [142 kB]
Get:31 http://deb.debian.org/debian stretch/main amd64 python3-wheel all 0.29.0-2 [51.8 kB]
Get:32 http://deb.debian.org/debian stretch/main amd64 python3-xdg all 0.25-4 [35.7 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 45.2 MB in 0s (69.9 MB/s)
Selecting previously unselected package libapparmor1:amd64.
(Reading database ... 
(Reading database ... 5%
(Reading database ... 10%
(Reading database ... 15%
(Reading database ... 20%
(Reading database ... 25%
(Reading database ... 30%
(Reading database ... 35%
(Reading database ... 40%
(Reading database ... 45%
(Reading database ... 50%
(Reading database ... 55%
(Reading database ... 60%
(Reading database ... 65%
(Reading database ... 70%
(Reading database ... 75%
(Reading database ... 80%
(Reading database ... 85%
(Reading database ... 90%
(Reading database ... 95%
(Reading database ... 100%
(Reading database ... 29375 files and directories currently installed.)
Preparing to unpack .../00-libapparmor1_2.11.0-3+deb9u2_amd64.deb ...
Unpacking libapparmor1:amd64 (2.11.0-3+deb9u2) ...
Selecting previously unselected package dbus.
Preparing to unpack .../01-dbus_1.10.26-0+deb9u1_amd64.deb ...
Unpacking dbus (1.10.26-0+deb9u1) ...
Selecting previously unselected package dpkg-dev.
Preparing to unpack .../02-dpkg-dev_1.18.25_all.deb ...
Unpacking dpkg-dev (1.18.25) ...
Selecting previously unselected package build-essential.
Preparing to unpack .../03-build-essential_12.3_amd64.deb ...
Unpacking build-essential (12.3) ...
Selecting previously unselected package libfakeroot:amd64.
Preparing to unpack .../04-libfakeroot_1.21-3.1_amd64.deb ...
Unpacking libfakeroot:amd64 (1.21-3.1) ...
Selecting previously unselected package fakeroot.
Preparing to unpack .../05-fakeroot_1.21-3.1_amd64.deb ...
Unpacking fakeroot (1.21-3.1) ...
Selecting previously unselected package libalgorithm-diff-perl.
Preparing to unpack .../06-libalgorithm-diff-perl_1.19.03-1_all.deb ...
Unpacking libalgorithm-diff-perl (1.19.03-1) ...
Selecting previously unselected package libalgorithm-diff-xs-perl.
Preparing to unpack .../07-libalgorithm-diff-xs-perl_0.04-4+b2_amd64.deb ...
Unpacking libalgorithm-diff-xs-perl (0.04-4+b2) ...
Selecting previously unselected package libalgorithm-merge-perl.
Preparing to unpack .../08-libalgorithm-merge-perl_0.08-3_all.deb ...
Unpacking libalgorithm-merge-perl (0.08-3) ...
Selecting previously unselected package libdbus-glib-1-2:amd64.
Preparing to unpack .../09-libdbus-glib-1-2_0.108-2_amd64.deb ...
Unpacking libdbus-glib-1-2:amd64 (0.108-2) ...
Selecting previously unselected package libpython3.5:amd64.
Preparing to unpack .../10-libpython3.5_3.5.3-1_amd64.deb ...
Unpacking libpython3.5:amd64 (3.5.3-1) ...
Selecting previously unselected package libpython3.5-dev:amd64.
Preparing to unpack .../11-libpython3.5-dev_3.5.3-1_amd64.deb ...
Unpacking libpython3.5-dev:amd64 (3.5.3-1) ...
Selecting previously unselected package libpython3-dev:amd64.
Preparing to unpack .../12-libpython3-dev_3.5.3-1_amd64.deb ...
Unpacking libpython3-dev:amd64 (3.5.3-1) ...
Selecting previously unselected package python-pip-whl.
Preparing to unpack .../13-python-pip-whl_9.0.1-2_all.deb ...
Unpacking python-pip-whl (9.0.1-2) ...
Selecting previously unselected package python3-cffi-backend.
Preparing to unpack .../14-python3-cffi-backend_1.9.1-2_amd64.deb ...
Unpacking python3-cffi-backend (1.9.1-2) ...
Selecting previously unselected package python3-crypto.
Preparing to unpack .../15-python3-crypto_2.6.1-7_amd64.deb ...
Unpacking python3-crypto (2.6.1-7) ...
Selecting previously unselected package python3-idna.
Preparing to unpack .../16-python3-idna_2.2-1_all.deb ...
Unpacking python3-idna (2.2-1) ...
Selecting previously unselected package python3-pyasn1.
Preparing to unpack .../17-python3-pyasn1_0.1.9-2_all.deb ...
Unpacking python3-pyasn1 (0.1.9-2) ...
Selecting previously unselected package python3-pkg-resources.
Preparing to unpack .../18-python3-pkg-resources_33.1.1-1_all.deb ...
Unpacking python3-pkg-resources (33.1.1-1) ...
Selecting previously unselected package python3-setuptools.
Preparing to unpack .../19-python3-setuptools_33.1.1-1_all.deb ...
Unpacking python3-setuptools (33.1.1-1) ...
Selecting previously unselected package python3-six.
Preparing to unpack .../20-python3-six_1.10.0-3_all.deb ...
Unpacking python3-six (1.10.0-3) ...
Selecting previously unselected package python3-cryptography.
Preparing to unpack .../21-python3-cryptography_1.7.1-3_amd64.deb ...
Unpacking python3-cryptography (1.7.1-3) ...
Selecting previously unselected package python3-dbus.
Preparing to unpack .../22-python3-dbus_1.2.4-1+b1_amd64.deb ...
Unpacking python3-dbus (1.2.4-1+b1) ...
Selecting previously unselected package python3.5-dev.
Preparing to unpack .../23-python3.5-dev_3.5.3-1_amd64.deb ...
Unpacking python3.5-dev (3.5.3-1) ...
Selecting previously unselected package python3-dev.
Preparing to unpack .../24-python3-dev_3.5.3-1_amd64.deb ...
Unpacking python3-dev (3.5.3-1) ...
Selecting previously unselected package python3-gi.
Preparing to unpack .../25-python3-gi_3.22.0-2_amd64.deb ...
Unpacking python3-gi (3.22.0-2) ...
Selecting previously unselected package python3-secretstorage.
Preparing to unpack .../26-python3-secretstorage_2.3.1-2_all.deb ...
Unpacking python3-secretstorage (2.3.1-2) ...
Selecting previously unselected package python3-keyring.
Preparing to unpack .../27-python3-keyring_10.1-1_all.deb ...
Unpacking python3-keyring (10.1-1) ...
Selecting previously unselected package python3-keyrings.alt.
Preparing to unpack .../28-python3-keyrings.alt_1.3-1_all.deb ...
Unpacking python3-keyrings.alt (1.3-1) ...
Selecting previously unselected package python3-pip.
Preparing to unpack .../29-python3-pip_9.0.1-2_all.deb ...
Unpacking python3-pip (9.0.1-2) ...
Selecting previously unselected package python3-wheel.
Preparing to unpack .../30-python3-wheel_0.29.0-2_all.deb ...
Unpacking python3-wheel (0.29.0-2) ...
Selecting previously unselected package python3-xdg.
Preparing to unpack .../31-python3-xdg_0.25-4_all.deb ...
Unpacking python3-xdg (0.25-4) ...
Setting up python-pip-whl (9.0.1-2) ...
Setting up python3-cffi-backend (1.9.1-2) ...
Setting up python3-crypto (2.6.1-7) ...
Setting up libdbus-glib-1-2:amd64 (0.108-2) ...
Setting up libpython3.5:amd64 (3.5.3-1) ...
Setting up python3-idna (2.2-1) ...
Setting up python3-xdg (0.25-4) ...
Setting up python3-keyrings.alt (1.3-1) ...
Setting up python3-six (1.10.0-3) ...
Setting up python3-wheel (0.29.0-2) ...
Setting up python3-pkg-resources (33.1.1-1) ...
Setting up python3-gi (3.22.0-2) ...
Setting up libpython3.5-dev:amd64 (3.5.3-1) ...
Setting up python3-pyasn1 (0.1.9-2) ...
Setting up dpkg-dev (1.18.25) ...
Processing triggers for libc-bin (2.24-11+deb9u3) ...
Setting up libapparmor1:amd64 (2.11.0-3+deb9u2) ...
Setting up libfakeroot:amd64 (1.21-3.1) ...
Setting up python3-pip (9.0.1-2) ...
Setting up libalgorithm-diff-perl (1.19.03-1) ...
Setting up dbus (1.10.26-0+deb9u1) ...
invoke-rc.d: could not determine current runlevel
invoke-rc.d: policy-rc.d denied execution of start.
Setting up python3-setuptools (33.1.1-1) ...
Setting up python3.5-dev (3.5.3-1) ...
Setting up libpython3-dev:amd64 (3.5.3-1) ...
Setting up python3-cryptography (1.7.1-3) ...
Setting up python3-dbus (1.2.4-1+b1) ...
Setting up build-essential (12.3) ...
Setting up python3-dev (3.5.3-1) ...
Setting up fakeroot (1.21-3.1) ...
update-alternatives: using /usr/bin/fakeroot-sysv to provide /usr/bin/fakeroot (fakeroot) in auto mode
Setting up libalgorithm-merge-perl (0.08-3) ...
Setting up libalgorithm-diff-xs-perl (0.04-4+b2) ...
Setting up python3-secretstorage (2.3.1-2) ...
Setting up python3-keyring (10.1-1) ...
Processing triggers for libc-bin (2.24-11+deb9u3) ...
$ pip3 install requests
Collecting requests
  Downloading https://files.pythonhosted.org/packages/65/47/7e02164a2a3db50ed6d8a6ab1d6d60b69c4c3fdf57a284257925dfc12bda/requests-2.19.1-py2.py3-none-any.whl (91kB)
Collecting chardet<3.1.0,>=3.0.2 (from requests)
  Downloading https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl (133kB)
Collecting idna<2.8,>=2.5 (from requests)
  Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB)
Collecting certifi>=2017.4.17 (from requests)
  Downloading https://files.pythonhosted.org/packages/7c/e6/92ad559b7192d846975fc916b65f667c7b8c3a32bea7372340bfe9a15fa5/certifi-2018.4.16-py2.py3-none-any.whl (150kB)
Collecting urllib3<1.24,>=1.21.1 (from requests)
  Downloading https://files.pythonhosted.org/packages/bd/c9/6fdd990019071a4a32a5e7cb78a1d92c53851ef4f56f62a3486e6a7d8ffb/urllib3-1.23-py2.py3-none-any.whl (133kB)
Installing collected packages: chardet, idna, certifi, urllib3, requests
  Found existing installation: idna 2.2
    Not uninstalling idna at /usr/lib/python3/dist-packages, outside environment /usr
Successfully installed certifi-2018.4.16 chardet-3.0.4 idna-2.7 requests-2.19.1 urllib3-1.23
$ python3 -m unittest tests/test_openweather.py
.
----------------------------------------------------------------------
Ran 1 test in 0.161s

OK
Job succeeded
```

やっと通った…。

# おわりに
環境を整えるって、大変。昔、自分でやったはずだけど、ほぼ忘れてる。どういう依存関係になっているかとか、見直せるところも、CI使ったテストのいいところなんかも。汚染されてない環境で動くっていう安心感も出てくる。

# 参考
[Test and Deploy a python application with GitLab CI/CD | GitLab](https://docs.gitlab.com/ee/ci/examples/test-and-deploy-python-application-to-heroku.html)