Python Forum
how can I test this interactive calculator using pytest
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
how can I test this interactive calculator using pytest
#1
hi,

I have small interactive calculator.
could you please give me a hint how could test it using pytest?
I found e.g. this approach, but have no idea how apply it:
https://stackoverflow.com/questions/5347...simulation
or maybe you have another idea.

thank you for any help!
#!/usr/bin/env python3


class Calculator:
    def __init__(self):
        pass

    def add(self, a, b):
        return a + b

    def sub(self, a, b):
        return a - b
		
#!/usr/bin/env python3
import calculator
import cmd


class InteractiveCalculator(cmd.Cmd):
    prompt = '(icalc) '
    cal = calculator.Calculator()

    def do_add(self, arg):
        """A + B"""
        print(self.cal.add(*parse(arg)))

    def do_sub(self, arg):
        """A - B"""
        print(self.cal.sub(*parse(arg)))

    def do_exit(self, arg):
        """quits from the program"""
        exit()


def parse(arg):
    """Convert a series of zero or more numbers to an argument tuple"""
    return tuple(map(int, arg.split()))


if __name__ == '__main__':
    InteractiveCalculator().cmdloop()
Yoriz write Dec-17-2022, 10:28 AM:
Please post all code, output and errors (in their entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Reply
#2
Personally, I prefer not to use the monkey patching approach and instead allow the classes and functions that I write to take parameters for the things they need. This allows you to pass in fake versions that you can control in tests quite easily. I've written a tutorial on this idea that shows the idea when you want to control time in tests: https://python-forum.io/thread-38222.html. The idea is really the same for controlling where input and output are read from and written to, respectively (and in fact the functional test I show at the end does show this, at least for output).

In your specific case, you're using cmd.Cmd and its documentation does say that you can pass in parameters for input and output (which default to the console as you'd expect).

So, I'd say you might want to explore working with those parameters to Cmd so that you can make use of them in your tests.
buran likes this post
Reply
#3
I tried this approach (https://www.youtube.com/watch?v=dN-pVt7i4Us)
from icalc import InteractiveCalculator  # The module which contains the call to input


def test_function_1(capsys):
    InteractiveCalculator.do_add(arg="add 1 2")
    stdout, stderr = capsys.readouterr()
    assert stdout == "3"
but get this error
could you please help me?
____________________________________________________ test_function_1 ____________________________________________________

capsys = <_pytest.capture.CaptureFixture object at 0x7fd5364e6b30>

    def test_function_1(capsys):
>       InteractiveCalculator.do_add(arg="add 1 2")
E       TypeError: InteractiveCalculator.do_add() missing 1 required positional argument: 'self'

icalc_test.py:5: TypeError
this line
InteractiveCalculator.do_add(arg="add 1 2")
misses "self", but I do not understand how I should add it.

(Dec-17-2022, 11:06 AM)ndc85430 Wrote: Personally, I prefer not to use the monkey patching approach and instead allow the classes and functions that I write to take parameters for the things they need. This allows you to pass in fake versions that you can control in tests quite easily. I've written a tutorial on this idea that shows the idea when you want to control time in tests: https://python-forum.io/thread-38222.html. The idea is really the same for controlling where input and output are read from and written to, respectively (and in fact the functional test I show at the end does show this, at least for output).

In your specific case, you're using cmd.Cmd and its documentation does say that you can pass in parameters for input and output (which default to the console as you'd expect).

So, I'd say you might want to explore working with those parameters to Cmd so that you can make use of them in your tests.
Reply
#4
This solves my previous issue with "self"

#!/usr/bin/env python3
from icalc import InteractiveCalculator


def test_function_1(capsys):
    my_calc = InteractiveCalculator()
    my_calc.do_add(arg="1 2")
    stdout, stderr = capsys.readouterr()
    assert stdout == "3"
but I cannot get this trailing newline away, even with rstrip() like this
my_calc.do_add(arg="1 2".rstrip())
capsys = <_pytest.capture.CaptureFixture object at 0x7f5ee1256500>

    def test_function_1(capsys):
        my_calc = InteractiveCalculator()
        my_calc.do_add(arg="1 2".rstrip())
        stdout, stderr = capsys.readouterr()
>       assert stdout == "3"
E       AssertionError: assert '3\n' == '3'
E         - 3
E         + 3

icalc_test.py:9: AssertionError
Do you have an idea?




(Dec-17-2022, 11:06 AM)ndc85430 Wrote: Personally, I prefer not to use the monkey patching approach and instead allow the classes and functions that I write to take parameters for the things they need. This allows you to pass in fake versions that you can control in tests quite easily. I've written a tutorial on this idea that shows the idea when you want to control time in tests: https://python-forum.io/thread-38222.html. The idea is really the same for controlling where input and output are read from and written to, respectively (and in fact the functional test I show at the end does show this, at least for output).

In your specific case, you're using cmd.Cmd and its documentation does say that you can pass in parameters for input and output (which default to the console as you'd expect).

So, I'd say you might want to explore working with those parameters to Cmd so that you can make use of them in your tests.
Reply
#5
Why would you think you need to strip anything from the input? The failing assertion is telling you the output contains the new line character.

There's also no need to keep quoting someone's post in its entirety.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  call an instance of a class in the interactive nzcan 3 2,940 Aug-23-2018, 10:47 AM
Last Post: nzcan

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020