有没有什么工具可以同时对Excel公式和Visual Basic表格进行单元测试?我发现有一些方法可以测试其中一个或另一个,但不能同时测试两个。橡皮鸭 例如,看起来很有希望测试VBA,但似乎不允许测试Excel电子表格中的公式。
我发现在Excel中 "单元测试 "函数的唯一方法是在你的工作簿中创建一个工作表,它的目的是验证页。在这个工作表中定义各种额外的功能,在你的工作簿中寻找边缘情况和检查添加等。
保留一个注释字段和一个布尔成功字段是相当有用的,可以将其聚合起来,在你的其他输入页面上放一个自定义格式的消息,以提示用户一个失败的 "单元测试"。
这种方法可以很好地使你的测试可重用,以及对你的工作簿的最终用户透明。
使用以下方法可以对Excel公式和VBA进行单元测试 FlyingKoala. FlyingKoala是一个扩展的 xlwings.
xlwings提供了一个COM封装器,它提供了从Python中执行VBA的能力(通过让Excel运行它)。这是一个很好的图书馆解决方案。尊敬的ZoomerAnalyitics的Felix写了一篇文章。博文 关于使用xlwings对VBA进行单元测试的例子。
FlyingKoala使用了一个库(xlcalculator)将Excel公式转换为Python,然后可以在Python的unittest框架中进行单元测试。因此,可以评估公式,并根据已知的目标值进行检查,无论该目标值是Excel中的还是预先定义的。
一个在Excel运行时使用FlyingKoala对公式进行单元测试的例子。
import unittest
import logging
import xlwings as xw
from flyingkoala import FlyingKoala
from pandas import DataFrame
from pandas import Series
from numpy import array
from numpy.testing import assert_array_equal
from pandas.testing import assert_series_equal
logging.basicConfig(level=logging.ERROR)
class Test_equation_1(unittest.TestCase):
def setUp(self):
self.workbook_name = r'growing_degrees_day.xlsm'
if len(xw.apps) == 0:
raise "We need an Excel workbook open for this unit test."
self.my_fk = FlyingKoala(self.workbook_name, load_koala=True)
self.my_fk.reload_koala('')
self.equation_name = xw.Range('Equation_1')
if self.equation_name not in self.my_fk.koala_models.keys():
model = None
wb = xw.books[self.workbook_name]
wb.activate()
for name in wb.names:
self.my_fk.load_model(self.equation_name)
if self.equation_name == name.name:
model = xw.Range(self.equation_name)
self.my_fk.generate_model_graph(model)
if model is None:
return 'Model "%s" has not been loaded into cache, if named range exists check spelling.' % self.equation_name
def test_Equation_1(self):
"""First type of test for Equation_1"""
xw.books[self.workbook_name].sheets['Growing Degree Day'].activate()
goal = xw.books[self.workbook_name].sheets['Growing Degree Day'].range(xw.Range('D2'), xw.Range('D6')).options(array).value
tmin = xw.books[self.workbook_name].sheets['Growing Degree Day'].range(xw.Range('B2'), xw.Range('B6')).options(array).value
tmax = xw.books[self.workbook_name].sheets['Growing Degree Day'].range(xw.Range('C2'), xw.Range('C6')).options(array).value
inputs_for_DegreeDay = DataFrame({'T_min': tmin, 'T_max': tmax})
result = self.my_fk.evaluate_koala_model('Equation_1', inputs_for_DegreeDay).to_numpy()
assert_array_equal(goal, result)
def test_Equation_1_predefined_goal(self):
"""First type of test for Equation_1"""
goal = Series([0.0, 0.0, 0.0, 0.0, 0.0, 5, 10, 15, 20])
tmin = [-20, -15, -10, -5, 0, 5, 10, 15, 20]
tmax = [0, 5, 10, 15, 20, 25, 30, 35, 40]
inputs_for_DegreeDay = DataFrame({'T_min': tmin, 'T_max': tmax})
result = self.my_fk.evaluate_koala_model('Equation_1', inputs_for_DegreeDay)
assert_series_equal(goal, result)
def test_VBA_Equation_1(self):
"""
The function definition being called;
Function VBA_Equation_1(T_min As Double, T_max As Double) As Double
VBA_Equation_1 = Application.WorksheetFunction.Max(((T_max + T_min) / 2) - 10, 0)
End Function
"""
goal = 20
vba_equation_1 = xw.books[self.workbook_name].macro('VBA_Equation_1')
result = vba_equation_1(20.0, 40.0)
self.assertEqual(goal, result)