Python 应用闭包思路动态生成unittest执行脚本---分析问题,解决问题,记录填坑。

  至于为什么要动态生成unittest执行脚本,以及设计思路,代码阅读参考前文,传送门。好了,本文我们就上一篇文章中的问题做一下分析,记录一下填坑之路吧,这个坑真特么深,挣扎了好久才出来。

  首先我们先说一下问题在哪,因为使用了闭包,闭包会绑定变量无法清除无法更改,假如我第一次运行testall函数循环两次,第一次是正常的,第二次运行testall函数循环一次,那么生成的报告就会出现问题,会出现第一次运行的结果。即是:后一次循环运行只要比前一次循环少,那么report一定会出现前一次的结果,必先的bug。

  好了,我们聊一下前文动态生成unittest执行脚本的坑有多深吧,主要涉及闭包,又因为闭包循环调用unittest的Test类添加方法组成suite,大家都知道Python的闭包会绑定变量,无法清除无法改变,我们把相关代码贴出来吧,方便看。

 1 class Test(unittest.TestCase):  # TestCase类
 2     "测试类"
 3 
 4     def begin_req(self, apidata):  # 类方法
 5         back = run_single_testcase(apidata)  # 调用请求
 6         YQ = 200  # 结果对比
 7         SJ = back.status_code
 8         self.assertEqual(SJ, YQ)
 9 
10 def demo(apidata):  # 闭包
11     def tool(self):
12         Test.begin_req(self, apidata)  # 调用Test方法
13 
14     setattr(tool, '__doc__', u'测试%s' % str(apidata['name']))
15     return tool
16 
17 def testall(apidata): # 循环调用闭包
18     for i in range(len(apidata)):
19         setattr(Test, 'test_' + str(i + 1), demo(apidata[i]))
20 
21 def suite(Apidata):  # 调用testall拼装Test类,组装suit
22     testall(Apidata)
23     suit = unittest.makeSuite(Test)
24     return suit

 代码释义: 类Test继承unittest.TestCase没啥好说的,方法demo闭包内部函数tool,tool方法的第一个参数self是Test类(我理解为指针指向Test类),函数testall循环调用闭包,函数suite我上面注释写的很清楚了

  这个坑有很大的迷惑性,我有很大一部分时间都在关注闭包函数,我认为是闭包导致的,一直在研究闭包哪里出错了,还有要如何更改闭包函数的参数,用了很多方法,什么容器装参数,后面删除容器成员啥的,全用上了...MMP...结果确实是闭包导致的,但是问题没有出在闭包函数处,要理解闭包请参考其他文章,传送门,我们就不白话了,上解决的代码吧

 1 def testall(apidata):
 2     nameList = []
 3     for i in range(len(apidata)):
 4         name = 'test_' + str(i + 1)
 5         setattr(Test, name, demo(apidata[i]))
 6         nameList.append(name)
 7     return nameList
 8 
 9 def suite(Apidata):
10     nameList = testall(Apidata)
11     suites = unittest.TestSuite()
12     for i in nameList:
13         suites.addTest(Test(i))
14     return suites

  主要修改了testall函数和suite函数,其实问题出在suite函数里,原有函数如下代码

1 def suite(Apidata):  # 调用testall拼装Test类,组装suit
2     testall(Apidata)
3     suit = unittest.makeSuite(Test)
4     return suit

 

   第三行中makeSuite函数,是指一次性添加Test类的方法到suite,结果闭包绑定的对象(python一切皆对象)在Test里,第一次运行组装的Test类方法被闭包绑定,后一次运行如果比前一次少,那么就会有没有被覆盖的方法,就会出现错误,所以修改makeSuite函数为addTest函数,问题就解决了,我研究了很久的闭包啊,结果问题出在了Test类上,真心心累。文笔太差..见谅..多谢..

posted @ 2018-02-09 11:02  fengyca  阅读(714)  评论(0编辑  收藏  举报