2015-03-02 17 views
5

Ich verwende doctest.testmod(), um einige grundlegende Tests durchzuführen. Ich habe eine Funktion, die eine lange Zeichenfolge zurückgibt, sagen wir get_string(). Etwas wie:Zeilenfortsetzung/Umbruch in doctest

def get_string(a, b): 
    r''' (a, b) -> c 

    >>> get_string(1, 2) 
    'This is \n\n a long \n string with new \ 
    space characters \n\n' 
    # Doctest should work but does not. 

    ''' 
    return ('This is \n\n a long \n string ' + \ 
      'with new space characters \n\n') 

Das Problem ist, dass der doctest nicht vergeht, weil es nur eine einzige Zeile String erwartet, und es wird die Wrap als \n Zeichen zu behandeln. Gibt es eine Möglichkeit, dies zu umgehen?

PS: Dies ist nicht die eigentliche Funktion, mit der ich arbeite, aber eine minimale Version für Sie.

+0

Hinweis: in Ihrem Code in der 'return' Linie die Backslash ist ** ** nutzlos, wenn nicht schädlich. Klammern reichen für fortlaufende Zeilen (und sie sollten sowieso bevorzugt werden). Außerdem ist sogar das "+" überflüssig. – Bakuriu

Antwort

3

Ich glaube nicht, Sie zu verstehen, wie doctest funktioniert. Es tut nicht überprüfen, ob die Ausgabe irgendwie "gleichwertig" ist, überprüft es nur, ob die Ausgabe identisch ist (mit nur sehr geringen möglichen Variationen, wie die Verwendung von Auslassungspunkten). Aus der Dokumentation:

Die doctest Modul sucht nach Textstücken, die wie interaktive Python-Sitzungen aussehen, führt und dann diese Sitzungen zu überprüfen, ob sie genau wie gezeigt arbeiten.

doctest entspricht dem Ausgang (nicht Zeichenkettenliteral, ein Python-Ausdruck oder was auch immer. Raw Ausgangsbytes) mit dem Inhalt der Beispielausgabe Sie zur Verfügung stellen. Da es nicht weiß, dass der Text zwischen Anführungszeichen ein Zeichenfolgenliteral darstellt, kann er nicht so interpretiert werden, wie Sie möchten.

Mit anderen Worten: das einzige, was Sie tun können, ist, einfach die ganze Ausgabe auf eine Zeile zu setzen, wie in:

>>> get_string(1, 2) 
    'This is \n\n a long \n string with new space characters \n\n' 

Wenn der Ausgang dieses zu lang ist, können Sie versuchen, das Beispiel zu ändern produzieren Sie eine kürzere Zeichenfolge (z. B. schneiden Sie sie auf 50 Zeichen: get_string(1, 2)[:50]). Wenn Sie sich Doctests verschiedener Projekte ansehen, finden Sie verschiedene Hacks, um Doctests lesbarer zu machen und gleichzeitig eine zuverlässige Ausgabe zu erhalten.

+0

Ah jetzt macht alles Sinn. Vielen Dank! – JCOC611

1

Von doctest der docs:

Wenn Sie eine Linie über backslashing in einer interaktiven Sitzung, oder aus irgendeinem anderen Grund verwenden, um einen umgekehrten Schrägstrich weiter, sollten Sie eine rohe docstring verwenden, die Ihre Schrägstriche erhalten wird genau so, wie Sie sie eingeben :

>>> def f(x): 
...  r'''Backslashes in a raw docstring: m\n''' 
>>> print f.__doc__ 
Backslashes in a raw docstring: m\n 

Andernfalls könnten Sie einen doppelten Backslash verwenden.

+0

Ich verwende bereits rohe Zeichenketten für den Docstring Doe. – JCOC611

1

Eine einfache Lösung ist >>> repr(get_string(1,2)); Das wird neuen Zeilen entgehen und eine einzeilige Zeichenfolge nur für den Test verwenden.

würde ich eine Lösung bevorzugen, wo Sie sagen können:

>>> get_string(1,2) 
first line 
second line 

fourth 

In Ihrem Fall ist dies ein Problem ist, weil man weiß Raum haben Hinter.

Beachten Sie auch, dass es nicht möglich ist, das Zeilenfortsetzungszeichen zu testen.

"a" + \ 
"b" 

ist genau das gleiche wie

"a" + "b" 

nämlich "ab"

+0

Hört sich nach der besten Lösung an, obwohl ich * auch gerne nach Newline-Zeichen suchen würde, da in diesem Fall in meinem Programm Probleme auftreten könnten, wenn sie schlecht platziert sind. Trotzdem danke! – JCOC611

+0

'repr()' erlaubt genau das, also verstehe ich deinen Kommentar nicht. –

+0

Eigentlich war ich nicht in der Lage, den doctest mit 'repr (...)' zu implementieren. Es entkommt den neuen Zeilen, aber die Zeilenfortsetzung wird immer noch als Zeilenumbruch interpretiert und der Test wird nicht bestanden. Könnten Sie mir ein Beispiel zeigen, wie es aussehen würde? – JCOC611

3

Wenn Sie einen Test gegen eine lange einzeilige Zeichenfolge in der Ausgabe zu machen, Sie die doctest Matchstring innerhalb von 80 Zeichen für PEP8 Güte halten durch doctest des ELLIPSIS-Funktion, wo ... beliebige Zeichenfolge übereinstimmen. Während es im Allgemeinen für variable Ausgänge wie Objektadressen verwendet wird, arbeitet es ganz gut mit (lang) fester Ausgang als auch, zum Beispiel:

def get_string(a, b): 
    r''' (a, b) -> c 

    >>> get_string(1, 2) # doctest: +ELLIPSIS 
    'This is ... string with newline characters \n\n' 
    ''' 
    return ('This is \n\n a long \n string ' 
      'with newline characters \n\n') 

Es gibt einen geringen Verlust an Genauigkeit in der Anpassung, aber das ist normalerweise nicht kritisch für Tests.

2

Sie können die Option NORMALIZE_WHITESPACE verwenden (siehe auch full list of options). Hier

ist ein Beispiel aus doctest documentation:

>>> print range(20) # doctest: +NORMALIZE_WHITESPACE 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
10, 11, 12, 13, 14, 15, 16, 17, 18, 19] 
Verwandte Themen