[英]Randomly select functions
我正在編寫一個測試腳本,其中包含不同測試的不同功能。 我希望能夠隨機選擇要運行的測試。 我已經通過以下功能實現了這一目標......
test_options = ("AOI", "RMODE")
def random_test(test_options, control_obj):
ran_test_opt = choice(test_options)
if ran_test_opt.upper() == "AOI":
logging.debug("Random AOI Test selected")
random_aoi()
elif ran_test_opt.upper() == "RMODE":
logging.debug("Random Read Mode Test selected")
random_read_mode(control_obj)
但是,我希望在不必修改隨機測試選擇功能的情況下添加更多測試功能。 我想要做的就是在腳本中添加測試功能。 另外,我還想要一種方法來選擇哪個測試將包含在隨機選擇中。 這就是變量test_options的作用。 我將如何改變我的隨機生成函數來實現這一目標?
編輯:我解決了所有測試可能需要不同的參數,將它們全部包含在測試類中。 所有參數都將傳遞給init,測試函數將使用“self”引用它們。 當他們需要一個特定的變量時......
class Test(object):
"""A class that contains and keeps track of the tests and the different modes"""
def __init__(self, parser, control_obj):
self.parser = parser
self.control_obj = control_obj
def random_test(self):
test_options = []
for name in self.parser.options('Test_Selection'):
if self.parser.getboolean('Test_Selection', name):
test_options.append(name.lower())
ran_test_opt = choice(test_options)
ran_test_func = getattr(self, ran_test_opt)
ran_test_func()
#### TESTS ####
def random_aoi(self):
logging.info("Random AOI Test")
self.control_obj.random_readout_size()
def random_read_mode(self):
logging.info("Random Readout Mode Test")
self.control_obj.random_read_mode()
您可以在python中創建一個函數列表,您可以調用它們:
test_options = (random_aoi, random_read_mode)
def random_test(test_options, control_obj):
ran_test_opt = choice(test_options)
ran_test_opt(control_obj) # call the randomly selected function
您必須使每個函數以這種方式使用相同的參數,因此您可以以相同的方式調用它們。
如果需要為函數提供一些人類可讀的名稱,可以將它們與函數一起存儲在字典中。 我希望你將control_obj
傳遞給每個函數。
編輯:這似乎與 @Ikke的答案相同 ,但使用字典而不是函數列表。
>>> test_options = {'AOI': random_aoi, 'RMODE': random_read_mode}
>>> def random_test(test_options, control_obj):
... ran_test_opt = test_options[choice(test_options.keys())]
... ran_test_opt(control_obj)
或者您可以從test_options.values()
選擇一個測試。 對list()
的'額外'調用是因為在python 3.x中, dict.values()
返回一個迭代器。
>>> ran_test_opt = choice(list(test_options.values()))
我要在這里走出去,並建議你實際上使用一個真正的單元測試框架。 Python提供一個-方便命名unittest
。 要隨機運行測試,它將如下工作:
import unittest
class Tests(unittest.TestCase):
def test_something(self):
...
def test_something_else(self):
...
if __name__ == '__main__':
tests = list(unittest.defaultTestLoader.loadTestsFromTestCase(Tests))
import random
# repeat as many times as you would like...
test = random.choice(tests)
print(test)
test()
要運行所有測試,請使用: unittest.main()
- 我想你可以通過一個簡單的命令行開關來切換。
這具有巨大的優勢,您無需保持與測試本身分開的最新測試列表。 如果你想添加一個新的測試,只需添加一個, unittest
將找到它(只要方法名稱以test
開頭)。 它還會告訴您有關哪些測試運行以及哪些測試失敗等信息。
如果您將測試選擇功能和測試本身包裝在一個類中,則可以執行以下操作:
from random import choice
class Test(object):
""" Randomly selects a test from the methods with 'random' in the name """
def random_aoi(self):
print 'aoi'
def random_read_mode(self):
print 'read_mode'
def random_text(self):
print 'test'
# add as many tests as needed here
# important that this function doesn't have 'random' in the name(in my code anyway)
def run_test(self): # you can add control_obj to the args
methods = [m for m in dir(self) if callable(getattr(self, m)) and 'random' in m]
test = choice(methods)
getattr(self, test)() # you would add control_obj between these parens also
app = Test()
app.run_test()
這使得添加測試變得容易,而無需更改任何其他代碼。 這是關於getattr的信息
除了其他選項,請查看functools.partial
。 它允許為函數創建閉包:
from functools import partial
def test_function_a(x,y):
return x+y
def other_function(b, c=5, d=4):
return (b*c)**d
def my_test_functions(some_input):
funclist = (partial(test_function_a, x=some_input, y=4),
partial(other_function, b=some_input, d=9))
return funclist
random.choice(funclist)()
這使您可以規范化每個測試函數的參數列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.