Anthony Mastrean
Anthony Mastrean

Reputation: 22394

How would I test that a PowerShell function properly streams input from the pipeline?

I know how to write a function that streams input from the pipeline. I can reasonably tell by reading the source for a function if it will perform properly. However, is there any method for actually testing for the correct behavior?

I accept any definition of "testing"... be that some manual test that I can run or something more automated.

If you need an example, let's say I have a function that splits text into words.

PS> Get-Content ./warandpeace.txt | Split-Text

How would I check that it streams input from the pipeline and begins splitting immediately?

Upvotes: 0

Views: 74

Answers (3)

Anthony Mastrean
Anthony Mastrean

Reputation: 22394

Ah, I've got a very simple solution. The concept is to insert your own step into the pipeline with obvious side-effects before the function that you're testing. For example...

PS> 1..10 | %{ Write-Host $_; $_ } | function-under-test

If your function-under-test is "bad", you will see all of the output from 1..10 twice, like this

1
2
3
1
2
3

If the function-under-test is processing items lazily from the pipeline, you'll see the output interleaved.

1
1
2
2
3
3

Upvotes: 0

user4003407
user4003407

Reputation: 22122

You can write a helper function, which would give you some indication as pipeline items passed to it and processed by next command:

function Print-Pipeline {
    param($Name, [ConsoleColor]$Color)
    begin {
        $ColorParameter = if($PSBoundParameters.ContainsKey('Color')) {
            @{ ForegroundColor = $Color }
        } else {
            @{ }
        }
    }
    process {
        Write-Host "${Name}|Before|$_" @ColorParameter
        ,$_
        Write-Host "${Name}|After|$_" @ColorParameter
    }
}

Suppose you have some functions to test:

$Text = 'Some', 'Random', 'Text'
function CharSplit1 { $Input | % GetEnumerator }
filter CharSplit2 { $Input | % GetEnumerator }

And you can test them like that:

PS> $Text |
>>> Print-Pipeline Before` CharSplit1 |
>>> CharSplit1 |
>>> Print-Pipeline After` CharSplit1
Before CharSplit1|Before|Some
Before CharSplit1|After|Some
Before CharSplit1|Before|Random
Before CharSplit1|After|Random
Before CharSplit1|Before|Text
Before CharSplit1|After|Text
After CharSplit1|Before|S
S
After CharSplit1|After|S
After CharSplit1|Before|o
o
After CharSplit1|After|o
After CharSplit1|Before|m
m
After CharSplit1|After|m
After CharSplit1|Before|e
e
After CharSplit1|After|e
After CharSplit1|Before|R
R
After CharSplit1|After|R
After CharSplit1|Before|a
a
After CharSplit1|After|a
After CharSplit1|Before|n
n
After CharSplit1|After|n
After CharSplit1|Before|d
d
After CharSplit1|After|d
After CharSplit1|Before|o
o
After CharSplit1|After|o
After CharSplit1|Before|m
m
After CharSplit1|After|m
After CharSplit1|Before|T
T
After CharSplit1|After|T
After CharSplit1|Before|e
e
After CharSplit1|After|e
After CharSplit1|Before|x
x
After CharSplit1|After|x
After CharSplit1|Before|t
t
After CharSplit1|After|t
PS> $Text |
>>> Print-Pipeline Before` CharSplit2 |
>>> CharSplit2 |
>>> Print-Pipeline After` CharSplit2
Before CharSplit2|Before|Some
After CharSplit2|Before|S
S
After CharSplit2|After|S
After CharSplit2|Before|o
o
After CharSplit2|After|o
After CharSplit2|Before|m
m
After CharSplit2|After|m
After CharSplit2|Before|e
e
After CharSplit2|After|e
Before CharSplit2|After|Some
Before CharSplit2|Before|Random
After CharSplit2|Before|R
R
After CharSplit2|After|R
After CharSplit2|Before|a
a
After CharSplit2|After|a
After CharSplit2|Before|n
n
After CharSplit2|After|n
After CharSplit2|Before|d
d
After CharSplit2|After|d
After CharSplit2|Before|o
o
After CharSplit2|After|o
After CharSplit2|Before|m
m
After CharSplit2|After|m
Before CharSplit2|After|Random
Before CharSplit2|Before|Text
After CharSplit2|Before|T
T
After CharSplit2|After|T
After CharSplit2|Before|e
e
After CharSplit2|After|e
After CharSplit2|Before|x
x
After CharSplit2|After|x
After CharSplit2|Before|t
t
After CharSplit2|After|t
Before CharSplit2|After|Text

Upvotes: 2

user189198
user189198

Reputation:

Add some Write-Verbose statements to your Split-Text function, and then call it with the -Verbose parameter. You should see output in real-time.

Upvotes: 1

Related Questions