Как я могу протестировать STDERR с помощью Test:: More?

Я пишу некоторые тесты, используя Test::More, и одна из функций, которую я тестирую, печатает на STDERR. Я хотел бы проверить вывод на STDERR, но я немного не уверены, как это сделать. Я знаю, что близок к этому. Это работает:

use strict;
use warnings;
use feature qw(say);

close STDERR;
open STDERR, ">", my $error_string;

say STDERR "This is my message";
say qq(The $error_string is equal to "$error_string");

это распечатывает:

The $error_string is equal to "This is my message
"

однако я не хочу закрывать STDERR. Я просто хочу его облить.

Я попытался это:

use strict;
use warnings;
use feature qw(say);

open my $error_fh, ">", my $error_string;
open STDERR, ">&", $error_fh;

say STDERR "This is my message";
close $error_fh;
say qq(The $error_string is equal to "$error_string");

а, $error_string пусто.

что я делаю не так?

3 ответов


для меня open STDERR, ">&", $error_fh (вместе с open STDERR, ">&" . fileno($error_fh)) не возвращает значение true. Я думаю, что >& режим может быть довольно прямым синтаксическим сахаром для dup системный вызов, который не будет работать на псевдо-filehandle, как $error_fh.

как насчет локализации STDERR?

{
    local *STDERR = *$error_fh;
    say STDERR "something";
}
# STDERR restored

Test:: Output может это сделать, и теперь он использует Capture:: Tiny для того чтобы уловить случаи края.


#  perl -MPerlIO::tee -MData::Printer -e 'my $output; STDERR->push_layer(tee=> $output); warn "Danger, Will Robinson!"; p($output);'
Danger, Will Robinson! at -e line 1.
"Danger, Will Robinson! at -e line 1.
"