PyFes テスティングハンズオン

やること

  • ユニットテスト
  • ダミーやモックの使い方
  • カバレージとか

準備

ツール

$ pip install nose
$ pip install mock
$ pip install coverage
$ pip install tox

テスト対象

好きな方法で取得

ユニットテスト

ユニットテストの実行方法

$ nosetests

setup.cfg にオプション設定してあるため、 doctest も実行されます。

[nosetests]
with-doctest = 1

カバレージを測る

noseはcoverageを利用できるプラグインを同梱しています。 --with-covarage オプションでカバレージ測定を有効にできます。 --cover-package オプションで測定対象を設定できます。

$ nosetests --with-coverage --cover-package=aodag.tasks

毎回指定するのが面倒であれば、 setup.cfg にオプションを指定します。

[nosetests]
with-covarge = 1
cover-package = aodag.tasks

ダミーを使う

たとえば ArgumentParser.parse_arg の結果を使う関数のテストをする場合に、 わざわざ parse_arg を呼ぶ必要はありません。

以下のようなダミーを渡してあげれば十分です。

class DummyArgs(object):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

mock の使い方

input 関数や datetime.now などは、実行ごとに結果が変わります。 mockを使って、決まった内容を返させるようにします。

@mock.patch('test_under_the_module.datetime'):
def test_it(mock_datetime):
    mock_datetime.now.return_value = datetime(2012, 3, 17)

    # some test
@mock.patch('test_under_the_module.input'):
def test_it(mock_input):
    mock_input.side_effect = ['first input', 'second input']

    # some test

toxを使う

tox.ini ファイルで環境設定します。

[tox]
envlist = py27

[testenv]
deps = nose coverage
commands = nosetests

tox コマンドを実行します。

$ tox

課題

  • aodag.tasks は Python3用に書かれています。Python2で動くように修正してください。
  • aodag/tasks/tests.py を追加して、 unittest のテストケースにしてください。
  • coverage を 100% にしてください。
  • toxを使って、完全に隔離された環境のテストを実行してください。

おまけ

テストのひながた

import unittest

class SampleTests(unittest.TestCase):

    def _callFUT(self, *args, **kwargs):
        from module_under_the_test import function_under_the_test
        return function_under_the_test(*args, **kwargs)

    def test_it(self):
        result = self._callFUT()
        self.assertTrue(result)