如何在单个python脚本中设置测试数据和测试用例

如何在单个python脚本中设置测试数据和测试用例,python,unit-testing,ddt,Python,Unit Testing,Ddt,我正在编写一个单元测试,并尝试在同一个python脚本中设置测试数据以用于测试用例 但是,当我运行脚本时,它确实创建了测试数据,但打印了一条错误消息,表明数据不存在,从而导致测试失败。只有当我再次运行脚本时,测试才会成功 下面是我写的一个简化脚本,以了解发生了什么 导入单元测试 从ddt导入ddt,文件\u数据 进口大熊猫 @滴滴涕 类TestAnywhere(unittest.TestCase): @类方法 def设置等级(cls): cls.设置测试数据() 打印(“setUpClass正在

我正在编写一个单元测试,并尝试在同一个python脚本中设置测试数据以用于测试用例

但是,当我运行脚本时,它确实创建了测试数据,但打印了一条错误消息,表明数据不存在,从而导致测试失败。只有当我再次运行脚本时,测试才会成功

下面是我写的一个简化脚本,以了解发生了什么

导入单元测试
从ddt导入ddt,文件\u数据
进口大熊猫
@滴滴涕
类TestAnywhere(unittest.TestCase):
@类方法
def设置等级(cls):
cls.设置测试数据()
打印(“setUpClass正在运行”)
@类方法
def拆卸类(cls):
打印(“tearDownClass正在运行”)
@类方法
def设置测试数据(cls):
data=pandas.DataFrame({'msg':[“testing”]})
data=data.transpose()
打开(“practice_test.json”、“w”)作为文件:
file.write(data.to_json())
打印(“设置\测试\数据正在运行”)
@文件数据(“practice\u test.json”)
def test_尽可能(self,msg):
打印(“正在运行的测试:”,msg)
self.assertEqual('q','q'))
def测试(不可能的情况)(自我):
打印(“正在运行任何不可能的测试”)
self.assertEqual('n','n'))
当我运行上面的脚本时,它会打印:

setup_test_data is running
setUpClass is running
test_whatever_impossible is running
.EtearDownClass is running

======================================================================
ERROR: test_whatever_possible_00001_error (main.TestWhatever)
Error!
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\ddt.py", line 145, in wrapper
    return func(self, *args, **kwargs)
  File "C:\ddt.py", line 187, in func
    raise ValueError(message % file_attr)
ValueError: practice_test.json does not exist

----------------------------------------------------------------------
Ran 2 tests in 0.006s

FAILED (errors=1)
然后在第二次运行时:

setup_test_data is running
setUpClass is running
test_whatever_impossible is running
.test_whatever_possible is running : testing
.tearDownClass is running

----------------------------------------------------------------------
Ran 2 tests in 0.005s

OK
在这一点上我几乎迷路了。。。
有人对此有线索吗?

所有Python代码都是可执行的。加载类主体时,将执行其中的语句。修饰函数使用
def
中的咖啡创建函数,将其分配给临时类名称空间中的名称(例如
test\u无论什么可能的
),然后用调用修饰器的结果替换它

这一点很重要的原因是,在加载类时调用decorator,而不是在运行测试时调用decorator。decorator检查文件是否存在(间接地),因为它必须将您的测试函数替换为使用文件中的值调用您的测试的函数

您的第二次运行已通过,因为第一次运行已创建测试文件。我建议在GitHub上填写一个问题。
file\u data
需要延迟打开文件,或者需要在某个地方清楚地记录意外行为


你可以确切地看到这个魔术在世界上发生的地方。仅标记测试函数以进行进一步处理。然后检查该文件是否可用于扩展实际测试,或者是否可创建只会引发您看到的错误的替换文件。

作为一种解决方法,您可以编写自己的decorator来创建数据文件,例如

def创建_数据(名称):
def装饰器(fn):
def装饰(*args,**kwargs):
data=pandas.DataFrame({“msg”:[“testing”]})
data=data.transpose()
打开(名称“w”)作为文件:
file.write(data.to_json())
res=fn(*args,**kwargs)
操作系统取消链接(名称)
返回res
回报
返回装饰器
然后将其堆叠用于测试(并删除
setup\u test\u data
步骤):

滴滴涕 类TestAnywhere(unittest.TestCase): @类方法 def设置等级(cls): 打印(“setUpClass正在运行”) @类方法 def拆卸类(cls): 打印(“tearDownClass正在运行”) @创建数据(“practice\u test.json”) @文件数据(“practice\u test.json”) def测试(尽可能)(自身): 打印(“正在运行的测试:”) self.assertEqual(“q”、“q”) 更新:1月31日 以下示例保留了将参数值传递给测试函数的ddt行为:

导入json
导入单元测试
从ddt导入ddt,文件\u ATTR
def创建文件数据(值、数据):
def包装器(func):
打开(值“w”)作为文件:
file.write(json.dumps(数据))
#这就是文件数据装饰器所做的
setattr(函数,文件\属性,值)
返回函数
返回包装器
@滴滴涕
类TestAnywhere(unittest.TestCase):
@创建_文件_数据(“practice_test.json”,{“msg”:[“testing”]})
def测试文件数据(self,msg):
打印(“测试文件数据消息:”,消息)
unittest.main()
运行时,输出为:

test_file_data msg: ['testing']
.
----------------------------------------------------------------------
Ran 1 test in 0.001s

使用上面的两个示例,您应该能够为您的问题导出适当的解决方案。

解决方案确实为测试方法创建了一个json文件,但是文件中的数据('msg')不再被传递到测试中。这方面也会有解决办法吗?@jsy我在我的报告中添加了另一个示例answer@jsy额外的例子对你有帮助吗?是的。现在我正在研究ddt库的源代码,以便根据我的需要修改您的示例。:)@jsy你能接受这个答案吗,因为它可以帮助其他人寻找类似的答案。谢谢