从unittest.TestCase通过命令行运行单个testing

在我们的团队中,我们定义了大部分的testing案例:

一个“框架”类ourtcfw.py:

import unittest class OurTcFw(unittest.TestCase): def setUp: # something # other stuff that we want to use everywhere 

还有很多像testMyCase.py这样的testing用例:

 import localweather class MyCase(OurTcFw): def testItIsSunny(self): self.assertTrue(localweather.sunny) def testItIsHot(self): self.assertTrue(localweather.temperature > 20) if __name__ == "__main__": unittest.main() 

当我编写新的testing代码并希望经常运行它,并节省时间时,我所做的是将“__”放在所有其他testing之前。 但是,这很麻烦,分散我从我正在写的代码,而这造成的交付噪音简直是烦人的。

所以,例如,当对testItIsHot()进行更改时,我希望能够做到这一点:

 $ python testMyCase.py testItIsHot 

并且unittest 运行testItIsHot()

我怎样才能做到这一点?

我试图重写if __name__ == "__main__":部分,但由于我是Python的新手,我感到迷茫,并且一直在抨击一切,而不是方法。

这是按照你的build议工作 – 你只需要指定类名称:

 python testMyCase.py MyCase.testItIsHot 

如果你组织你的testing用例,也就是像实际的代码一样遵循相同的组织结构,也可以在同一个包中使用相对导入模块

您也可以使用以下命令格式:

 python -m unittest mypkg.tests.test_module.TestClass.test_method # In your case, this would be: python -m unittest testMyCase.MyCase.testItIsHot 

它可以很好地工作,你猜

 python testMyCase.py MyCase.testItIsHot 

还有另一种方法来testingtestItIsHot

  suite = unittest.TestSuite() suite.addTest(MyCase("testItIsHot")) runner = unittest.TextTestRunner() runner.run(suite) 

如果您查看了unittest模块的帮助,它会告诉您几个允许您从模块运行testing用例类和testing用例类的testing方法的组合。

 python3 -m unittest -h [...] Examples: python3 -m unittest test_module - run tests from test_module python3 -m unittest module.TestClass - run tests from module.TestClass python3 -m unittest module.Class.test_method - run specified test method 

它不要求你定义一个unittest.main()作为模块的默认行为。

受@yarkee启发,我把它和我已经有的一些代码结合起来。 你也可以通过调用函数run_unit_tests()来调用另一个脚本,而不需要使用命令行,或者使用python3 my_test_file.py从命令行调用它。

 import my_test_file my_test_file.run_unit_tests() 

可悲的是,这只适用于Python 3.3或更高版本:

 import unittest class LineBalancingUnitTests(unittest.TestCase): @classmethod def setUp(self): self.maxDiff = None def test_it_is_sunny(self): self.assertTrue("a" == "a") def test_it_is_hot(self): self.assertTrue("a" != "b") def run_unit_tests(): runner = unittest.TextTestRunner() classes = \ [ LineBalancingUnitTests, ] # Comment all the tests names on this list, to run all Unit Tests unit_tests_to_run = \ [ "test_it_is_sunny", # "test_it_is_hot", ] runner.run( suite( classes, unit_tests_to_run ) ) def suite(classes, unit_tests_to_run): """ Problem with sys.argv[1] when unittest module is in a script https://stackoverflow.com/questions/2812218/problem-with-sys-argv1-when-unittest-module-is-in-a-script Is there a way to loop through and execute all of the functions in a Python class? https://stackoverflow.com/questions/2597827/is-there-a-way-to-loop-through-and-execute-all-of-the-functions looping over all member variables of a class in python https://stackoverflow.com/questions/1398022/looping-over-all-member-variables-of-a-class-in-python """ suite = unittest.TestSuite() unit_tests_to_run_count = len( unit_tests_to_run ) for _class in classes: _object = _class() for function_name in dir( _object ): if function_name.lower().startswith( "test" ): if unit_tests_to_run_count > 0 \ and function_name not in unit_tests_to_run: continue suite.addTest( _class( function_name ) ) return suite if __name__ == "__main__": print( "\n\n" ) run_unit_tests() 

稍微编辑一下代码,你可以传递一个你想要调用的所有unit testing的数组:

 ... def run_unit_tests(unit_tests_to_run): runner = unittest.TextTestRunner() classes = \ [ LineBalancingUnitTests, ] runner.run( suite( classes, unit_tests_to_run ) ) ... 

另一个文件:

 import my_test_file # Comment all the tests names on this list, to run all Unit Tests unit_tests_to_run = \ [ "test_it_is_sunny", # "test_it_is_hot", ] my_test_file.run_unit_tests( unit_tests_to_run ) 

这是另一种方式

 testname = "testItIsHot" testcase = MyCase(testname) testcase.testItIsHot()