Reputation: 3252
I wrote a simple command line utility that accepts a text file and searches for a given word in it using the click module.
sfind.py
import click
@click.command()
@click.option('--name', prompt='Word or string')
@click.option('--filename', default='file.txt', prompt='file name')
@click.option('--param', default=1, prompt="Use 1 for save line and 2 for word, default: ")
def find(name, filename, param):
"""Simple program that find word or string at text file and put it in new"""
try:
with open(filename) as f, open('result.txt', 'w') as f2:
count = 0
for line in f:
if name in line:
if param == 1:
f2.write(line + '\n')
elif param == 2:
f2.write(name + '\n')
count += 1
print("Find: {} sample".format(count))
return count
except FileNotFoundError:
print('WARNING! ' + 'File: ' + filename + ' not found')
if __name__ == '__main__':
find()
Now I need to write a test using unittest (using unittest is required).
test_sfind.py
import unittest
import sfind
class SfindTest(unittest.TestCase):
def test_sfind(self):
self.assertEqual(sfind.find(), 4)
if __name__ == '__main__' :
unittest.main()
When I run the test:
python -m unittest test_sfind.py
I get an error
click.exceptions.UsageError: Got unexpected extra argument (test_sfind.py)
How can I test this click command?
Upvotes: 7
Views: 4819
Reputation: 5254
For those wanting to test exceptions in a click command, I have found this way to do it:
def test_download_artifacts(
self,
):
runner = CliRunner()
# test exception raised for invalid dir format
result = runner.invoke(
my_module.download_artifacts,
'--bucket_name my_bucket \
--artifact_dir artifact_dir'.split(),
input='2')
print(f"result.exception: {result.exception}")
assert "Enter artifact_dir ending" in str(result.exception)
Upvotes: 2
Reputation: 49774
You can not simply call a click command and then expect it to return. The decorators applied to make a click command considerably change the behavior of the function. Fortunately the click frameworks provides for this through the CliRunner
class.
Your command can be tested via unittest with something like this:
import unittest
import sfind
from click.testing import CliRunner
class TestSfind(unittest.TestCase):
def test_sfind(self):
runner = CliRunner()
result = runner.invoke(
sfind.find, '--name url --filename good'.split(), input='2')
self.assertEqual(0, result.exit_code)
self.assertIn('Find: 3 sample', result.output)
Upvotes: 13