How to use unit tests with a Python script that contains an input call?

How to use unit tests with a Python script that contains an input call?

Any time I try to use a unit test to test a program that has an input call anywhere inside of it (even if it’s not in the section of code I am testing), I receive the following error:

Running tests failed

Traceback (most recent call last):
  File "_test_runnertest_runner.py", line 2, in <module>
    import _test_runnertest_suite
  File "/home/runner/254-Distance-Formula-Solution/_test_runnertest_suite.py", line 2, in <module>
    from main import *
  File "/home/runner/254-Distance-Formula-Solution/main.py", line 17, in <module>
    main()
  File "/home/runner/254-Distance-Formula-Solution/main.py", line 10, in main
    x1 = float(input())
RuntimeError: input(): lost sys.stdin

exit status 1

The unit test I am executing is displayed below. I am only testing the function distance() which does not have any input calls in it.

Unit Test:

def test_distance():
  self.assertEqual(distance(1, 1, -1, -1), math.sqrt((-1 - 1)**2 + (-1 - 1)**2))

Here is my program that I am testing. There are two different versions that I tried, but both give the same error. This error will occur anytime you are using the replit Python unit tests to test a section of code if there is an input() call anywhere in the program. Is there any way around this?

Version 1:

import math

def distance(x1, y1, x2, y2):
  return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)

def main():
  x1 = float(input())
  y1 = float(input())
  x2 = float(input())
  y2 = float(input())
  print(distance(x1, x2, y1, y2))

main()

Version 2:

import math

def distance(x1, y1, x2, y2):
  return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)

x1 = float(input())
y1 = float(input())
x2 = float(input())
y2 = float(input())
print(distance(x1, x2, y1, y2))
2 Likes

This seems to be a bug in replit’s testing framework. I am encountering the same issue.

In this case, I am actually trying to mock the input function to provide my own inputs which is necessary for tests that also needs tests the main function for input and output.

Not been able to find a work around yet. But it’s causing quite a bind.

Setting variables on the module to mock the input function, before running the test:

import main
def my_input(prompt='', /):
  return '5'
main.input = my_input
main.main()

A closure or custom object allows more customization of the return value.
I don’t use unit tests so I don’t know if it’ll work.