pythonのテストを書いてみる2
数値微分
プロダクションコード
# -*- coding:utf-8 -*- # 2次関数の数値微分を行うクラス class Diff: # 2次関数 def f(self,x): y = x**2 return y # 数値微分 def numerical_diff(self,f,x,dx): if dx == 0: raise ValueError('division by zero') else: x_diff = (f(x+dx)-f(x-dx))/(2*dx) return x_diff if __name__ == '__main__': diff = Diff() print diff.numerical_diff(diff.f,3,0.001)
テストコード
# -*- coding:utf-8 -*- import unittest, numerical_diff class TestDiff(unittest.TestCase): # 前処理 def setUp(self): self.diff = numerical_diff.Diff() # 後片付け def tearDowm(self): pass # 3の2乗のテスト def test_func1(self): self.assertEqual(self.diff.f(3),9) # 4の2乗のテスト def test_func2(self): self.assertEqual(self.diff.f(4),16) # 数値微分ができているかのテスト def test_numerical_diff(self): self.assertAlmostEqual(self.diff.numerical_diff(self.diff.f,3,0.001),6.0, delta=1e-8) self.assertEqual(round(self.diff.numerical_diff(self.diff.f,3,0.001)),6.0) # ダメな例。検証したい値に操作を加えている。 # 0で割られたときの例外のテスト def test_numerical_diff_zero_error(self): with self.assertRaises(ValueError) as cm: self.diff.numerical_diff(self.diff.f,3,0.0) exception = cm.exception self.assertEqual(exception.message, 'division by zero')
文字の変換
プロダクションコード
#-*- coding:utf-8 -*- import re class StringUtils: def to_snake_case(self,text): if len(text) is 0: raise ValueError('snake case error') else: snake = re.sub("([A-Z])",lambda x:"_" + x.group(1).lower(),text) return re.sub("^_","",snake) def to_camel_case(self,text): if len(text) is 0: raise ValueError('camel case error') else: camel = re.sub("_(.)",lambda x:x.group(1).upper(),text) return re.sub("^(.)",lambda x:x.group(1).upper(),camel) if __name__ == '__main__': camel = "CamelCase" snake = "snake_case" string_utils = StringUtils() print string_utils.to_snake_case(camel) print string_utils.to_camel_case(snake)
参考: lambda式はすごく面白い - 元理系院生の新入社員がPythonとJavaで色々頑張るブログ
【技術】pythonでのキャメルケースとスネークケースの変換について - エンジニアリングとお金の話
Pythonで文字列を置換する:replace(), re.sub() | UX MILK
テストコード
# -*- coding:utf-8 -*- import unittest, string_utils class TestStringUtils(unittest.TestCase): # 前処理 def setUp(self): self.su = string_utils.StringUtils() # 後片付け def tearDowm(self): pass # camel->snake, snake->camelへの変換テスト def test_to_snake_case1(self): self.assertEqual(self.su.to_snake_case("CamelCase"),"camel_case") def test_to_snake_case2(self): self.assertEqual(self.su.to_snake_case("camelCase"),"camel_case") def test_to_snake_case3(self): self.assertEqual(self.su.to_snake_case("camelcase"),"camelcase") def test_to_camel_case1(self): self.assertEqual(self.su.to_camel_case("snake_case"),"SnakeCase") def test_to_camel_case2(self): self.assertEqual(self.su.to_camel_case("Snake_Case"),"SnakeCase") def test_to_camel_case3(self): self.assertEqual(self.su.to_camel_case("SnakeCase"),"SnakeCase") # 文字がない場合の例外のテスト def test_snake_error(self): with self.assertRaises(ValueError) as cm: self.su.to_snake_case("") exception = cm.exception self.assertEqual(exception.message, 'snake case error') def test_camel_error(self): with self.assertRaises(ValueError) as cm: self.su.to_camel_case("") exception = cm.exception self.assertEqual(exception.message, 'camel case error')
カウント
プロダクションコード
# -*- coding:utf-8 -*- class Counter: def __init__(self): self.count = 0 def increment(self): self.count += 1 return self.count if __name__ == '__main__': counter = Counter() for i in range(10): print counter.increment()
テストコード
# -*- coding:utf-8 -*- import unittest, counter class TestCounter(unittest.TestCase): # 前処理 def setUp(self): self.ct = counter.Counter() # 後片付け def tearDowm(self): pass # カウントできているかのテスト def test_count_init(self): self.assertEqual(self.ct.increment(),1) def test_count_2(self): self.ct.increment() self.assertEqual(self.ct.increment(),2) def test_count_100(self): for i in range(100): self.ct.increment() self.assertEqual(self.ct.increment(),101)
偶数判定
プロダクションコード
# -*- coding:utf-8 -*- class NumberUtils: def even(self,num): return num % 2 == 0 if __name__ == '__main__': number = NumberUtils() print number.even(2) print number.even(3)
テストコード
# -*- coding:utf-8 -*- import unittest, number_utils class TestStringUtils(unittest.TestCase): # 前処理 def setUp(self): self.nu = number_utils.NumberUtils() # 後片付け def tearDowm(self): pass def test_even(self): self.assertTrue(self.nu.even(2)) def test_odd(self): self.assertFalse(self.nu.even(3))
物品管理
プロダクションコード
# -*- coding:utf-8 -*- class Item: def __init__(self,name,price): self.name = name self.price = price def get_name(self): return self.name def get_price(self): return self.price class ItemStock: def __init__(self): self.item_dic = {} def add(self, item): num = self.item_dic.get(item.name) if num is None: num = 0 num +=1 self.item_dic[item.name] = num def get_num(self, item): num = self.item_dic.get(item.name) if num is not None: return num else: return 0 if __name__ == '__main__': drone = Item("drone",6800) robot = Item("robot",10000) item_stock = ItemStock() item_stock.add(drone) item_stock.add(drone) item_stock.add(robot) print drone.get_name(),drone.get_price() print item_stock.get_num(drone) print robot.get_name(),robot.get_price() print item_stock.get_num(robot)
テストコード
# -*- coding:utf-8 -*- import unittest, item_stock class TestItemSocket(unittest.TestCase): # 前処理 def setUp(self): self.itemstock = item_stock.ItemStock() self.drone = item_stock.Item("drone",6800) self.robot = item_stock.Item("robot",10000) # 後片付け def tearDowm(self): pass def test_init(self): self.assertEqual(self.itemstock.get_num(self.drone),0) def test_one_object_add_1(self): self.itemstock.add(self.drone) self.assertEqual(self.itemstock.get_num(self.drone),1) def test_one_object_add_2(self): self.itemstock.add(self.drone) self.itemstock.add(self.drone) self.assertEqual(self.itemstock.get_num(self.drone),2) def test_two_object_add_2_and_1(self): self.itemstock.add(self.drone) self.itemstock.add(self.drone) self.itemstock.add(self.robot) self.assertEqual(self.itemstock.get_num(self.drone),2) self.assertEqual(self.itemstock.get_num(self.robot),1)
スレッド
(TBD)
プロダクションコード
テストコード
FizzBuzz
プロダクションコード
# -*- coding:utf-8 -*- class FizzBuzz: def __init__(self): pass def create_fizz_buzz_list(self,size): list = [] for i in range(1,size): if i % 15 == 0: list.append("FizzBuzz") elif i % 3 == 0: list.append("Fizz") elif i % 5 == 0: list.append("Buzz") else: list.append(str(i)) return list if __name__ == '__main__': fizzbuzz = FizzBuzz() print fizzbuzz.create_fizz_buzz_list(20)
テストコード
# -*- coding:utf-8 -*- import unittest, FizzBuzz class TestFizzBuzz(unittest.TestCase): # 前処理 def setUp(self): self.cfb = FizzBuzz.FizzBuzz() # 後片付け def tearDowm(self): pass # FizzBuzzのテスト def test_fizz_buzz(self): actual = self.cfb.create_fizz_buzz_list(17) self.assertEqual(len(actual),16) self.assertEqual(actual[0],"1") self.assertEqual(actual[1],"2") self.assertEqual(actual[2],"Fizz") self.assertEqual(actual[3],"4") self.assertEqual(actual[4],"Buzz") self.assertEqual(actual[5],"Fizz") self.assertEqual(actual[6],"7") self.assertEqual(actual[7],"8") self.assertEqual(actual[8],"Fizz") self.assertEqual(actual[9],"Buzz") self.assertEqual(actual[10],"11") self.assertEqual(actual[11],"Fizz") self.assertEqual(actual[12],"13") self.assertEqual(actual[13],"14") self.assertEqual(actual[14],"FizzBuzz") self.assertEqual(actual[15],"16")
ゴリゴリすぎるので、カスタムMatcherでも書いてみたい。。。 (TBD)
カスタムMatcher: Python: Matcher フレームワーク PyHamcrest を使ってみる | CUBE SUGAR STORAGE GitHub - hamcrest/PyHamcrest: Hamcrest matchers for Python
参考
Python コメント、Pydoc - @//メモ Pythonで学ぶ 基礎からのプログラミング入門 (32) マルチスレッド処理を理解しよう(前編) | マイナビニュース