7

I'm writing a module which has unit tests that require a certain external server program to be running, and, if it is, the hostname and port need to be known.

I would like to prompt for this information when running the test suite, and skip those tests if the user declines to provide it.

What's the best way to handle this?

Thanks

friedo
  • 65,762
  • 16
  • 114
  • 184
  • 1
    Without knowing the particulars of the server program or how you'd like to check to see if it's running, you can just `use Test::More`, insert the prompt where you need it, and then use the values from the prompt in your test. A unit test in Perl is really just another Perl script, except that it's usually littered with the `ok()`, `isa_ok()`, etc functions from `Test::More`. –  Oct 02 '11 at 21:44
  • That's pretty much what I was thinking; I just wasn't sure if doing so would interfere in some unanticipated way with the test harness or automated installs via CPAN.pm and the like. – friedo Oct 02 '11 at 21:54

2 Answers2

7

Are you looking for ExtUtils::MakeMaker::prompt?

Other Handy Functions

prompt

my $value = prompt($message);
my $value = prompt($message, $default);

The prompt() function provides an easy way to request user input used to write a makefile. It displays the $message as a prompt for input. If a $default is provided it will be used as a default. The function returns the $value selected by the user.

If prompt() detects that it is not running interactively and there is nothing on STDIN or if the PERL_MM_USE_DEFAULT environment variable is set to true, the $default will be used without prompting. This prevents automated processes from blocking on user input.

If no $default is provided an empty string will be used instead.

socket puppet
  • 3,191
  • 20
  • 16
  • Ah yes, that's what I was looking for, thanks. I knew it was somewhere but I was looking in the test harness rather than the build system. :) I'm actually using `Module::Install` rather than MakeMaker, but I'm sure it can do something similar. – friedo Oct 02 '11 at 22:29
  • 1
    http://p3rl.org/ExtUtils::MakeMaker#prompt http://p3rl.org/Module::Build::API#prompt http://p3rl.org/Module::Install::Makefile#DESCRIPTION – daxim Oct 03 '11 at 10:35
3

I'll take a different tack on this. Why exactly do you need the user as a middleman for this - especially for automated tests? A significantly better approach (from my own experience) is to do one of the following:

  • Make the server (hostname/port) somehow discoverable by the test. It can be either a genuine discoverability, or having the server register itself, or, heck, some config service. Considering that the server's clients in real world would need to be able to connect to the server, such a discovery logic (again, worst case scenario being some config file) should already exist.

  • For a really advanced case, allow the test harness the ability to start the test instance of a server on a test port if one is not running.

Mind you, if your server for some reason can not be instrumented to allow either of the approaches above, then socket puppet's answer is the best approach.

DVK
  • 126,886
  • 32
  • 213
  • 327
  • All good suggestions, but this server doesn't have any kind of discovery protocol and I can't invent one. I'm just working on a client library. – friedo Oct 03 '11 at 00:45
  • @friedo - don't be confused by the fancy term I invented. How does a client know how to connect? That's what I mean by discovery protocol – DVK Oct 03 '11 at 01:07
  • 1
    @friedo: As a user, I'd *much* prefer a config file or command line option, so that I can invoke the test (possibly even from a script?) and not have to worry about a prompt coming up. – Cascabel Oct 03 '11 at 04:45