【发布时间】:2020-06-05 04:44:56
【问题描述】:
我是 python 新手,正在尝试学习单元测试。我正在使用 pytest 对我的代码运行一些单元测试。与此示例非常相似:
def test_calc_total():
total = mathlib.calc_total(4,5)
assert total == 9
我在这里可能不正确,但我了解到,为了使您的函数可测试,它必须返回一个值。所有单元测试都是这样吗?
我发现我的大部分函数都无法测试,因为它们没有返回值。我正在创建一个票务跟踪系统并将票务信息存储在数据框中。这是 TicketDF 类的一部分:
class TicketDF():
cwd = os.getcwd()
df = pd.DataFrame()
def __init__(self, configParser):
self.populateFilePaths(configParser)
self.populateAttributes(configParser)
self.populateTable()
def populateTable(self):
if self.doesFileExistAndNotEmpty(self.ticketCSVFilePath):
self.df = pd.read_csv(self.ticketCSVFilePath, converters={'Comments':literal_eval}) #, 'Attachments':literal_eval})
self.df.set_index('Ticket ID', inplace=True)
def populateAttributes(self, configParser):
self.ticketAttributes = configParser.getTicketAttributes()
def populateFilePaths(self, configParser):
self.ticketCSVFilePath = configParser.getTicketsCSVPath()
def doesFileExistAndNotEmpty(self, filepath):
if os.path.exists(filepath) and os.path.getsize(filepath) > 0:
return True
else:
return False
def getTicketDF(self):
return self.df
def addTicketToDF(self, data):
df = pd.DataFrame (data, columns = self.ticketAttributes)
df.set_index('Ticket ID', inplace=True)
self.df = self.df.append(df)
self.saveDFToCSV()
如您所见,大多数函数,即使是未显示的函数,也没有返回值。编写代码以使所有函数都有返回值是最佳实践吗?或者有没有其他方法可以测试没有返回值的函数?
【问题讨论】:
-
这些方法正在更改对象或其属性的状态,因此您可以验证值,更改的状态
-
纯函数——即输出仅由输入决定的函数——是最容易测试的。您应该尽可能地编写这些类型的函数,因为您可以对行为做出更强有力的保证。
-
要编写单元测试,您需要调用函数的可观察、可验证、确定性副作用。不需要有返回值。
-
纯函数存在于计算机世界之外,但是是的——在编程的上下文中,输出将是返回的值。底线是:尽可能保持数据不可变,尝试返回值,并尽量减少副作用;您将有更快乐的时间编写程序。 :-)
-
这取决于几件事,最终是一个非常哲学的讨论。您要问的基本上是“我应该更喜欢面向对象”还是“我应该更喜欢函数式编程?”两者都有一席之地-我鼓励您阅读两者并自己确定。我更倾向于 FP(所以函数、它们的组成和不变性)——这并不能使它或多或少正确。
标签: python unit-testing pytest