Как выбрать конкретный тест с помощью тестовых наборов модульных тестов Python

У меня есть код модульного теста Python, организованный следующим образом:

Maindir
   |
   |--Dir1
   |  |
   |  |-- test_A.py
   |  |-- test_B.py
   |  |-- test_C.py
   |
   |--Dir2
       | ...

Я полагаю, вы поняли картину. В каждом из каталогов Dirx у меня есть файл с именем suite.py, который объединяет набор тестов из тестов в данном каталоге (так что вы можете выбрать конкретный тест, пропустить другие тесты и т. д.). Эти файлы выглядят, например. как показано ниже (в случае выбора всех тестов они также могут выбрать только подмножество тестов) [также рассмотрите тест ‹-› модульный тест]:

import test_A
import test_B
import test_C

suite1 = test.TestSuite()
suite1.addTests(test.TestLoader().loadTestsFromTestCase(test_A.MyTest))
suite1.addTests(test.TestLoader().loadTestsFromTestCase(test_B.MyTest))
suite1.addTests(test.TestLoader().loadTestsFromTestCase(test_C.MyTest))

Главный бегун, execall.py, в каталоге Maindir выглядит так:

from Dir1.suite import suite1
from Dir2.suite import suite2

suite_all = test.TestSuite([
    suite1,
    suite2])

if __name__ == '__main__':
    test.main(defaultTest='suite_all')

Теперь я могу сделать следующее:

  • Запустите все тесты: «execall.py» (как задокументировано)
  • Запустите определенный пакет: execall.py suite1 (как задокументировано)

Но как я могу запустить только один конкретный тест? И как я могу запустить все тесты конкретного файла? Я безуспешно пробовал следующее, с той же ошибкой: 'TestSuite' object has no attribute 'xxx'

execall.py suite1.test_A
execall.py suite1.test_A.test1
execall.py test_A
execall.py test_A.test1

execall.py -h дает очень конкретные примеры того, как запускать одиночные тесты или тесты в тесткейсах, но в моем случае это не работает.


person Alex    schedule 07.12.2012    source источник


Ответы (1)


Один из способов сделать это — написать собственный загрузчик тестов. Я настоятельно рекомендую использовать механизм, найденный в модуле testsuite Flask.

Основная идея такова:

  1. Реализуйте подпрограмму, которая возвращает объект unittest.TestSuite() со всеми модулями Python, содержащими необходимые тесты. Это можно сделать, например. просканировав каталог на наличие test_XXX.py файлов (просто проверив их по startswith('test'), регулярному выражению и т. д.).

  2. Подкласс unittest.TestLoader и переопределение loadTestsFromName(self, name, module), которое будет использовать набор тестов, созданный на шаге 1. Например, во фляге:

     for testcase, testname in find_all_tests(suite):
         if testname == name or \
             testname.endswith('.' + name) or \
             ('.' + name + '.') in testname or \
             testname.startswith(name + '.'):
             all_tests.append(testcase)
    

    Это позволяет загружать тесты по имени модуля Python, по имени тестового набора (тестового класса) или просто по имени тестового примера.

person Zaur Nasibov    schedule 07.12.2012
comment
Но это более крупное расширение, использующее другую структуру... Слишком выходящее за рамки - person Alex; 07.12.2012
comment
Нет, это фреймворк с открытым исходным кодом, лицензированный BSD, так что просто берите оттуда то, что вам нужно. На самом деле, я использовал немного модифицированный подход Flask testsuite в своей собственной структуре. - person Zaur Nasibov; 07.12.2012
comment
Но мне кажется, что мне нужно werkzeug, чтобы заставить его работать, или нет? - person Alex; 07.12.2012
comment
Flask действительно требует werkzeug, но я говорю об использовании крошечной его части, механизма и идеи, концепции, способа, ... - вы называете это, о том, как тестирование выполняется во Flask. В простейшем случае вам придется принять один __init__.py из набора тестов. Чтение кода других программистов улучшает свои навыки гораздо быстрее, чем можно себе представить. Армин Ронахер, автор Flask, очень известный человек в мире Python, и изучение его кода — очень приятный процесс. - person Zaur Nasibov; 07.12.2012
comment
Хорошо, думаю, попробую. Большое спасибо - person Alex; 07.12.2012