最近Codecovというサービスを使ってカバレッジを計測しているのですが、テストをしようというモチベーションが上がる良いサービスだと思ったので紹介したいと思います。
Codecovとは
Codecovについて簡単に説明すると、コードのカバレッジを計測し、可視化したりslackに通知したり出来るサービスです。似たようなサービスだとcoverallsなんかがあります。
Codevcovはテストされていないコードを行単位で色づけしたり。
ファイルやディレクトリ単位でカバレッジを計測したり。
GitHubと連携させてプルリクにカバレッジがどう変化したかをコメントしてくれたり。
Slackと連携してカバレッジの差分が閾値を越えたら警告することができます。
カバレッジがとれる言語も幅広く、Java・Ruby・PHP・Python・Goなどメジャーな言語は一通りサポートされますし、サンプルコードも公式のリポジトリで手厚くサポートされています。
また設定をymlで書くことが可能で、カバレッジが閾値以下になるプルリクはマージできないようにしたり、結果をSlackなどに通知するための設定を書くことが出来ます。
基本的なカバレッジを可視化するサービスとしては十分な機能をそろえている言えると思います。
またCodecovの良いところとしてFreeプランでPrivateリポジトリが一つ無料で使用できることです。会社で使用するときまずはこの無料枠で試してみて、設定などがこなれてきたら課金して他のリポジトリでも使えるようにするとよさそうです。
Codecovのはじめかた
PythonでのCodecovのはじめ方を解説していきます。今回はDjangoのアプリケーションでテストをしていきます。
サンプルリポジトリは次のURLです。
テスト対象のコード
最初にテスト対象のコードを示します。
from django.db import models
class Todo(models.Model):
text = models.CharField(max_length=255, null=None)
is_done = models.BooleanField(default=False, null=None)
created_at = models.DateTimeField(auto_now_add=True)
@classmethod
def create(cls, **params):
return cls.objects.create(**params)
@classmethod
def get_list_all(cls):
return list(cls.objects.all())
@classmethod
def get_by_id(cls, id):
try:
return cls.objects.get(id=id)
except cls.DoesNotExist:
return None
Djangoのモデルです。Todoモデルを作成しました。
from modules.todo.models.todo import Todo
def create(**params):
return Todo.create(**params)
def get_all():
return Todo.get_list_all()
def get_by_id(self, id):
return Todo.get_by_id(id)
Todoモデルを操作するサービスモデルです。
from django.test import TestCase
from modules.todo import service as todo_sv
from modules.todo.models.todo import Todo
class TodoServiceTests(TestCase):
def test_create(self):
todo_sv.create(text='hoge', is_done=False)
todo_list = Todo.objects.all()
self.assertEqual(len(todo_list), 1)
def test_get_all(self):
todo_sv.create(text='hoge', is_done=False)
todo_list = todo_sv.get_all()
self.assertEqual(len(todo_list), 1)
サービスモデルをテストするテストコードです。上記のコードだと create
と get_all
はテストされていますが get_by_id
はテストされていません。
この状態でカバレッジを計測すべく準備をしていきます。
codecovでカバレッジを計測するための準備
codecovを使用してカバレッジを計測していきたいと思います。
まずは実際にカバレッジを計測するcoverage.py
と、codecovに計測結果を送信するcodecov
をインストールします。
$ pipenv install -d coverage codecov
coverage.py
はdjangoのテストと一緒に使うことで .coverage
ファイルを作成します。このファイルはテストのカバレッジ結果が保存されています。
codecov
コマンドはこのファイルを使用してcodecovに情報を送信します。
カバレッジを計測し、それをcodecovに送る流れをCIに組み込みます。今回はCircleCIを使用して行います。
CircleCIの設定を次に示します。
version: 2
jobs:
build:
docker:
- image: circleci/python:3.7.1
working_directory: ~/repo
steps:
- checkout
- restore_cache:
keys:
- cache-{{ checksum "Pipfile.lock" }}
- cache-
- run:
name: Install dependencies
command: pipenv sync --dev
- save_cache:
key: cache-{{ checksum "Pipfile.lock" }}
paths:
- ~/.local
- ~/.cache
- run: pipenv run coverage run --source='.' ./manage.py test
- run: pipenv run codecov
CIのステップにカバレッジを計測するステップとそれを送るステップを書いています。
次にトークンをCIにセットします。トークンはcodecovのダッシュボードからプロジェクトを追加するときに閲覧することが出来ます。
ここまで設定してCIを実行するとCodecovでカバレッジ結果を閲覧することが出来ます。
Codecovでは次のように表示されます。
テストされていない get_by_id
のコードが赤くなっていることが分かります。
これ以降プルリクを投げるたびにプルリクにコメントされ、カバレッジの結果を毎回見ることが出来るようになります。
プルリクにはコードの量に応じた大きさの四角が描かれた画像が表示されます。その部分のカバレッジが下がっていると赤く表示されます。今回のプルリクにはメソッドを追加してテストは書いていなかったためカバレッジが下がり赤く表示されることが分かります。
可視化されることで上がるテストへのモチベーション
Codecovを使うことでカバレッジをグラフィカルに表示し、プルリクにもわかりやすくコメントを入れてくれることを見てきました。Codecovを使わなくても coverage.py
を使えば%表示でカバレッジを見ることは出来ますが、グラフィカルに表示することで実際にテストされていないコードを見ることも出来ますし、カバレッジが減っていることも色でわかりやすく表示されます。
また自分の出したプルリクにコメントとしてカバレッジの増減を表示することにより、テストへのモチベーションが上がります。自分出したプルリクに、カバレッジが減少したファイルが赤く表示されたら緑にしたくなる気持ちがわき、テストを書くことが楽しくなるのがポイントです。
とはいえただテストを書くだけでは品質向上には繋がらないので、テストの描き方についてはレビューが必要でしょう。
まとめ
Codecovについて簡単に紹介していきました。プルリクへのコメントやFreeプランでprivateなリポジトリが一つ使えるというところが魅力的です。
Codecovでカバレッジを常に計測し十分にテストされたプロダクト開発を行っていきたいところです。