pytestでcoverageを測りたい。そうすれば、色々スピードアップする予感がある。
とりあえず、やってみた話。
- venv環境を作る
- pytestでテストできるようにする
- pytest-covを使う
- カバレッジ下げてみる
- djangoでpytestでカバレッジを図る
- djangoの準備
- pytestでdjangoをテスト
- pytest + django + coverage
- 終わり
venv環境を作る
$ python3.6 -m venv coverage $ . coverage/bin/activate (coverage) $ python -V Python 3.6.5
pytestでテストできるようにする
とりあえず、pytestでテストできるようにしとく。
(coverage) $ pip install pytest (coverage) $ pip freeze | grep pytest pytest==3.5.1
test_my_module.py
import my_module def test_case_1(): source = 1 result = my_module.function1(source) assert str(source) == result
my_module.py
def function1(x): return str(x)
(coverage) $ pytest test_my_module.py ===================================== test session starts ===================================== platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 rootdir: /Users/mtb/work/coverage/work, inifile: collected 1 item test_my_module.py . [100%] ================================== 1 passed in 0.00 seconds ===================================
OK
pytest-covを使う
まず、インストールする。
(coverage) $ pip install pytest-cov (coverage) $ pip freeze | grep pytest-cov pytest-cov==2.5.1
そして実行する。
(coverage) $ py.test --cov my_module =============================================================== test session starts =============================================================== platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 rootdir: /Users/mtb/work/coverage/work, inifile: plugins: cov-2.5.1 collected 1 item test_my_module.py . [100%] ---------- coverage: platform darwin, python 3.6.5-final-0 ----------- Name Stmts Miss Cover ---------------------------------- my_module.py 2 0 100% ============================================================ 1 passed in 0.02 seconds =============================================================
便利だ。
カバレッジ下げてみる
あえて、カバレッジが下がりそうなことをしてみる。
def function1(x): return str(x) def function2(x): if x == 1: return True return False
(coverage) $ py.test --cov my_module =============================================================== test session starts =============================================================== platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 rootdir: /Users/mtb/work/coverage/work, inifile: plugins: cov-2.5.1 collected 1 item test_my_module.py . [100%] ---------- coverage: platform darwin, python 3.6.5-final-0 ----------- Name Stmts Miss Cover ---------------------------------- my_module.py 6 3 50% ============================================================ 1 passed in 0.02 seconds =============================================================
OK. カバレッジ下がった。
テストを追加する。
import my_module def test_case_1(): source = 1 result = my_module.function1(source) assert str(source) == result def test_case_2(): source = 1 result = my_module.function2(source) assert result == True def test_case_3(): source = 2 result = my_module.function2(source) assert result == False
(coverage) $ py.test --cov my_module =============================================================== test session starts =============================================================== platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 rootdir: /Users/mtb/work/coverage/work, inifile: plugins: cov-2.5.1 collected 3 items test_my_module.py ... [100%] ---------- coverage: platform darwin, python 3.6.5-final-0 ----------- Name Stmts Miss Cover ---------------------------------- my_module.py 6 0 100% ============================================================ 3 passed in 0.03 seconds =============================================================
100%になった。
djangoでpytestでカバレッジを図る
djangoでもカバレッジ測りたい。というわけで測ってみる。
djangoの準備
django 初心者だから1.11にしとく。
(coverage) $ pip install django==1.11
(coverage) $ django-admin startproject myproject (coverage) $ cd myproject/ (coverage) $ ls manage.py myproject
そして、雑なレスポンスを返すように修正。
myproject/url.py
from django.conf.urls import url from django.contrib import admin from django.http.response import HttpResponse def index(request): return HttpResponse('Hello Djano') urlpatterns = [ url(r'^', index), url(r'^admin/', admin.site.urls), ]
雑に動作確認して動くことを確認。d
(coverage) $ python manage.py runserver
$ curl http://localhost:8000 Hello Djano
pytestでdjangoをテスト
pytest-djangoをインストールする。バージョンは現時点の最新版。
(coverage) $ pip install pytest-django (coverage) $ pip freeze | grep pytest-django pytest-django==3.2.1
pytest.iniという設定ファイルを追加
[pytest] DJANGO_SETTINGS_MODULE = myproject.settings python_files = tests.py test_*.py *_tests.py
テストを追加。
myproject/tests.py
from django.test import TestCase, Client class IndexTest(TestCase): def test_http(self): client = Client() response = client.get('/') self.assertEqual(response.status_code, 200)
テストを実行。
(coverage) $ pytest =============================================================== test session starts =============================================================== platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 Django settings: myproject.settings (from ini file) rootdir: /Users/mtb/work/coverage/work/myproject, inifile: pytest.ini plugins: django-3.2.1, cov-2.5.1 collected 1 item myproject/tests.py . [100%] ============================================================ 1 passed in 0.20 seconds =============================================================
テストできた。
pytest + django + coverage
とりあえず指定したらできた。
(coverage) $ pytest --cov myproject =============================================================== test session starts =============================================================== platform darwin -- Python 3.6.5, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 Django settings: myproject.settings (from ini file) rootdir: /Users/mtb/work/coverage/work/myproject, inifile: pytest.ini plugins: django-3.2.1, cov-2.5.1 collected 1 item myproject/tests.py . [100%] ---------- coverage: platform darwin, python 3.6.5-final-0 ----------- Name Stmts Miss Cover ------------------------------------------- myproject/__init__.py 0 0 100% myproject/settings.py 18 0 100% myproject/tests.py 6 0 100% myproject/urls.py 6 0 100% myproject/wsgi.py 4 4 0% ------------------------------------------- TOTAL 34 4 88% ============================================================ 1 passed in 0.27 seconds =============================================================
ふむ。測れてそう。
ちなみに、coverageを図るパッケージは指定しないと、全範囲が対象になって、時間がかかるし、大量に出てくる。
終わり
とりあえず、djangoをpytest使ってcoverage測れるようにあった。
実際の仕事でもどんどん使って行こう。