Ответ 1
Это работает так, как вы предлагаете - вам просто нужно указать имя класса:
python testMyCase.py MyCase.testItIsHot
В нашей команде мы определяем большинство тестовых примеров:
Один класс "framework" ourtcfw.py:
import unittest
class OurTcFw(unittest.TestCase):
def setUp:
# something
# other stuff that we want to use everywhere
и множество тестовых примеров, таких как testMyCase.py:
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()
Когда я пишу новый тестовый код и хочу часто его запускать, и экономя время, я делаю то, что я ставил "__" перед всеми другими тестами. Но это громоздко, отвлекает меня от кода, который я пишу, и шум фиксации, который это создает, довольно раздражает.
Так, например, при внесении изменений в testItIsHot()
, я хочу иметь возможность сделать это:
$ python testMyCase.py testItIsHot
и unittest
запускать только testItIsHot()
Как я могу это достичь?
Я попытался переписать часть if __name__ == "__main__":
, но так как я новичок в Python, я чувствую себя потерянным и все время ругаюсь во всем, кроме методов.
Это работает так, как вы предлагаете - вам просто нужно указать имя класса:
python testMyCase.py MyCase.testItIsHot
Если вы организуете свои тестовые случаи, то есть следуйте той же организации, что и реальный код, а также используйте относительный импорт для модулей в одном пакете
Вы также можете использовать следующий формат команды:
python -m unittest mypkg.tests.test_module.TestClass.test_method
# In your case, this would be:
python -m unittest testMyCase.MyCase.testItIsHot
Документация Python3 для этого: https://docs.python.org/3/library/unittest.html#command-line-interface
Он может работать хорошо, как вы думаете
python testMyCase.py MyCase.testItIsHot
И есть еще один способ просто протестировать testItIsHot
:
suite = unittest.TestSuite()
suite.addTest(MyCase("testItIsHot"))
runner = unittest.TextTestRunner()
runner.run(suite)
Если вы проверите помощь модуля unittest, он расскажет вам о нескольких комбинациях, которые позволяют запускать классы тестов из модуля и методы тестирования из класса тестового случая.
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()
как поведения вашего модуля по умолчанию.
Может быть, это будет полезно для кого-то. Если вы хотите запускать только тесты из определенного класса:
if __name__ == "__main__":
unittest.main(MyCase())
Это работает для меня в Python 3.6
Вдохновленный @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")
Код бегуна:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import unittest
from .somewhere import LineBalancingUnitTests
def create_suite(classes, unit_tests_to_run):
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
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( create_suite( classes, unit_tests_to_run ) )
if __name__ == "__main__":
print( "\n\n" )
run_unit_tests()
Немного отредактировав код, вы можете передать массив со всеми юнит-тестами, которые вы хотели бы вызвать:
...
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 )
Кроме того, вы можете использовать https://docs.python.org/3/library/unittest.html#load-tests-protocol и определить следующий метод для вашего тестового модуля/файла:
def load_tests(loader, standard_tests, pattern):
suite = unittest.TestSuite()
# To add a single test from this file
suite.addTest( LineBalancingUnitTests( 'test_it_is_sunny' ) )
# To add a single test class from this file
suite.addTests( unittest.TestLoader().loadTestsFromTestCase( LineBalancingUnitTests ) )
return suite
Если вы хотите ограничить выполнение одним тестовым файлом, вам просто нужно установить шаблон обнаружения теста на единственный файл, в котором вы определили функцию load_tests()
.
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import unittest
test_pattern = 'mytest/module/name.py'
PACKAGE_ROOT_DIRECTORY = os.path.dirname( os.path.realpath( __file__ ) )
loader = unittest.TestLoader()
start_dir = os.path.join( PACKAGE_ROOT_DIRECTORY, 'testing' )
suite = loader.discover( start_dir, test_pattern )
runner = unittest.TextTestRunner( verbosity=2 )
results = runner.run( suite )
print( "results: %s" % results )
print( "results.wasSuccessful: %s" % results.wasSuccessful() )
sys.exit( not results.wasSuccessful() )
Ссылки:
В качестве альтернативы последнему примеру основной программы, я прочитал следующий вариант после прочтения реализации метода unittest.main()
:
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
import unittest
PACKAGE_ROOT_DIRECTORY = os.path.dirname( os.path.realpath( __file__ ) )
start_dir = os.path.join( PACKAGE_ROOT_DIRECTORY, 'testing' )
from testing_package import main_unit_tests_module
testNames = ["TestCaseClassName.test_nameHelloWorld"]
loader = unittest.TestLoader()
suite = loader.loadTestsFromNames( testNames, main_unit_tests_module )
runner = unittest.TextTestRunner(verbosity=2)
results = runner.run( suite )
print( "results: %s" % results )
print( "results.wasSuccessful: %s" % results.wasSuccessful() )
sys.exit( not results.wasSuccessful() )
https://docs.python.org/2/library/unittest.html
Вот еще один способ
testname = "testItIsHot"
testcase = MyCase(testname)
testcase.testItIsHot()