先問題,然後解釋一下是否有興趣。在python中生成py.test測試
在py.test的上下文中,我如何從一小組測試函數模板中生成一大組測試函數?
喜歡的東西:
models = [model1,model2,model3]
data_sets = [data1,data2,data3]
def generate_test_learn_parameter_function(model,data):
def this_test(model,data):
param = model.learn_parameters(data)
assert((param - model.param) < 0.1)
return this_test
for model,data in zip(models,data_sets):
# how can py.test can see the results of this function?
generate_test_learn_parameter_function(model,data)
說明:
我想很難進入單元測試。我編寫'科學',因爲我編寫的代碼在數學上是複雜的,但從編程的角度來看並不是那麼糟糕,也就是說我可能需要測試五個函數。我來自'科學'意味着我對單元測試很新,但已經讓我的CS夥伴確信它是「事情要做」。
我正在寫的代碼需要一個模型結構,一些數據,並學習模型的參數。所以我的單元測試包括一堆模型結構和預先生成的數據集,然後在每個結構+數據上完成一組約5個機器學習任務。
因此,如果我手工編寫代碼,我需要爲每個任務的每個模型測試一次。每次我想出一個新模型時,我需要複製並粘貼5個任務,更改我指向的哪個pickled結構+數據。這對我來說感覺像是不好的練習。理想情況是我想要的是5個模板函數,它們定義了我的5個任務中的每一個,然後爲我指定的結構列表吐出測試函數。
使用Google搜索將我帶到a)工廠或b)關閉,這兩者都會讓我的大腦更加生動,並且暗示我必須有一個更簡單的方法,因爲這個問題必須由合適的程序員經常面對。那麼在那裏?
編輯:所以這裏是如何解決這個問題!
def pytest_generate_tests(metafunc):
if "model" in metafunc.funcargnames:
models = [model1,model2,model3]
for model in models:
metafunc.addcall(funcargs=dict(model=model))
def test_awesome(model):
assert model == "awesome"
這將對我的模型列表中的每個模型應用test_awesome測試!謝謝@dfichter!
(注:斷言總是通過,順便說一句)
一般來說這是一個壞主意,像動態生成測試代碼。因爲那麼你必須爲測試代碼編寫測試等''複製並粘貼5個任務'我認爲這表明不是生成新代碼或複製粘貼,而是可以找到你的函數可以測試的共同點,而不必知道它們究竟是什麼正在測試。 – Falmarri
目前我正在編寫看起來像def test_learn的測試:對於模型中的模型:assert(錯誤<閾值)。但是這意味着測試可能會在任何一個模型上失敗,而我希望有一個測試失敗了一個模型和另一個模型的單獨測試,即使它是相同的機器學習函數。 –
@Falmarri:http://en.wikipedia.org/wiki/Copy_and_paste_programming請避免幾乎所有費用。 – lpapp