Skip to content

How to pytest raw_input calls #3504

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

Closed
ridhwaans opened this issue May 24, 2018 · 6 comments
Closed

How to pytest raw_input calls #3504

ridhwaans opened this issue May 24, 2018 · 6 comments
Labels
type: question general question, might be closed after 2 weeks of inactivity

Comments

@ridhwaans
Copy link

ridhwaans commented May 24, 2018

Pytest newbie here
Want to make three test cases that take in None, nonexistant filenames and whitespace filenames for raw_input in main(prompt), and assert the print output
Code in question

#!/usr/bin/env python
import os
import unittest.mock as mock
import pytest

'''Print file
'''
def main(prompt):
  filename = raw_input(prompt) #ask for filename using the given prompt
  if validate(filename):
    for line in open(filename.strip(), "r").readlines(): 
        print line
  else:
    print "The file you selected does not exist, please try again"
    main(prompt) #repeat this function if the use did not give valid input

def validate(input):
    input = input.strip()
    if input is None:
        return False
    elif input == '':
        return False
    elif not (os.path.exists(input)):
        return False
    else:
        return True

if __name__ == "__main__":
    main("Select file in current directory:")

Using: python 2.7, pytest latest version

@pytestbot
Copy link
Contributor

GitMate.io thinks possibly related issues are #699 (Move pytest to Github), #1411 (Pytest stops), #1563 (All pytest tests skipped), #1602 (pytest.print()), and #2838 (Contributing to pytest-dev).

@pytestbot pytestbot added the type: bug problem that needs to be addressed label May 24, 2018
@nicoddemus
Copy link
Member

Hi @ridhwaans,

I think you want something like this (untested):

from mymodule import validate

def test_validate_none():
    assert validate(None) is None

def test_validate_empty():
    assert validate('') is False

def test_validate_f(tmpdir):
    assert validate(tmpdir.ensure('somefile'))

FWIW a function returning None, False or True is not a good approach because None and False are both, well, false, so it's easy to confuse them with one another. I realize that you are probably learning so that's fine.

This would naturally expand to a @pytest.mark.parametrize call, but given that you need the fixture to create the filename this complicates it a little bit so I'm keeping it simple for now.

Testing the actual raw_input call is more complicated, let me know if you want that as well.

Hope this helps

@nicoddemus nicoddemus added type: question general question, might be closed after 2 weeks of inactivity and removed type: bug problem that needs to be addressed labels May 24, 2018
@ridhwaans
Copy link
Author

@nicoddemus yes the test cases are to cover the actual raw_input in main(), I dont care about validate()
I'm following this answer https://stackoverflow.com/a/35851524/ which suggests using mock module

@nicoddemus
Copy link
Member

Yep that's the recommended way. You can also use monkeypatch which is builtin in pytest.

I'm closing this for now but feel free to follow with further questions if you have any.

@ridhwaans
Copy link
Author

ridhwaans commented May 24, 2018

In the end, side_effect did it for me

# valid: 'print-file.py'
# invalid: None, '', 'nonexistent'
def test_01():
    with mock.patch.object(__builtin__, 'raw_input', side_effect=['print-file.py']):
        assert main("Enter filename") == "File exists"

def test_02():
    with mock.patch.object(__builtin__, 'raw_input', side_effect=['  ']):
        assert main("Enter filename") == "File does not exist"

def test_03():
    with mock.patch.object(__builtin__, 'raw_input', side_effect=[None]):
        assert main("Enter filename") == "File does not exist"

def test_04():
    with mock.patch.object(__builtin__, 'raw_input', side_effect=['nonexistent']):
        assert main("Enter filename") == "File does not exist"

> python -m pytest print-file.py
============================================================================================================ test session starts =============================================================================================================
platform darwin -- Python 2.7.12, pytest-3.6.0, py-1.5.3, pluggy-0.6.0
rootdir: <>, inifile:
collected 4 items

print-file.py ....                                                                                                                                                                                                                     [100%]

========================================================================================================== 4 passed in 0.06 seconds ==========================================================================================================

@gwenau
Copy link

gwenau commented Feb 25, 2019

The solution and syntax for Python 3 can be found here
https://forum.learncodethehardway.com/t/testing-input-and-print/1757/3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question general question, might be closed after 2 weeks of inactivity
Projects
None yet
Development

No branches or pull requests

4 participants