Python unittest passing arguments

后端 未结 6 1014
伪装坚强ぢ
伪装坚强ぢ 2020-11-28 23:16

In python how would I pass an argument from the command line to a unittest function. Here is the code so far… I know it\'s wrong.

class TestingClass(unittes         


        
相关标签:
6条回答
  • 2020-11-28 23:29

    If you want to use steffens21's approach with unittest.TestLoader, you can modify the original test loader (see 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)
    
    0 讨论(0)
  • 2020-11-28 23:30

    Unit testing is meant for testing the very basic functionality (the lowest level functions of the application) to be sure that your application building blocks work correctly. There is probably no formal definition of what does that exactly mean, but you should consider other kinds of testing for the bigger functionality -- see Integration testing. The unit testing framework may not be ideal for the purpose.

    0 讨论(0)
  • 2020-11-28 23:45

    So the doctors here that are saying "You say that hurts? Then don't do that!" are probably right. But if you really want to, here's one way of passing arguments to a unittest test:

    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()
    

    that will let you run with:

    python mytests.py ausername apassword
    

    You need the argv.pops so your command line params don't mess with unittest's own...

    [update] The other thing you might want to look into is using environment variables:

    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()
    

    That will let you run with:

    TEST_USERNAME=ausername TEST_PASSWORD=apassword python mytests.py
    

    and it has the advantage that you're not messing with unittest's own argument parsing. downside is it won't work quite like that on Windows...

    0 讨论(0)
  • 2020-11-28 23:45

    Another method for those who really want to do this in spite of the correct remarks that you shouldn't:

    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)
    
    0 讨论(0)
  • 2020-11-28 23:50

    Have a same problem. My solution is after you handle with parsing arguments using argparse or other way, remove arguments from sys.argv

    sys.argv = sys.argv[:1]  
    

    If you need you can filter unittest arguments from main.parseArgs()

    0 讨论(0)
  • 2020-11-28 23:52

    Even if the test gurus say that we should not do it: I do. In some context it makes a lot of sense to have parameters to drive the test in the right direction, for example:

    • which of the dozen identical USB cards should I use for this test now?
    • which server should I use for this test now?
    • which XXX should I use?

    For me, the use of the environment variable is good enough for this puprose because you do not have to write dedicated code to pass your parameters around; it is supported by Python. It is clean and simple.

    Of course, I'm not advocating for fully parametrizable tests. But we have to be pragmatic and, as I said, in some context you need a parameter or two. We should not abouse of it :)

    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))
    

    Then from the command line (tested on Linux)

    $ export VAR1=1
    $ export VAR2=2
    $ python -m unittest MyTest
    var1: 1, var2: 2
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.000s
    
    OK
    
    0 讨论(0)
提交回复
热议问题