laziness, impatience, and hubris | |
PerlMonks |
Re: Outputting input prompt with proveby davido (Cardinal) |
on Aug 05, 2019 at 15:09 UTC ( [id://11103947]=note: print w/replies, xml ) | Need Help?? |
This is a tricky problem, but it has various solutions. One solution is to use IPC::Open3, and to test your script by writing to STDIN programatically, and reading from STDOUT. It would be a lot more convenient to just use a module like Capture::Tiny, but that module doesn't really help you solve the writing to STDIN problem very well. IPC::Run may be easier to use for this. Another solution is to convert your prompting and input code to use ExtUtils::MakeMaker's prompt function. This function allows you to provide a default value, but also allows you to set the environment variable PERL_MM_USE_DEFAULT to tell prompt to use that default value in lieu of reading from STDIN. It's sort of an odd state of evolution that ExtUtils::MakeMaker contains a prompt function, but ExtUtils::MakeMaker is a core Perl module, as baked into the Perl distribution as strict. Though it introduces a dependency to do so, IO::Prompt::Tiny puts the function into a module that is less of a kitchen sink, and more appropriately named for what it provides. It still offers compatibility with the PERL_MM_USE_DEFAULT environment variable. Here is an example script using it:
And here is a sample test:
But this still exposes a weakness in going about testing by looking at STDOUT; you're testing at the highest level, and are unable to examine what's going on at lower levels. It's difficult to unit test. If you went the route of using a modulino you could reconfigure your script for better testability. Modulinos are described in the OReilly book, "Mastering Perl", and also in various online resources, one of the earliest of which is http://www.drdobbs.com/scripts-as-modules/184416165. By converting to a modulino, breaking functionality into sensible subroutines, and then creating appropriate wrappers around the IO boundaries you can develop tests that validate both the top level code through the use of IO capturing techniques demonstrated above, and also at the unit level. For the unit level tests many of them could mock an output subroutine to avoid hitting STDOUT at all, similar to how prompt allows for hinting STDIN. Dave
In Section
Seekers of Perl Wisdom
|
|