在python中如何将命令行中的参数传递给unittest函数。到目前为止,这是代码......我知道它错了。
class TestingClass(unittest.TestCase):
def testEmails(self):
assertEqual(email_from_argument, "my_email@example.com")
if __name__ == "__main__":
unittest.main(argv=[sys.argv[1]])
email_from_argument = sys.argv[1]
答案 0 :(得分:98)
所以这里的医生说“你说那伤害了?那就不要那样做了!”可能是对的。但是如果你真的想要,这是将参数传递给单元测试的一种方法:
import sys
import unittest
class MyTest(unittest.TestCase):
USERNAME = "jemima"
PASSWORD = "password"
def test_logins_or_something(self):
print 'username', self.USERNAME
print 'password', self.PASSWORD
if __name__ == "__main__":
if len(sys.argv) > 1:
MyTest.USERNAME = sys.argv.pop()
MyTest.PASSWORD = sys.argv.pop()
unittest.main()
可以让你运行:
python mytests.py ausername apassword
你需要argv.pop
s所以你的命令行参数不会搞乱unittest自己...
[update]您可能想要研究的另一件事是使用环境变量:
import os
import unittest
class MyTest(unittest.TestCase):
USERNAME = "jemima"
PASSWORD = "password"
def test_logins_or_something(self):
print 'username', self.USERNAME
print 'password', self.PASSWORD
if __name__ == "__main__":
MyTest.USERNAME = os.environ.get('TEST_USERNAME', MyTest.USERNAME)
MyTest.PASSWORD = os.environ.get('TEST_PASSWORD', MyTest.PASSWORD)
unittest.main()
这将让你运行:
TEST_USERNAME=ausername TEST_PASSWORD=apassword python mytests.py
它的优点是你不会搞乱unittest自己的参数解析。缺点是它不会像在Windows上那样工作......
答案 1 :(得分:23)
扩展上述关于单元测试的评论。单元测试应该是独立的,因为它们在设置和拆除要求之外没有依赖关系,例如在您设置电子邮件的情况下。这可确保每项测试都有非常特殊的副作用和对测试的反应。传入参数会破坏单元测试的这个属性,从而使它们在某种意义上无效。使用测试配置是最简单的方法,也是更合适的方法,因为单元测试再也不应该依赖外部信息来执行测试。那是集成测试。
答案 2 :(得分:18)
对于那些真正想要这样做的人来说,尽管有正确的评论,你不应该这样做:
import unittest
class MyTest(unittest.TestCase):
def __init__(self, testName, extraArg):
super(MyTest, self).__init__(testName) # calling the super class init varies for different python versions. This works for 2.7
self.myExtraArg = extraArg
def test_something(self):
print self.myExtraArg
# call your test
suite = unittest.TestSuite()
suite.addTest(MyTest('test_something', extraArg))
unittest.TextTestRunner(verbosity=2).run(suite)
答案 3 :(得分:3)
如果您想将steffens21's approach与unittest.TestLoader
一起使用,则可以修改原始测试加载器(请参阅unittest.py
):
import unittest
from unittest import suite
class TestLoaderWithKwargs(unittest.TestLoader):
"""A test loader which allows to parse keyword arguments to the
test case class."""
def loadTestsFromTestCase(self, testCaseClass, **kwargs):
"""Return a suite of all tests cases contained in
testCaseClass."""
if issubclass(testCaseClass, suite.TestSuite):
raise TypeError("Test cases should not be derived from "\
"TestSuite. Maybe you meant to derive from"\
" TestCase?")
testCaseNames = self.getTestCaseNames(testCaseClass)
if not testCaseNames and hasattr(testCaseClass, 'runTest'):
testCaseNames = ['runTest']
# Modification here: parse keyword arguments to testCaseClass.
test_cases = []
for test_case_name in testCaseNames:
test_cases.append(testCaseClass(test_case_name, **kwargs))
loaded_suite = self.suiteClass(test_cases)
return loaded_suite
# call your test
loader = TestLoaderWithKwargs()
suite = loader.loadTestsFromTestCase(MyTest, extraArg=extraArg)
unittest.TextTestRunner(verbosity=2).run(suite)
答案 4 :(得分:0)
Unit testing用于测试非常基本的功能(应用程序的最低级功能),以确保应用程序构建块正常工作。可能没有正式的定义是什么意思,但你应该考虑其他类型的测试更大的功能 - 见Integration testing。单元测试框架可能不是理想的用途。
答案 5 :(得分:0)
有同样的问题。我的解决方案是在您使用argparse或其他方式处理解析参数之后,从sys.argv中删除参数
sys.argv = sys.argv[:1]
如果需要,可以从main.parseArgs()
中过滤unittest参数答案 6 :(得分:0)
即使测试大师说我们不应该这样做:我做到了。在某些情况下,使用参数以正确的方向驱动测试是很有意义的,例如:
对我来说,使用环境变量对于这个puprose是足够好的,因为你不必编写专用代码来传递你的参数;它受Python支持。它干净而简单。
当然,我并不主张完全可参数化的测试。但我们必须务实,正如我所说,在某些情况下,你需要一个或两个参数。我们不应该放弃它:))
import os
import unittest
class MyTest(unittest.TestCase):
def setUp(self):
self.var1 = os.environ["VAR1"]
self.var2 = os.environ["VAR2"]
def test_01(self):
print("var1: {}, var2: {}".format(self.var1, self.var2))
然后从命令行(在Linux上测试)
$ export VAR1=1
$ export VAR2=2
$ python -m unittest MyTest
var1: 1, var2: 2
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
答案 7 :(得分:0)
这是我的解决方案:
# your test class
class TestingClass(unittest.TestCase):
# This will only run once for all the tests within this class
@classmethod
def setUpClass(cls) -> None:
if len(sys.argv) > 1:
cls.email = sys.argv[1]
def testEmails(self):
assertEqual(self.email, "my_email@example.com")
if __name__ == "__main__":
unittest.main()
您可以拥有一个 runner.py
文件,其中包含以下内容:
# your runner.py
loader = unittest.TestLoader()
tests = loader.discover('.') # note that this will find all your tests, you can also provide the name of the package e.g. `loader.discover('tests')
runner = unittest.TextTestRunner(verbose=3)
result = runner.run(tests
使用上面的代码,您应该使用 runner.py my_email@example.com
运行您的测试。