Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make pytest run doctests as well #29

Closed
wants to merge 9 commits into from

Conversation

fabianvf
Copy link

This is my little hack to get :Pytest to capture and run doctests. Currently only works when running doctests for a file, not sure how much it would take to get it to capture and run doctests for classes/methods/functions. To run a doctest, you need to use this sort of syntax:

py.test --doctest-modules path/to/file.py::path.to.file.function_name

py.test --doctest-modules path/to/file.py::path.to.file.ClassName

py.test --doctest-modules path/to/file.py::path.to.file.ClassName.method_name

and I'm not sure how to get access to those from inside pytest.vim (need to spend some more time looking at what's going on).
If it were possible to get that information, might be better to have a :Pytest doctest [file | class | method | function] command.

My temporary fix to #28

@alfredodeza
Copy link
Owner

right I agree, this needs to be an explicit call. Give me a bit to look into it

@fabianvf
Copy link
Author

Actually, I'm getting pretty close I think. My current approach is to add doctest as an additional optional argument, which if provided will change how the path is constructed and make pytest run with --doctest-modules

@fabianvf
Copy link
Author

PR update soon to follow

@fabianvf
Copy link
Author

K, updated. The current PR works for functions run normally, or with doctest functions.

Current syntax is:

:Pytest function verbose doctest

or

:Pytest function doctest

@fabianvf
Copy link
Author

All right, I think I have most everything functioning. Let me know if you think the approach is sane, I'm happy to respond to review and change it up.

let cmd = 'py.test'
if (a:doctest == 'True')
let cmd = cmd . ' --doctest-modules'

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is missing an endif

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops!

@alfredodeza
Copy link
Owner

I couldn't see any changes to the parsing, trying your branch it doesn't parse correctly when there are failures. Have you tried this on all the Python objects? (function, method, class, file, etc..?)

@fabianvf
Copy link
Author

Strange, I have it working locally on function/method/class/file doctests (project doesn't collect doctests atm though), both for passing and failing doctests

@fabianvf
Copy link
Author

Here is a python file that works locally for me (for class, function, method and file):

def hello(name):
    '''
    >>> print(hello('Bob'))
    Hello Bob
    '''
    return 'Hello ' + name


class GreetingsFactory(object):
    '''
    >>> print(GreetingsFactory().greeting)
    Hello
    >>> print(GreetingsFactory('Goodbye').greeting)
    Goodbye
    '''

    greeting = 'Hello'

    def __init__(self, *args):
        if len(args) == 1:
            self.greeting = args[0]

    def mk_greeting(self, greeting=None):
        '''
        >>> print(GreetingsFactory('Goodbye').mk_greeting()('Bob'))
        Goodbye Bob
        >>> print(GreetingsFactory().mk_greeting()('Karl'))
        Hello Karl
        '''
        def inner(name):
            return (greeting or self.greeting) + ' ' + name
        return inner

@alfredodeza
Copy link
Owner

If they all pass it seems it works. Try changing the 'Hello ' string in the hello func to return 'Hi ' to see how that fails and how it looks.

@fabianvf
Copy link
Author

Ah, I think I see what you mean, in non-verbose mode?

In verbose mode, it prints:

============================= test session starts ==============================
platform darwin -- Python 2.7.10 -- py-1.4.30 -- pytest-2.6.3 -- /Users/fabian/Envs/scrapi/bin/python2.7
plugins: cov
collecting ... collected 3 items

example.py::[doctest] example.GreetingsFactory PASSED
example.py::[doctest] example.GreetingsFactory.mk_greeting PASSED
example.py::[doctest] example.hello FAILED

=================================== FAILURES ===================================
___________________________ [doctest] example.hello ____________________________
002     '''
003     >>> print(hello('Bob'))
Expected:
    Hello Bob
Got:
    Hi Bob

/Users/fabian/code/cos/scrapi/example.py:3: DocTestFailure
====================== 1 failed, 2 passed in 0.02 seconds ======================

which looks ok to me.

But it seems to have no real output in non-verbose mode. I'll look into it...

@fabianvf
Copy link
Author

Yeah, it just seems to be because the failure output for doctests is completely different than normal test failures. I haven't had time to dive into the parsing logic yet, but I'll look into it as soon as I do.

@alfredodeza
Copy link
Owner

This PR has become too stale. Feel free to re-open when the parsing is improved. Thanks for taking a stab at it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants