我喜欢在日常测试任务中使用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输出。 我如何创建我的记录器频道??
答案 0 :(得分:0)
这似乎是一个非常复杂的脚本。有了这样的事情,分阶段做就能让生活变得更轻松。第一部分是将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 之后重复读取标准输入,这很不可能是您想要的。还有其他问题(例如,不是从读写管道读取)但我认为最大的问题是你的代码是一个可怕的单行程,当它不需要时,这隐藏了背后的所有问题一面反斜杠和不可读的墙。我强烈建议尝试保持子脚本更整洁(作为单独的文件或至少作为支撑部分,如上所述),因为这会阻止你发疯。
由于您正在尝试将大量输出重定向到它,因此您需要一个更智能的脚本:
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时更多的问题)是它是一个具有默认缓冲的管道中的面向行的脚本, full 缓冲。我的答案的第二部分中的fconfigure
是如何解决这个问题;它让你告诉Tcl一旦准备就发送每一行到管道实现,而不是等待完整的4-8 kB数据。
答案 1 :(得分:0)
您可能希望简化设置并留在Tcl中?使用Tcl的通道转换重定向stdout(由tcltest
在引擎盖下使用)是一个方便的选项;并且之前已被覆盖here。
此主题有许多变体,但您可能希望开始使用:
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直接导出/偷窃的。
stdout
套件tcltest
拦截器
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
方法中分配给通知程序)。但我怀疑这是否有道理。osascript
)上运行,您必须将其修改为* nix工具。