4

For this sample program

N = int(raw_input());
n  = 0;
sum = 0;
while n<N:

    sum += int(raw_input());
    n+=1;

print sum;  

I have a set of testcases, so I need a python program that invokes the above python program, gives input and should validate the output printed in the console.

Sathish
  • 409
  • 8
  • 24
  • 1
    Turn it into a function and replace the `raw_input()`s with parameters. Also, don't put semicolons at the end of each line. Python doesn't require them. – Blender Jan 19 '13 at 06:39
  • @Blender I am solving [this puzzle](https://www.interviewstreet.com/challenges/dashboard/#problem/4ff1484963063) for which I need to give a lot of input. I am automating that part. Basically I want to emulate what interviewstreet does to the submitted programs. and for ; old habits die hard :) – Sathish Jan 19 '13 at 07:17
  • 3
    You can make a second function that uses `raw_input()` to get user input and feed it into your original function. It'll be easier if you separate the logic from the user interaction. – Blender Jan 19 '13 at 07:19

4 Answers4

3

In a Unix shell, this can be achieved by:

$ python program.py < in > out  # Takes input from in and treats it as stdin.
                                # Your output goes to the out file.
$ diff -w out out_corr          # Validate with a correct output set

You can do the same in Python like this

from subprocess import Popen, PIPE, STDOUT

f = open('in','r')            # If you have multiple test-cases, store each 
                              # input/correct output file in a list and iterate
                              # over this snippet.
corr = open('out_corr', 'r')  # Correct outputs
cor_out = corr.read().split()
p = Popen(["python","program.py"], stdin=PIPE, stdout=PIPE)
out = p.communicate(input=f.read())[0]
out.split()
# Trivial - Validate by comparing the two lists element wise.
siddharthlatest
  • 2,237
  • 1
  • 20
  • 24
1

Picking up the separation thought, I would consider this:

def input_ints():
    while True:
        yield int(raw_input())

def sum_up(it, N=None):
    sum = 0
    for n, value in enumerate(it):
        sum += int(raw_input());
        if N is not None and n >= N: break
    return sum

print sum

To use it, you can do

inp = input_ints()
N = inp.next()
print sum_up(inp, N)

To test it, you can do something like

inp = (1, 2, 3, 4, 5)
assert_equal(sum_up(inp), 15)
glglgl
  • 89,107
  • 13
  • 149
  • 217
  • Could you provide a full example? Script, that provides multiline input to itself or to other script? – WebComer Apr 12 '21 at 21:52
0

I wrote a testing framework (prego) that may be used for your issue::

from hamcrest import contains_string
from prego import TestCase, Task

class SampleTests(TestCase):
    def test_output(self):
        task = Task()
        cmd = task.command('echo your_input | ./your_app.py')
        task.assert_that(cmd.stdout.content, 
                         contains_string('your_expected_output'))

Of course, prego provides more features than that.

david villa
  • 384
  • 4
  • 9
-1

Ordinarily, you'd want to structure your code in a different way, perhaps according to how Blender suggested in his comment. To answer your question, however, you can use the subprocess module to write a script that will call this script, and compare the output to an expected value.

In particular, look at the check_call method.

alexgolec
  • 26,898
  • 33
  • 107
  • 159