空飛ぶロボットのつくりかた

ロボットをつくるために必要な技術をまとめます。ロボットの未来についても考えたりします。

pythonのテストを書いてみる

unittest

Robot and Animal

roboani.py

class Robot:
    def get_name(self):
        return "robot"
    def get_legs(self):
        return 2

class Animal:
    def get_name(self):
        return "animal"
    def get_legs(self):
        return 4

def calc_roboani_legs(robot,animal,heads,legs):
    robo_l = robot.get_legs()
    ani_l = animal.get_legs()
    robot_name = robot.get_name()
    animal_name = animal.get_name()
    animal_num = (legs - (robo_l*heads)) // (ani_l-robo_l)
    robot_num = heads - animal_num
    print "------"
    print "head",heads,"leg",legs
    print robot_num,animal_num
    return robot_num,animal_num

if __name__ == '__main__':
    calc_roboani_legs(Robot(),Animal(),heads=10,legs=28)

Test

test_roboani.py

import unittest, roboani

class TestRobotAnimal(unittest.TestCase):

    def setUp(self):
        self.robot = roboani.Robot()
        self.animal = roboani.Animal()

    def tearDown(self):
        pass

    def test_legs(self):
        self.assertEqual(self.robot.get_legs(),2,"leg num")
        self.assertEqual(self.animal.get_legs(),4,"leg num")

    
    def test_roboani(self):
        robot, animal = roboani.calc_roboani_legs(
            self.robot,self.animal,
            heads = 10, legs = 28)

        self.assertEqual((robot,animal) ,(6,4), "robot animal calc")

テスト実行

$ python -m unittest test_roboani

結果

.------
head 10 leg 28
6 4
.
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

mocktest

RobotDataBaseConnect

# -*- coding:utf-8 -*-

import unittest
from mock import Mock, patch

class DataBaseConnect(object):
    def __init__(self):
        pass

    def find(self, param):
        print('find ' + param)

class CalculationMovement(object):
    def __init__(self, data):
        self.__dataget = data

    def execute(self):
        return self.__dataget.find('param')

calc = CalculationMovement(DataBaseConnect())
calc.execute()

# ---------------- mock test --------------------------#

class CalculationModelTestCase(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_execute_1(self):
        mock_test = Mock()  
        mock_test.find.return_value = 'mock_test'
        test_obj = CalculationMovement(mock_test)
        self.assertEqual('mock_test', test_obj.execute())
        self.assertEqual(mock_test.find.call_count, 1)
        self.assertEqual(list(mock_test.find.call_args_list[0]),
                         [('param',),{}])

    def test_execute_2(self):
        DataBaseConnect.find = Mock(return_value='mock_test')
        mock_test = DataBaseConnect()
        test_obj = CalculationMovement(mock_test)
        self.assertEqual('mock_test', test_obj.execute())

    def test_execute_3(self):
        with patch('__main__.DataBaseConnect') as mock_test:
            mock_test.find.return_value = 'with_mock_test'
            test_obj = CalculationMovement(mock_test)
            self.assertEqual('with_mock_test', test_obj.execute())

unittest.main()

結果

find param
...
----------------------------------------------------------------------
Ran 3 tests in 0.002s

OK

参考:

PythonでMockを使ったユニットテスト - 工作とかプログラミングとか

python - How to unittest that a thread is spawned? - Stack Overflow

サンプルでみる Python の Mock ライブラリ Mox の使い方 | CUBE SUGAR STORAGE

EasyMockでSocketクラスのモックを作る - Yのはてな

Pythonのテストコードでmockを使ってみた | Developers.IO

Pythonのコードをきれいに書くためのTips | TRIVIAL TECHNOLOGIES 4 @ats のイクメン日記

http://momijiame.tumblr.com/post/22379282563/モックオブジェクトフレームワーク-pymox-を使って-python-のテストを書く

標準ライブラリのunittestで例外の発生を確認するテスト - podhmoの日記

unit testing - How do you test that a Python function throws an exception? - Stack Overflow