重定向 tcltest 的测试结果
Redirect test results for tcltest
我喜欢在日常测试任务中使用 tcltest。但是我只能在控制台中看到测试结果,所以在每次测试后 运行 我需要切换到那个控制台,才能找到结果。
根据 tcltest 文档,有选项 outputChannel。此选项允许将测试结果重定向到管道或通道,然后显示在我想要的任何地方。
所以我尝试创建这个频道:
set logger [ open "|bash -c \"while true;do sleep 1; while read mess;do debug=\\"$debug \n $mess\\";done; if \\[\\[ $debug != \\"\\" \\]\\];then notify-send $debug; debug=\\"\\";fi; done \" " r+]
接下来我像这样配置 tcltest:
configure -singleproc 1 -verbose t -match ** -outputChannel $logger
然后我尝试在我的频道中发送测试消息:
puts $logger "Test message 1st line \n test message 2 line"
此脚本有效,但没有显示测试消息,并且通知中没有 tcltest 输出。
我如何创建我的记录器频道??
这似乎是一个相当复杂的脚本。有了这样的事情,分阶段进行会使生活变得容易得多。第一部分是将 Bash 脚本放在大括号中并将其存储在变量中:
set notifySendScript {
while true; do
sleep 1
while read mess; do
sleep 1
debug="$debug\n$mess"
done
if [[ $debug != "" ]]; then
notify-send $debug
debug=""
fi
done
}
然后你可以 运行 你的脚本更简单并且更清楚发生了什么(我已经切换到 list
这样它会自动为我们引用):
set logger [ open [list |bash -c $notifySendScript] r+]
puts $logger "aaaaaaaa\n bbbbbbb"
现在我们已经将这些部分分开,我们可以看到您的 bash 脚本中存在问题。特别是,它重复地从标准输入读取(由于循环)直到它获得 EOF,您的代码永远不会发送它,因为它没有 close
管道。更有趣的是,它将它放在一个循环中,这样您的代码将在 EOF 之后继续尝试从标准输入中重复读取 ,这不太可能是您想要的。还有其他问题(例如,不从那个 read-write 管道读取)但我认为最大的问题是你的代码在不需要的时候是一个可怕的 one-liner,那是隐藏的反斜杠墙和不可读性背后的所有问题。我强烈建议尝试使 sub-scripts 更整洁(作为单独的文件或至少作为 braced 部分,例如我上面所做的),因为这会阻止你发疯。
由于您试图将大量输出流重定向到它,因此您需要一个更智能的脚本:
set script {
while read mess; do
while read -t 1 tail && [ -n $tail ]; do
mess=`printf '%s\n%s' $mess $tail`
done
if [ -n $mess ]; then
notify-send $mess
fi
done
}
set pipeline [open [list |bash -c $script] "w"]
# This could also be an issue; want line buffering because that's what the
# bash script expects, and the default is full buffering (as for *all* channels)
fconfigure $pipeline -buffering line
# Demonstration
puts $pipeline "aaaaaaaa\nbbbbbbb"
after 5000
puts $pipeline "cccccccc\nddddddd"
after 5000
close $pipeline
诀窍是我使用 -t
选项(用于超时)到 read
但仅用于累积额外行的内部循环。此外,它将空行视为发送消息的借口。最后,外层循环将在收到 EOF 时终止。这对于让您正确关闭整个系统很重要。
存在的另一个问题(在测试中比在部署 IMO 时更严重)是它是管道中的 line-oriented 脚本,具有默认缓冲,即 完全 缓冲。我答案第二部分的 fconfigure
是如何解决的;它让您告诉 Tcl 在每一行准备就绪后立即将其发送到管道实现,而不是等待完整的 4–8 kB 数据。
您可能想简化设置并继续使用 Tcl?使用 Tcl 的通道转换重定向 stdout(由 tcltest
在幕后使用)是一个方便的选择;之前已经介绍过 here。
此主题有多种变体,但您可能希望通过以下方式开始:
第 1 步:定义通道拦截器
oo::class create TcltestNotifier {
variable buffer
method initialize {handle mode} {
if {$mode ne "write"} {error "can't handle reading"}
return {finalize initialize write}
}
method finalize {handle} {
# NOOP
}
method write {handle bytes} {
append buffer $bytes
return $bytes
}
method report {} {
# sanitize the tcltest report for the notifier
set buffer [string map {\" \\"} $buffer]
# dispatch to notifier (Mac OS X, change to your needs/ OS)
append cmd "display notification \"$buffer\"" " "
append cmd "with title \"Tcltest notification\""
exec osascript -e $cmd
}
}
上面的代码片段是从 Donal.
直接导出/窃取的
第 2 步:在您的 tcltest
套件
周围使用 stdout
注册拦截器
package req tcltest
namespace import ::tcltest::*
set tn [TcltestNotifier new]
chan push stdout $tn
test mytest-0.1 "Fails!" -body {
BARF!;
} -result "?"
chan pop stdout
$tn report
一些评论
- 您可以改变粒度,为每个输出行请求通知而不是测试报告(然后您必须在
write
方法中发送给您的通知程序)。但我怀疑这是否有意义。
- 该示例是在 Mac OS X (
osascript
) 上构建的 运行,您必须将其修改为您的 *nix 工具。
我喜欢在日常测试任务中使用 tcltest。但是我只能在控制台中看到测试结果,所以在每次测试后 运行 我需要切换到那个控制台,才能找到结果。 根据 tcltest 文档,有选项 outputChannel。此选项允许将测试结果重定向到管道或通道,然后显示在我想要的任何地方。 所以我尝试创建这个频道:
set logger [ open "|bash -c \"while true;do sleep 1; while read mess;do debug=\\"$debug \n $mess\\";done; if \\[\\[ $debug != \\"\\" \\]\\];then notify-send $debug; debug=\\"\\";fi; done \" " r+]
接下来我像这样配置 tcltest:
configure -singleproc 1 -verbose t -match ** -outputChannel $logger
然后我尝试在我的频道中发送测试消息:
puts $logger "Test message 1st line \n test message 2 line"
此脚本有效,但没有显示测试消息,并且通知中没有 tcltest 输出。 我如何创建我的记录器频道??
这似乎是一个相当复杂的脚本。有了这样的事情,分阶段进行会使生活变得容易得多。第一部分是将 Bash 脚本放在大括号中并将其存储在变量中:
set notifySendScript {
while true; do
sleep 1
while read mess; do
sleep 1
debug="$debug\n$mess"
done
if [[ $debug != "" ]]; then
notify-send $debug
debug=""
fi
done
}
然后你可以 运行 你的脚本更简单并且更清楚发生了什么(我已经切换到 list
这样它会自动为我们引用):
set logger [ open [list |bash -c $notifySendScript] r+]
puts $logger "aaaaaaaa\n bbbbbbb"
现在我们已经将这些部分分开,我们可以看到您的 bash 脚本中存在问题。特别是,它重复地从标准输入读取(由于循环)直到它获得 EOF,您的代码永远不会发送它,因为它没有 close
管道。更有趣的是,它将它放在一个循环中,这样您的代码将在 EOF 之后继续尝试从标准输入中重复读取 ,这不太可能是您想要的。还有其他问题(例如,不从那个 read-write 管道读取)但我认为最大的问题是你的代码在不需要的时候是一个可怕的 one-liner,那是隐藏的反斜杠墙和不可读性背后的所有问题。我强烈建议尝试使 sub-scripts 更整洁(作为单独的文件或至少作为 braced 部分,例如我上面所做的),因为这会阻止你发疯。
由于您试图将大量输出流重定向到它,因此您需要一个更智能的脚本:
set script {
while read mess; do
while read -t 1 tail && [ -n $tail ]; do
mess=`printf '%s\n%s' $mess $tail`
done
if [ -n $mess ]; then
notify-send $mess
fi
done
}
set pipeline [open [list |bash -c $script] "w"]
# This could also be an issue; want line buffering because that's what the
# bash script expects, and the default is full buffering (as for *all* channels)
fconfigure $pipeline -buffering line
# Demonstration
puts $pipeline "aaaaaaaa\nbbbbbbb"
after 5000
puts $pipeline "cccccccc\nddddddd"
after 5000
close $pipeline
诀窍是我使用 -t
选项(用于超时)到 read
但仅用于累积额外行的内部循环。此外,它将空行视为发送消息的借口。最后,外层循环将在收到 EOF 时终止。这对于让您正确关闭整个系统很重要。
存在的另一个问题(在测试中比在部署 IMO 时更严重)是它是管道中的 line-oriented 脚本,具有默认缓冲,即 完全 缓冲。我答案第二部分的 fconfigure
是如何解决的;它让您告诉 Tcl 在每一行准备就绪后立即将其发送到管道实现,而不是等待完整的 4–8 kB 数据。
您可能想简化设置并继续使用 Tcl?使用 Tcl 的通道转换重定向 stdout(由 tcltest
在幕后使用)是一个方便的选择;之前已经介绍过 here。
此主题有多种变体,但您可能希望通过以下方式开始:
第 1 步:定义通道拦截器
oo::class create TcltestNotifier {
variable buffer
method initialize {handle mode} {
if {$mode ne "write"} {error "can't handle reading"}
return {finalize initialize write}
}
method finalize {handle} {
# NOOP
}
method write {handle bytes} {
append buffer $bytes
return $bytes
}
method report {} {
# sanitize the tcltest report for the notifier
set buffer [string map {\" \\"} $buffer]
# dispatch to notifier (Mac OS X, change to your needs/ OS)
append cmd "display notification \"$buffer\"" " "
append cmd "with title \"Tcltest notification\""
exec osascript -e $cmd
}
}
上面的代码片段是从 Donal.
直接导出/窃取的第 2 步:在您的 tcltest
套件
周围使用 stdout
注册拦截器
package req tcltest
namespace import ::tcltest::*
set tn [TcltestNotifier new]
chan push stdout $tn
test mytest-0.1 "Fails!" -body {
BARF!;
} -result "?"
chan pop stdout
$tn report
一些评论
- 您可以改变粒度,为每个输出行请求通知而不是测试报告(然后您必须在
write
方法中发送给您的通知程序)。但我怀疑这是否有意义。 - 该示例是在 Mac OS X (
osascript
) 上构建的 运行,您必须将其修改为您的 *nix 工具。