問題陳述
。我正試圖為一個函式建立單元測驗,該函式對其收到的輸入執行一系列算術運算。這些操作是在函式之外配置的(在本例中是在一個包的常量中)。
我的問題是:我可以撰寫應該通過的測驗,但如果外部配置發生變化,測驗就會中斷,或者測驗主要是重復待測函式中的代碼。
我可以想到的撰寫測驗的兩種方式是:
一個 "假定 "了特定配置的測驗。問題是,這個測驗很脆弱,如果我改變了配置就會停止作業。(見下面的 test_example1) 我可以建立一個測驗,使用配置來計算預期結果。問題是,首先,測驗依賴于函式之外的配置常量,其次,測驗的代碼與被測驗的代碼非常相似,這感覺不對。(見下面的test_example2) 你能幫助我找出對一個執行配置在它之外的操作的函式進行單元測驗的正確方法嗎?
uj5u.com熱心網友回復: 這有點見仁見智,但與其嚴格依賴全域變數,我可能會讓你的函式( 例如 這樣做有兩個好處。 為了測驗,你可以為這個資料傳入一些假值(據推測,這些假值將比真實資料更小、更簡單),然后在較簡單的資料下測驗一個已知的正確輸出。
另一個優點是它使您的代碼在總體上更具擴展性。
如果您不想這樣做,另一個例子(因為您正在使用 在這種情況下,你將把你的測驗寫成: 這本質上是同樣的事情,但給出了一種方法,在不改變默認值的情況下,針對(臨時分配的)新配置測驗你的函式。
標籤:
示例代碼
import unittest
import operator
OPS = {' ': operator.add,
'-':operator.sub}。
DIRECTIVES = {'calculated_field':[(' ','field1'],
(' ','field2')]}。
def example(input_dict)。
output_dict = {}
for item,calcs in DIRECTIVES.items()。
output_dict[item] = 0
for operation, field in calcs:
output_dict[item] = OPS[operation](output_dict[item],input_dict[field])
return output_dict
class TestExample(unittest.TestCase)。
item1 = 'field1'/span>
value1 = 10: item1 = 'field1'.
item2 = 'field2'20
item3 = 'field3'
value3 = 5
def setUp(self)。
self.input_dict = {self.item1:self.value1,
self.item2:self.value2,
self.item3:self.value3}。
def test_example_option1(self)。
expected_result = {'calculated_field':self.value1 self.value2}.
actual_result = example(self.input_dict)
self.assertDictEqual(expected_result,actual_result)
def test_example_option2(self)。
expected_result = {}。
for item,calcs in DIRECTIVES.items() 。
expected_result[item] =0
for operation, field in calcs:
expected_result[item] = OPS[operation](expected_result[item],self.input_dict[field])
actual_result = example(self.input_dict)
self.assertDictEqual(expected_result,actual_result)
example(),在這種情況下,我假設)允許傳入它所依賴的外部資料的可選重寫。
def example(ops=OPS, directives=DIRECTIVES) 。
...
unittest 模塊)是使用 unittest.mock.patchclass TestExample(...)。
@patch('yourmodule.OPS', TEST_OPS)
@patch('yourmodule.DIRECTIVES', TEST_DIRECTIVES)
def text_example_option(self)。
# call example() and test against a known--good value.
# given TEST_OPS and TEST_DIRECTIVES.
