2013年12月15日日曜日

開発環境

初めてのコンピュータサイエンス(Jennifer CampbellPaul GriesJason MontojoGreg Wilson(著)長尾 高弘(翻訳))の12章(各種ツール)、12.7(練習問題)、12-11.を解いてみる。

12.7(練習問題)、12-11.

リストは可変性(ミュータブル)を持ち、remove_all関数でリストの要素が変更されるので、一つの関数をテストすると、リストが変更され、他のテストでは元のリストではなく、変更されたリストがテストされることになり、誤ったテスト結果を得ることになる。(問題の例では、one_item_listが2回テストされているので、2つ目のテストでは、one_item_listは既に取り除きたい要素が取り除かれたリストをテストすることになる。)

正しいテスト結果を得る為には、リストをスライス等でコピーしてからテストするように変更すればいい。

コード(BBEdit)

sample.py

#!/usr/bin/env python3.3
#-*- coding: utf-8 -*-

import nose

def remove_all(items, item):
    items[:] = list(filter(lambda x: x != item, items))

# 元の誤りがあるテスト
one_item_list1 = ['He']

# 誤り
def test_remove_from_one_item_list1():
    remove_all(one_item_list1, 'He')
    assert len(one_item_list1) == 0

def test_remove_something_else1():
    '''既にone_item_listは'He'が取り除かれている'''
    remove_all(one_item_list1, 'Pb')
    assert len(one_item_list1) == 1

# 修正
empty_list = []
one_item_list = ['He']
multi_item_list = ['Ne', 'Ar', 'He', 'He']

def test_remove_from_empty():
    temp = empty_list[:]
    remove_all(temp, 'He')
    assert len(temp) == 0

def test_remove_from_one_item_list():
    temp = one_item_list[:]
    remove_all(temp, 'He')
    assert len(temp) == 0

def test_remove_something_else():
    temp = one_item_list[:]
    remove_all(temp, 'Pb')
    assert len(temp) == 1

def test_remove_multiple():
    temp = multi_item_list[:]
    remove_all(temp, 'He')
    assert len(temp) == 2

if __name__ == '__main__':
    nose.runmodule()

入出力結果(Terminal)

$ ./sample.py
.F....
======================================================================
FAIL: 既にone_item_listは'He'が取り除かれている
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "./sample.py", line 20, in test_remove_something_else1
    assert len(one_item_list1) == 1
AssertionError

----------------------------------------------------------------------
Ran 6 tests in 0.002s

FAILED (failures=1)
$

0 コメント:

コメントを投稿