Continue / end line in doctest

I use doctest.testmod() to do basic testing. I have a function that returns a long string, like get_string() . Sort of:

 def get_string(a, b): r''' (a, b) -> c >>> get_string(1, 2) 'This is \n\na long \n string with new \ space characters \n\n' # Doctest should work but does not. ''' return ('This is \n\na long \n string ' + \ 'with new space characters \n\n') 

The problem is that doctest does not pass because it expects a single line of the line, and treats the wrapper as the \n character. Is there any way around this?

PS: This is not the actual function I'm working with, but the minimum version for you.

+5
source share
5 answers

I don’t think you understood how doctest works. It does not check whether the output is somehow "equivalent", it checks whether the output is identical (only with very minor possible options, for example using ellipsis). From the documentation:

The doctest module doctest for pieces of text that look like interactive Python sessions, and then runs those sessions to make sure they work exactly as shown.

Doctest matches output ( not a string literal, python expression, or something else. Source bytes) with the contents of the example you provided. Since he does not know that the text between quotation marks is a string literal, he cannot interpret it the way you want.

In other words: the only thing you can do is simply put all the output on one line, as in:

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

If the output of this is too long, you can try changing the example to create a shorter string (for example, cut it into 50 characters: get_string(1, 2)[:50] ). If you look at the teachings of different projects, you will find different hacks to make the doctrines more readable, while providing a reliable conclusion.

+3
source

If you do a test against a long single-line output, you can save the doctest matching string within 80 characters for PEP8 goodness using the doctest ELLIPSIS function, where ... will match any string. Although it is commonly used for variable output, such as object addresses, it works fine with a long fixed output, for example:

 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\na long \n string ' 'with newline characters \n\n') 

In comparison, there is a slight loss of accuracy, but this is usually not critical for tests.

+3
source

You can use the NORMALIZE_WHITESPACE option (see also the full list of options ).

Here is an example from the documentation for the doctrine :

 >>> 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] 
+2
source

From the doctest docs:

If you continue the line through a backslash in an interactive session or for some other reason use a backslash, you should use an raw docstring that will save your backslashes exactly the same way you type them:

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

Otherwise, you can use double backslash.

+1
source

A simple solution is >>> repr(get_string(1,2)) ; which avoids new lines and uses a single line line only for the test.

I would prefer a solution where you can say:

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

In your case, this is a problem because you have a space.

Also note that it is not possible to check the line continuation character.

 "a" + \ "b" 

exactly matches

 "a" + "b" 

namely "ab"

+1
source

Source: https://habr.com/ru/post/1214454/


All Articles