Python单元测试传递参数

Python单元测试传递参数,python,unit-testing,Python,Unit Testing,在Python中,如何将参数从命令行传递给unittest函数 这是到目前为止的代码…我知道它错了 class TestingClass(unittest.TestCase): def testEmails(self): assertEqual(email_from_argument, "my_email@example.com") if __name__ == "__main__": unittest.main(ar

在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]

用于测试非常基本的功能(应用程序的最低级别功能),以确保应用程序构建块正常工作。可能没有确切的定义是什么意思,但是你应该考虑更大的功能的其他类型的测试——参见。单元测试框架可能不适合这个目的。

所以这里的医生说“你说那很伤人?那就别那么做!”可能是对的。但如果您真的想,这里有一种将参数传递给unittest的方法:

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 myusername mypassword
TEST_USERNAME=ausername TEST_PASSWORD=apassword python mytests.py
您需要
argv.pop
s,这样您的命令行参数就不会与unittest自己的参数冲突

您可能需要研究的另一件事是使用环境变量:

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()
这将使您能够在以下情况下运行:

python mytests.py myusername mypassword
TEST_USERNAME=ausername TEST_PASSWORD=apassword python mytests.py

它的优点是您不会干扰unittest自己的参数解析。缺点是它在Windows上的工作方式不太像…

另一种方法适用于那些真正想这样做的人,尽管有正确的评论说你不应该这样做:

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)
如果要与
unittest.TestLoader
一起使用,可以修改原始测试加载程序(请参见
unittest.py
):


我也有同样的问题。我的解决方案是,使用argparse或其他方法处理解析参数后,从sys.argv中删除参数:

sys.argv = sys.argv[:1]  

如果需要,您可以从main.parseArgs()中筛选unittest参数。

即使测试专家说我们不应该这样做:我应该这样做。在某些情况下,设置参数以使测试朝着正确的方向进行非常有意义,例如:

  • 我现在应该使用这十二个相同的USB卡中的哪一个来进行此测试
  • 我现在应该使用哪个服务器进行此测试
  • 我应该使用哪个XXX
对我来说,环境变量的使用对于这个puprose来说已经足够好了,因为您不必编写专门的代码来传递参数;Python支持它。它干净而简单

当然,我并不提倡完全参数化的测试。但我们必须务实,正如我所说,在某些情况下,你需要一个或两个参数。我们不应该谈论它:)

然后从命令行(在Linux上测试)

这是我的解决方案:

#您的测试类
类TestingClass(unittest.TestCase):
#该类中的所有测试只运行一次
@类方法
def设置类(cls)->无:
如果len(sys.argv)>1:
cls.email=sys.argv[1]
电子邮件(自我):
assertEqual(self.email,“我的_email@example.com")
如果名称=“\uuuuu main\uuuuuuuu”:
unittest.main()
您可以有一个包含如下内容的
runner.py
文件:

#你的跑步者.py
loader=unittest.TestLoader()
tests=loader.discover('.')#注意,这将查找所有测试,您还可以提供包的名称,例如'loader.discover('tests'))
runner=unittest.TextTestRunner(verbose=3)
结果=运行程序。运行(测试

使用上述代码,您应该能够使用
runner.py my运行测试_email@example.com

问题是,单元测试应该能够自动运行,这使得传递参数变得困难。如果您详细解释了您要测试的内容,也许可以在命令行中运行python testfunction.py和name==“main”允许这样做。我希望能够运行python testfunction.py my_email@example.com我的_email2@example.comHow关于使用配置文件?这有用吗?例如,我不希望…只是一个首选项,但也许我也应该看看(这是一个更老的问题,但缺少.很好的例子!另一个at.但care passed参数不会弄乱unittest的..谢谢。这有助于了解如何使unittest在我的特定情况下工作。我可以批量执行吗?如果MyTest类中有多个测试,请告诉我为什么选择不使用unittest.main()相反,我们使用了TestSuite/TextTestRunner?self.getTestCaseNames方法来自何处?它属于TestLoaderWithKwargs继承的unittest.TestLoader类。看起来pytest页面被移动了。仅供参考,我以前做过类似的事情:使用“-”要将我的arg与unittest可能需要的arg分开,那么我可以将“-”后面的参数列表传递给我自己的arg解析器,并将它们从sys.argv中删除,或者使用unittest.main(argv=smaller_list)显式传递args unittest可能需要的
sys.argv.pop()
方法在
python3
中似乎不起作用。我想知道如何在
python3
@Yeow\u-Meng中实现这一点,您可能需要更具体一些。我正在使用python-3.6.5,它可以工作。如果您想在不同的环境(如不同的阶段等)下运行相同的测试,那么它非常方便。可能是我nt变量是最干净的。是的,但是可以使用unittest框架本身(并且在许多情况下使用)开发和集成测试框架,这通常需要复杂的设置和拆卸。在这种情况下,有一个带有测试函数和参数的基类,有一个带有参数定义的继承类(如果可能的话)或使用基于环境的配置脚本将是有帮助的。与Umar一致,unittest框架对于如果你小心的话,它会非常方便,这与它最初的用途不符。不仅仅是因为你可以与所有其他工具集成,例如,它可以输出到的东西。
$ export VAR1=1
$ export VAR2=2
$ python -m unittest MyTest
var1: 1, var2: 2
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK