Тесты Django занимают много времени, чтобы начать - PullRequest
0 голосов
/ 06 мая 2018

Я запускаю тесты для приложения django под названием stats, которое использует базу данных Postgre. Проект хранит все тесты в папке ./stats/tests/.

Когда я запускаю тест, т.е. python manage.py test stats.tests.test_dataGeneration, несколько минут ничего не проходит, когда текстовый курсор в моей командной строке просто мигает. На этом раннем этапе я даже не могу использовать прерывание клавиатуры для немедленной остановки теста (прерывание клавиатуры занимает не менее 30 секунд для регистрации).

В конце концов, через несколько минут я вижу
Creating test database for alias 'default' ('test_statsdb')...
сообщение, которое создает базу данных для тестирования. С этого момента тесты всегда завершаются менее чем за 10 секунд (как в выходных данных django Ran XX tests in 5.00s).

Я не знаю или не понимаю, почему тесты начинаются так долго, или что именно выполняется в первые несколько минут. Несколько дней назад у меня не было проблем с тестированием приложения. Использование --keepdb для перезапуска базы данных тестов между запусками тестов заметно не сокращает время, необходимое для выполнения тестов.

Я надеялся, что кто-нибудь сможет пролить свет на то, что приносит счастье.

Пример вывода результатов теста, когда я запускаю их с verbosity=2 для дополнительной информации:
>python manage.py test stats.tests.test_dataGeneration --verbosity=2

Creating test database for alias 'default' ('test_statsdb')...
Operations to perform:
  Synchronize unmigrated apps: messages, portfolio_web, staticfiles, updateDatabase
  Apply all migrations: auth, contenttypes, sessions, stats
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0001_initial... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying sessions.0001_initial... OK
  Applying stats.0001_initial... OK
  Applying stats.0002_auto_20180312_1632... OK
  Applying stats.0003_auto_20180321_2336... OK
  Applying stats.0004_auto_20180321_2353... OK
  Applying stats.0005_auto_20180423_1700... OK
System check identified no issues (0 silenced).
test_create_method_calls_create_game_with_correct_fields (stats.tests.test_dataGeneration.TestGameManager) ... FAIL
test_finds_tournament_instance (stats.tests.test_dataGeneration.TestGameManager) ... ok
test_sets_match_length (stats.tests.test_dataGeneration.TestGameManager) ... FAIL
test_can_create_tournaments_given_api_input (stats.tests.test_dataGeneration.TestProcessor) ... ERROR
test_correct_game_mode_being_selected_by_create_game_fucntion (stats.tests.test_dataGeneration.TestProcessor) ... FAIL
test_get_heroes (stats.tests.test_dataGeneration.TestProcessor) ... 
ok
test_get_players (stats.tests.test_dataGeneration.TestProcessor) ... 
ok
test_pass_data_method_calls_model_manager_equivalent (stats.tests.test_dataGeneration.TestProcessor) ...
ok
test_returns_match_ids (stats.tests.test_dataGeneration.TestProcessor) ... 
ok
test_tournament_creation_also_returns_tournament_ids_of_created_objects (stats.tests.test_dataGeneration.TestProcessor) ... FAIL
test_tournament_filter (stats.tests.test_dataGeneration.TestProcessor) ...
ok

======================================================================
ERROR: test_can_create_tournaments_given_api_input (stats.tests.test_dataGeneration.TestProcessor)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\dev\Django code\portfolio_web\stats\tests\timer.py", line 8, in wrapper
    f(*args,**kwargs)
  File "C:\dev\Django code\portfolio_web\stats\tests\test_dataGeneration.py", line 77, in test_can_create_tournaments_given_api_input
    num_tournaments_start = Tournaments.objects.all()
NameError: name 'Tournaments' is not defined

======================================================================
FAIL: test_create_method_calls_create_game_with_correct_fields (stats.tests.test_dataGeneration.TestGameManager)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\dev\Django code\portfolio_web\stats\tests\test_dataGeneration.py", line 143, in test_create_method_calls_create_game_with_correct_fields
    self.fail("finish test")
AssertionError: finish test

======================================================================
FAIL: test_sets_match_length (stats.tests.test_dataGeneration.TestGameManager)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\dev\Django code\portfolio_web\stats\tests\test_dataGeneration.py", line 158, in test_sets_match_length
    self.fail("finish test, implement functionality")
AssertionError: finish test, implement functionality

======================================================================
FAIL: test_correct_game_mode_being_selected_by_create_game_fucntion (stats.tests.test_dataGeneration.TestProcessor)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\dev\Django code\portfolio_web\stats\tests\timer.py", line 8, in wrapper
    f(*args,**kwargs)
  File "C:\dev\Django code\portfolio_web\stats\tests\test_dataGeneration.py", line 136, in test_correct_game_mode_being_selected_by_create_game_fucntion
    self.fail("Make sure the game mode is the correct one!")
AssertionError: Make sure the game mode is the correct one!

======================================================================
FAIL: test_tournament_creation_also_returns_tournament_ids_of_created_objects (stats.tests.test_dataGeneration.TestProcessor)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\dev\Django code\portfolio_web\stats\tests\timer.py", line 8, in wrapper
    f(*args,**kwargs)
  File "C:\dev\Django code\portfolio_web\stats\tests\test_dataGeneration.py", line 93, in test_tournament_creation_also_returns_tournament_ids_of_created_objects
    self.assertEqual(tournament_ids, [data[0]['leagueid'], data[2]['leagueid']])
AssertionError: Lists differ: [] != ['30', '37']

Second list contains 2 additional elements.
First extra element 0:
'30'

- []
+ ['30', '37']

----------------------------------------------------------------------
Ran 11 tests in 0.015s

1 Ответ

0 голосов
/ 08 мая 2018

Тестируемые мной классы хранятся не в отдельных файлах, а в отдельном файле Controller.py, который также создает экземпляр класса с именем API. API занимает около 5-10 минут для инициализации. Python классы (и функции) не объявлены; вместо этого они являются реальными живыми заявлениями. Следовательно, интерпретатор читает и выполняет весь код в файле, а не просто выбирает определения классов. Это было сделано в моих тестовых файлах, когда они импортировали классы из Controller.py

Следовательно, строка в самом конце моего кода, которая была
API_INSTANCE = API(*args)
инициализируется API во время каждого теста. API собирает тонны данных во время инициализации, и это значительно замедляет тестирование во время чтения импорта в тестовых файлах.

Очевидное решение проблемы заключается в том, чтобы обернуть приведенную выше строку кода следующим образом:

if __name__ == '__main__':
    API_INSTANCE = API(*args)

Тот факт, что программа остановилась перед сообщением Creating test database..., должен был указывать на то, что код останавливался до выполнения django.test.TestCase класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...