Python unittest传递参数

Chr*_*r H 63 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(argv=[sys.argv[1]])
    email_from_argument = sys.argv[1] 
Run Code Online (Sandbox Code Playgroud)

hwj*_*wjp 115

所以这里的医生说"你说那伤害了吗?那就不要那样了!" 可能是对的.但是如果你真的想要,这是将参数传递给unittest测试的一种方法:

import sys
import unittest

class MyTest(unittest.TestCase):
    USERNAME = "jemima"
    PASSWORD = "password"

    def test_logins_or_something(self):
        print('username : {}'.format(self.USERNAME))
        print('password : {}'.format(self.PASSWORD))


if __name__ == "__main__":
    if len(sys.argv) > 1:
        MyTest.USERNAME = sys.argv.pop()
        MyTest.PASSWORD = sys.argv.pop()
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

这将让你运行:

python mytests.py ausername apassword
Run Code Online (Sandbox Code Playgroud)

你需要argv.pops所以你的命令行参数不要搞乱unittest自己...

[更新]您可能想要研究的另一件事是使用环境变量:

import os
import unittest

class MyTest(unittest.TestCase):
    USERNAME = "jemima"
    PASSWORD = "password"

    def test_logins_or_something(self):
        print('username : {}'.format(self.USERNAME))
        print('password : {}'.format(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()
Run Code Online (Sandbox Code Playgroud)

这将让你运行:

TEST_USERNAME=ausername TEST_PASSWORD=apassword python mytests.py
Run Code Online (Sandbox Code Playgroud)

它的优点是你不会搞乱unittest自己的参数解析.缺点是它不会像在Windows上那样工作......

  • 这太棒了!它*伤害了,现在却没有. (12认同)
  • @Yeow_Meng,您可能需要更具体。我正在将它与 python-3.6.5 一起使用并且它有效。 (2认同)

sea*_*ean 22

扩展上述关于单元测试的评论.单元测试应该是独立的,因为它们在设置和拆除要求之外没有依赖关系,例如在您设置电子邮件的情况下.这可确保每项测试都有非常特殊的副作用和对测试的反应.传入参数会破坏单元测试的这个属性,从而使它们在某种意义上无效.使用测试配置是最简单的方法,也是更合适的方法,因为单元测试再也不应该依赖外部信息来执行测试.那是集成测试.

  • 问题不是"我应该这样做吗?" 这是"我该怎么做?" 用"你不应该这样做"回应的傲慢是令人震惊的. (57认同)
  • 如果我想使用unittest模块编写集成测试怎么办?或者有更好的工具吗? (35认同)
  • 传递参数的示例是有意义的:我们将参数传递给测试以声明我们希望运行测试的服务器. (10认同)
  • @EddieSullivan更令人惊讶的是答案被接受了.来自@ hwjp的"真实"答案可能来得太晚了...... (4认同)
  • 这甚至还没有开始回答这个问题。它不应该被接受。如果我拥有它,则将其删除。公平地说,保留其权利,但只是非常笼统的。就像大家已经说过的那样,有时您会发现,无论出于何种原因(集成,更改部署conf,dev vs prod等),使用测试用例构建可参数化的测试集都可以节省大量的精力。 (2认同)

ste*_*s21 22

对于那些真正想要这样做的人来说,尽管你不应该做出正确的评论,这是另一种方法:

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)
Run Code Online (Sandbox Code Playgroud)


Fed*_*ico 11

即使测试大师说我们不应该这样做:我做。在某些情况下,使用参数来推动测试朝着正确的方向发展是很有意义的,例如:

  • 我现在应该使用十几个相同的 USB 卡中的哪一个来进行这个测试?
  • 我现在应该使用哪个服务器进行此测试?
  • 我应该使用哪个 XXX?

对我来说,使用环境变量就足够了,因为您不必编写专用代码来传递参数;它由 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))
Run Code Online (Sandbox Code Playgroud)

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

$ export VAR1=1
$ export VAR2=2
$ python -m unittest MyTest
var1: 1, var2: 2
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
Run Code Online (Sandbox Code Playgroud)

  • 感谢您以不同的方式思考 - 即“哦,这不是 python 派对路线,所以不能这样做” (2认同)

sfi*_*ens 6

如果您想使用steffens21 的方法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)
Run Code Online (Sandbox Code Playgroud)


pep*_*epr -5

单元测试旨在测试非常基本的功能(应用程序的最低级别功能),以确保您的应用程序构建块正常工作。对于这到底意味着什么,可能没有正式的定义,但是您应该考虑对更大的功能进行其他类型的测试- 请参阅集成测试。单元测试框架可能不适合此目的。

  • 是的,但是单元测试框架本身可以用于(并且在许多情况下使用)来开发和集成测试框架,这通常需要复杂的设置和拆卸。在这种情况下,如果可能的话,拥有一个带有测试函数和参数的基类以及带有参数定义的继承类或使用基于环境的配置脚本会很有帮助。 (11认同)