Django: testing commands

17 February 2009

When you want to run a command like syncdb in your tests using the test database, then you need to use call_command('syncdb'). Output from commands like that goes to stdout so you can't capture it directly to make sure that it's what you're expecting. This is a way to capture stdout temporarily (mostly from Programming Python, 3rd Ed):

class TestClass(TestCase):
    class Output():
        def __init__(self):
            self.text = ''
        def write(self, string):
            self.text = self.text + string
        def writelines(self,lines):
            for line in lines: self.write(line)

    def test_command(self):
        import sys
        savestreams =sys.stdin,     sys.stdout
        sys.stdout = self.Output()
        call_command('command_you_want_to_test')
        response = sys.stdout.text
        # put things back the way they were
        sys.stdin, sys.stdout = savestreams
        self.assertEquals( response, expected_value )