eval()的奇怪行为会破坏unittest

时间:2012-11-23 14:17:09

标签: python unit-testing

我一直在进行原型设计,而不关注分配了一个变量的低质量代码,该变量通过在argv上调用eval()来获取它的值,后者又在包含API密钥的外部文件中获取它的值。令我惊讶的是,它严重破坏了单元测试(它们都没有运行)。

以下是我认为是罪魁祸首的代码段:

from sys import argv
from apikeys import *


def setKey(the_key=DCK):
    global CK
    CK = the_key # Currently used key

if len(argv) == 1:
    print('---Executing script. Enter optional arguments if you wish to use special API keys.---')
    setKey()
elif len(argv) > 1:
    setKey(eval(argv[1]))

TOKEN = rget(DOMAIN+'signin', params={'key':CK}).json['response']['token']
PARAMS = {'signature':TESTSIG, 'token':TOKEN}

# Rest of the code uses unittests which rely on PARAMS.

所以我传递一个包含key的变量作为测试我的脚本的值,它产生以下回溯:

[gp@imdev1 dv1/tests]# python 2test_api2.py ANDROID_FILMS_KEY
Traceback (most recent call last):
  File "2test_api2.py", line 604, in <module>
    unittest.main()
  File "/usr/lib/python2.6/site-packages/unittest2/main.py", line 97, in __init__
    self.parseArgs(argv)
  File "/usr/lib/python2.6/site-packages/unittest2/main.py", line 152, in parseArgs
    self.createTests()
  File "/usr/lib/python2.6/site-packages/unittest2/main.py", line 161, in createTests
    self.module)
  File "/usr/lib/python2.6/site-packages/unittest2/loader.py", line 148, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/lib/python2.6/site-packages/unittest2/loader.py", line 142, in loadTestsFromName
    raise TypeError("don't know how to make test from: %s" % obj)
TypeError: don't know how to make test from: 9b269ac759211de6b3c8b238bd758ccf

9b269ac759211de6b3c8b238bd758ccf基本上是运行eval(ANDROID_FILMS_KEY)的结果,并且在单独的脚本中运行setKey函数正确地将API密钥分配给CK作为字符串'9b269ac759211de6b3c8b238bd758ccf'

踢球者如下:当CK和PARAMS用于包含应该进行单元测试的方法的类时,Python出乎意料地提出了奇怪的异常,据说单元测试不会认为9b269ac759211de6b3c8b238bd758ccf是一个字符串?

1 个答案:

答案 0 :(得分:1)

unittest2加载程序检查sys.argv,以限制为测试加载的模块from the command line

这里发生的是加载器正在寻找名为9b269ac759211de6b3c8b238bd758ccf的测试模块。

你必须从你的单位测试中操纵sys.argv;它是你可以改变的标准python列表。或者,创建一个main(args)函数,默认情况下,您使用sys.argv[1:]调用:

def main(args):
    if not args:
        print('---Executing script. Enter optional arguments if you wish to use special API keys.---')
        setKey()
    else:
        setKey(eval(args[0]))

if __name__ == '__main__':
    import sys
    main(sys.argv[1:])

现在您可以使用不同的参数测试main(),而不必依赖于将参数传递给测试脚本。