【问题标题】:Redirect test results for tcltest重定向 tcltest 的测试结果
【发布时间】:2018-09-18 14:34:17
【问题描述】:

我喜欢在我的日常测试任务中使用 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 脚本中的错误。
  • 您的问题实际上涉及两个(不一定相关)问题(可能分为两个单独的问题):1)tcltest 报告间接和 2)I/O 粘合。至于 1)另见我的回答,至于 2),@DonalFellows' 将服务。

标签: pipe tcl channel


【解决方案1】:

您可能想简化设置并留在 Tcl 中?使用 Tcl 的通道转换重定向标准输出(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
    }
}

上面的sn-p是直接从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 工具。

【讨论】:

    【解决方案2】:

    这似乎是一个相当复杂的脚本。有了这些东西,分阶段进行会使生活变得更加轻松。第一部分是将您的 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 时相比,在测试中的问题更大)是它是管道中的面向行的脚本,具有默认缓冲,即 已满 em> 缓冲。我的答案第二部分中的fconfigure 是如何解决这个问题;它使您可以告诉 Tcl 在准备好后立即将每一行发送到管道实现,而不是等待完整的 4-8 kB 数据。

    【讨论】:

    • 我不太喜欢像这样使用从属 bash 脚本,但这会起作用。大概。无法在此 OSX 系统上进行测试,因为它没有 notify-send...
    • 谢谢多纳尔。你最后的代码完美运行,除了 1 件事:if [ -n "$mess" ] 而不是 if [ -n $mess],现在我要将此代码集成到我的测试中,并在此处表示结果。
    • 好的,所以需要更多报价。听起来像是很多 shell 编程……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 2013-12-29
    • 2011-06-03
    • 1970-01-01
    相关资源
    最近更新 更多