ich ein neues tat erscheint analysieren Sie Ihren Code. Das Problem dort ist
- Sie definieren zwei Ströme für stdout und stderr. TextTextRunner verwendet nur einen Stream: sys.stderr standardmäßig.
- TextTestRunner verwendet standardmäßig sys.stderr und dies ist nicht Ihre sys.stderr. Das scheint seltsam, siehe später. Ihr Code funktioniert so, als hätte er keinen anderen Ausgabestream definiert.
Die Situation ändert sich, wenn Sie TextTextRunner() aufrufen, nicht mit ihren Standardeinstellungen, aber wenn Sie passieren explizit Ihre neu definiert sys.stderr. Nun wird die Ausgabe auf Ihre Datei umgeleitet werden:
# does not at all what you want (writes output to stderr):
tests = unittest.TextTestRunner(descriptions=True, verbosity=2).run(suite)
# does not everything what you want (writes output to file only):
tests = unittest.TextTestRunner\
(stream=sys.stderr, descriptions=True, verbosity=2).run(suite)
Eine Anforderung erfüllt ist (schreiben in eine Datei) aber der andere nicht. Dies liegt daran, dass nur einer Ihrer definierten Streams verwendet wird (der Stream, den Sie an TextTestRunner übergeben haben). Für die zweite Anforderung (in die Konsole schreiben) muss es eine Möglichkeit geben, von einem Stream (dem umgeleiteten stderr) in zwei Ausgabegeräte zu schreiben. Dies ist meiner Meinung nach nur möglich, wenn Sie die Ihrer StreamToLogger.write()
Methode in geeigneter Weise ändern:
def write(self, buf) :
my_console_stream_instance.write(buf)
my_file_stream_instance.write(buf)
wo my_console_stream_instance
der Strom ist, der in die Konsole schreibt und my_file_stream_instance
ist der Strom, der in die Datei schreibt. Also schauen Sie bitte auf das folgende Beispiel, das tun sollten, was Sie wollen:
class StreamToLogger(object):
def __init__(self):
self.terminal = sys.stderr
self.log = open("logger.log", "w")
def write(self, buf):
self.terminal.write(buf) # write to stderr
self.log.write(buf) # write to file
sys.stderr = StreamToLogger()
suite = suite()
tests = unittest.TextTestRunner\
(stream=sys.stderr, descriptions=True, verbosity=2).run(suite)
Nun gibt es wirklich zwei Ausgänge: eine auf dem Bildschirm und einer in die Datei.
Aber warum müssen Sie sys.stderr an den Stream-Parameter von TextTestRunner übergeben? Auf den ersten Blick scheint es dasselbe zu sein. Aber in der Referenz Python Sprache im Kapitel function definitions ist die Erklärung:
Standardparameterwerte ausgewertet werden, wenn die Funktionsdefinition ist ausgeführt.Dies bedeutet, dass der Ausdruck einmal ausgewertet wird, wenn die -Funktion definiert ist und derselbe "vorberechnete" Wert für jeden Aufruf verwendet wird. Dies ist besonders wichtig, um zu verstehen, wenn ein Standardparameter ein veränderbares Objekt ist.
Der Standard sys.stderr des stream-Parameters in TextTestRunner wird vor der Ausführung der stderr-Neudefinition ausgewertet. Deshalb müssen wir unseren neu definierten sys.stderr sowieso bestehen. Ein kleiner Beweis ist: Definieren Sie sys.stderr vor importieren Sie unittest: Der Code funktioniert gut, ohne die neu definierte sys.stderr übergeben.
Ich möchte die Ausgabe schreiben von 'Tests = unittest.TextTestRunner (Beschreibungen = True, Ausführlichkeit = 2) .run (suite) ' Logger-Datei und Konsole. Tatsächlich schreibt es nur in Logger-Datei, aber nicht auf der Konsole. –
Die Antwort von Amith Koujalgi in [diesem Beitrag] (http://stackoverflow.com/questions/14906764/how-to-redirect-stdout-to-both-file-and-console-with-scripting) ist die Lösung. Fügen Sie einfach einen 'stream = sys.stdout' im TextTestRunner() - Aufruf und der erwähnten Klasse' Logger' hinzu. – Humbalan
diese Lösung funktioniert nicht für mich. Ich denke, es gibt einen Konflikt zwischen testrunnners "stderr" und "sys.stderr = sl", das in meinem Beispielcode ist (siehe Frage) –