Почему 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. Это было одно из тех утр.

Вернуться на верх