Почему call_command( ... stdout=f ) не перехватывает stdout? Я в растерянности
Помогите! Я не могу заставить работать тестирование для моей команды управления. Команда работает нормально при тестировании вручную:
$ ./manage.py import_stock stock/tests/header_only.csv
Descriptions: 0 found, 0 not found, 0 not unique
StockLines: 0 found, 0 not found, 0 not unique
но не в тесте. Он выводится в stdout, несмотря на то, что call_command
указывает stdout=f
(f
является StringIO()
). Запустив тест, я получаю
$ ./manage.py test stock/tests --keepdb
Using existing test database for alias 'default'...
System check identified no issues (0 silenced).
Descriptions: 0 found, 0 not found, 0 not unique
StockLines: 0 found, 0 not found, 0 not unique
Returned
""
F
======================================================================
FAIL: test_001_invocation (test_import_stock_mgmt_cmd.Test_010_import_stock)
make sure I've got the basic testing framework right!
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/nigel/django/sarah/silsondb/stock/tests/test_import_stock_mgmt_cmd.py",line 32, in test_001_invocation
self.assertIn('Descriptions: 0', text) # do-nothing
AssertionError: 'Descriptions: 0' not found in ''
----------------------------------------------------------------------
Ran 1 test in 0.006s
FAILED (failures=1)
Preserving test database for alias 'default'...
Тестовый код, который генерирует это, выглядит следующим образом. print(f'Returned\n"{text}"')
показывает, что я получаю нулевую строку обратно от do_command
(который создает StringIO() и вызывает call_command
). То, что я пытаюсь перехватить, записывается в консоль, как и при прямом вызове команды.
import csv
import io
from django.core.management import call_command
from django.core.management.base import CommandError
from django.test import TestCase
class Test_010_import_stock( TestCase):
def do_command( self, *args, **kwargs):
with io.StringIO() as f:
call_command( *args, stdout=f )
return f.getvalue()
def test_001_invocation(self):
""" make sure I've got the basic testing framework right! """
text = self.do_command( 'import_stock', 'stock/tests/header_only.csv')
print(f'Returned\n"{text}"')
print()
self.assertIn('Descriptions: 0', text) # do-nothing
self.assertIn('Stocklines: 0', text )
Ответ на собственный вопрос. Это была глупая путаница в самой команде управления.
Я знаю, что вы не использовали print
, но должны использовать self.stdout.write()
в команде управления
Но в результате мозгового штурма получилось sys.stdout.write
и, по чистой невезухе, эта конкретная команда импортировала sys. Это было одно из тех утр.