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
GitMate.io thinks possibly related issues are https://github.com/pytest-dev/pytest/issues/699 (Move pytest to Github), https://github.com/pytest-dev/pytest/issues/1411 (Pytest stops), https://github.com/pytest-dev/pytest/issues/1563 (All pytest tests skipped), https://github.com/pytest-dev/pytest/issues/1602 (pytest.print()), and https://github.com/pytest-dev/pytest/issues/2838 (Contributing to pytest-dev).
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 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
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.
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 ==========================================================================================================
The solution and syntax for Python 3 can be found here
https://forum.learncodethehardway.com/t/testing-input-and-print/1757/3