jkeenan1 has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a test suite which a user will run either with prove or with make test as part of module installation. The module distro includes an executable script located in the scripts/ directory.

In the executable script -- which we'll call login.pl -- I have the following code:

my $config = {}; print "Type your username: "; chomp ($config->{username} = <>); system "stty -echo" and croak "Unable to turn off echoing to STDOUT"; print "Type your password: "; chomp ($config->{password} = <>); print "\n"; system "stty echo" and croak "Unable to turn echoing to STDOUT back on";

It DWIMs. But now suppose that in one of my test files I want to call login.pl, have the user enter her username and password and then use that data to log in to a server. If the login is successful, a string will be returned whose content I would like to validate with Test::More::like. How can I do that?

I have found that if I enter this code directly in a file where Test::More has been used, the prompt is never printed but the program hangs. I've explored both Test::Expect and IPC::Run, but I haven't been able to match anything in the documentation of either module to my needs.

Suggestions? Thanks in advance.

Jim Keenan

Replies are listed 'Best First'.
Re: Interactive prompts inside a test harness
by Joost (Canon) on Nov 07, 2006 at 21:54 UTC
Re: Interactive prompts inside a test harness
by Old_Gray_Bear (Bishop) on Nov 08, 2006 at 00:42 UTC
    Take a look at the Perl Testing, A Developer's Notebook, Langworth and chromatic, page 169 - "Testing Interactive Programs"; this is a quick write-up on Test::Expect. The example shown is a test harness for an iterative routine; it keeps prompting the User until it receives a 'quit-it' string ("\n" in this case).

    Last Monday, I was also confronted with the need to automate 'Password, Please!' routine in a test-harness. I did a bit of research, read the PT section, and said "Eureka". I then ran into a spot of difficulty dealing with password prompting - I was only prompting one time and then moving on, rather than re-issuing a prompt in a loop and waiting for the User to say 'done, enough'. After a bit of playing around, I sorted a way to allow me to get this behavior to work in the context of Expect::Simple. Last Thursday I sent a patch off to the maintainer (Leon Brocard).

    Basically, the patch adds the prompt-string and the quit-string to the results obtained from the test-code, before the results are passed on to Expect::Simple. This results in Expect::Simple returning the right stuff to the test-harness, and then, since the quit-string appeared following the 'next prompt', Expect::Simple cleans up and exits normally. I set things up so that you can call-out this behavior at will via a parameter passed into the Test::Expect::expect_run() routine.

    /msg me if you need the work-around immediately, or wait until it gets incorporated formally into Test::Expect.

    ----
    I Go Back to Sleep, Now.

    OGB

Re: Interactive prompts inside a test harness
by Firefly258 (Beadle) on Nov 08, 2006 at 00:06 UTC
    You should really be using one of the Term::Readline::* modules to be prompting for the password rather than the stty which isn't installed or readily useable on all operating systems. Moreover, it's the most error-prone executable perl can call in my experience. As for authentication on the server and recieving a return value, no info has been given on the particulars, so we'll just have to presume that a value representing TRUE is returned on a successful login and FALSE otherwise
    my $status = authenticate($username, $password); if ($status) { #if authenticate() returned a 'TRUE' value # get the test string from somewhere # and then use it in the following test my $is_like = Test::More->like( get_string(), qw/like_regex/, $test_name); }
      Firefly258 wrote:

      You should really be using one of the Term::Readline::* modules to be prompting for the password ...

      I was shying away from Term::ReadLine at first because it wasn't core, and I don't want to have to include non-core modules in this tarball for my code to work. But just now I typed:

      corelist Term::ReadLine

      ... and discovered:

      Term::ReadLine was first released with perl 5.002

      ... so I'll definitely be making use of it. Thank you very much.

      UPDATE:

      Wait! Perhaps I won't be making use of it after all. It's non-core module Term::ReadKey that you use to turn off echoing -- not Term::ReadLine. Correct?

      Jim Keenan
Re: Interactive prompts inside a test harness
by jethro (Monsignor) on Nov 07, 2006 at 23:34 UTC
    Could you elaborate on what you want to test? The server or the client? Couldn't you test them seperately?

    I would avoid an interactive test like the devil. Fake the server locally. Then you a) know the password already and b) don't test the internet connection as well.

Re: Interactive prompts inside a test harness
by Anonymous Monk on Nov 08, 2006 at 04:38 UTC

    Aye,
    You could use either the Term::Readkey (a la cooked mode) or Term::Readline::Gnu (a la shadow_redisplay) to achieve the same goal. I think i meant to say, use either of the Term::Read* modules.

    The reason i am inclined to using the cpan modules (and suggested likewise) is that their whole point of the existance of the CPAN modules is to help the perl user write portable code. It's all good shying away from CPAN modules, you almost always can write cleaner, shorter, faster code without them and with hacks using external utilities but that guarantees little as the end-user might not be running the OS you presume he is running, he/she also might not have those external utilities your code depends on. Another principal reason for using the modules is that debugging's so much more easier since you know exactly how the modules behave, you have access to the code, etc. It might be fair to say, it's never safe to make presumtions about arbitrary external conditions, take control and ensure _your_ code is guaranteed to run (anywhere and everywhere, hopefully).

    20061109 Janitored by Corion: Added formatting, links, as per Writeup Formatting Tips