4

I'm using Python 2.7 to create a game. I want to use a test script to check the methods in my main file, but I'm running into a slight issue.

In the main script, I ask if the user wants to play the game, using raw_input(). Unfortunately, this means that when I run the test script using Windows PowerShell, the console asks the user for input and I have to manually type an answer. With repeated testing, manual typing is getting tedious.

(MWE and output below: Here, the test script should generate a 'n' because it's only checking the method, and not the gameplay itself. The actual method does some calculation, prints a statement, and outputs a string.)

This brings me to my question: Is there some way to write a test script that will automatically generate an input for raw_input()? Alternately, is there some other way to accept user input in the main game file that the test script can simulate?

Thoughts: While searching for an answer, I've seen some information about mock...I haven't used that before and also mock seems to assert an outcome from a particular statement, but I just want the test file to effectively bypass that prompt. I could just remove that (y/n) prompt from the game script, but this seems like a good learning opportunity...

MWE.py (the game file)

def game_method(stuff):
    """Calculates stuff for game"""
    stuff_out = 'foo'
    return stuff_out

""" Check user wants to play the game """
startCheck = raw_input('Would you like to play the game? (y/n) > ')
if (startCheck.lower() == 'y'):
    play = True
else:
    play = False

""" Set up a game to play"""
while (play==True):
    # Do stuff
    stuff_out = game_method(stuff)
else:
    print "\n\tGoodbye.\n\n"

MWE-test.py (the test script)

import MWE

def check_game(input):
    string_out = MWE.game_method(input)
    return string_out

""" Test code here """
input = 7
string_output = check_game(input)
print "===============\n%s\n===============\n\n\n" % (string_output == 'foo')

Console output:

PS C:\dir> python MWE-test.py
Would you like to play the game? (y/n) > n

        Goodbye.


===True===

PS C:\dir>
Wokpak
  • 573
  • 6
  • 16
user2441511
  • 11,036
  • 3
  • 25
  • 50
  • I don't know the syntax for Windows, but look into input redirection. You tell the program to take input from a file, and have the commands in there. –  May 20 '16 at 13:47
  • Consider creating a [StringIO](https://docs.python.org/2.7/library/stringio.html) object and replacing `sys.stdio` with it. – aghast May 20 '16 at 14:08
  • @AustinHastings I'm new to the StringIO idea. It seems like it pulls inputs or writes outputs to a file, so that could work. But I'm not sure how to pull from there. Would I need to redefine `raw_input()` to be a StringIO instead? Where would I even define that? Would that go inside the main file, or the test file? I'm hoping to leave the game file as is, or change it in some what that it will work in general on any machine. Thoughts? Could you please provide me with some more information? – user2441511 May 20 '16 at 14:23
  • @JETM I think that's an interesting idea. It looks like command redirection will place inputs from a file on the command line. However, I think that raw_input() pauses the script to wait for user input, so I'm not sure that would work. Or maybe I'm not understanding input redirection/raw_input() correctly. I think then I would need to use something besides raw_input()... – user2441511 May 20 '16 at 14:28

2 Answers2

0

I was interested in this so did some searching for raw_input redirection. Austin Hashings suggestion work when you use it inside the script where raw_input is called:

import sys
import StringIO

def game_method(stuff):
    """Calculates stuff for game"""
    stuff_out = 'foo'
    return stuff_out

# Specity your 'raw_input' input
s = StringIO.StringIO("n")
sys.stdin = s

""" Check user wants to play the game """
startCheck = raw_input('Would you like to play the game? (y/n) > ')

sys.stdin = sys.__stdin__

if (startCheck.lower() == 'y'):
    play = True
else:
    play = False

""" Set up a game to play"""
while (play==True):
    # Do stuff
    stuff_out = game_method(stuff)
else:
    print "\n\tGoodbye.\n\n"

Unfortunately, this doesn't seem to work outside of the script. This question looks at the problem and the general consensus is that you don't really need to include raw_input in your testing as its a language function, so you can pass in the input using some other method and simply mimic the raw_input using some other method such as:

  • Add an additional input to your game function and pass it from your test script
  • Launch the game script with arguments from your test script
Community
  • 1
  • 1
Wokpak
  • 573
  • 6
  • 16
0
import MWE

def check_game(input):
    string_out = MWE.game_method(input)
    return string_out

""" Test code here """
input = 7

old_sysin = sys.stdin
server_input = cStringIO.StringIO("y" + "\n")
sys.stdin = server_input

string_output = check_game(input)
print "===============\n%s\n===============\n\n\n" % (string_output 
== 'foo')