簡體   English   中英

用於測試 ncurses 應用程序的假/模擬/后台終端

[英]fake/mock/background terminal for testing an ncurses application

我正在使用一個(其他)遺留 C 應用程序,它有一個使用 ncurses 編寫的文本用戶界面。

我想編寫程序運行的一些測試腳本,但它只會在終端中運行。 沒有辦法刪除用戶界面。

有沒有辦法在不必將屏幕帶到前台的情況下偽造或后台終端(用於應用程序)?


到目前為止,我最好的使用屏幕和超時如下。 此示例執行程序的定時運行。 為簡潔起見,我省略了管理工作區的機器。

#!/bin/bash

cat - >runmyprogram <<EOF
echo running 
timeout --foreground --preserve-status --signal=HUP 3s cursesprogramcommandlinehere
STATUS=\$?
echo \$STATUS >workspace/exit_status
stty sane
clear
exit \$STATUS
EOF
chmod u+x runmyprogram

screen -dmS foobar /bin/bash

(
    sleep 3
    sleep 1
    screen -S foobar -p 0 -X quit
) &

screen -S foobar -p 0 -X stuff "runmyprogram^M"
screen -r

這種工作但是:

  • ncurses 應用程序只有在使用screen -r進入前台后才會啟動。

我想實現類似的東西而不必使用screen -r

  • 我也嘗試過tmux但到目前為止還沒有像screen那樣接近工作。 它還需要連接一個終端才能啟動 GUI(即 tmux 連接)。

  • 在 Azure 構建管道中運行測試時,我得到“必須連接到終端”

(按照此處的建議添加腳本 /dev/null 會導致掛起。我不明白為什么這會創建一個終端)

  • 如果我使用當然沒有終端的“nohup”運行測試,也會發生這種情況。

  • 當從 ctest 屏幕運行時,似乎也改變了它在其中運行的終端的拓撲結構,而我真的希望它完全隔離。

  • 還有至少一個競爭條件,因為 exit_status 並不總是被填充,但是我在超時超時和將退出消息發送到屏幕之間添加了很多時間。

超時對於覆蓋 TUI 不響應的(失敗的)測試用例是必要的。

我能夠對遺留應用程序進行更改以更好地支持這一點,但重寫整個用戶界面不是一種選擇。

一些相關問題:


screen 的困難是由 screen 和 ncurses 之間的微妙交互引起的。 我已經嘗試了https://www.etcwiki.org/wiki/Best_ncurses_linux_console_programs中的很多應用程序作為示例,並且可以讓它們全部與屏幕一起工作。 遺留應用程序是唯一需要將屏幕置於前台的應用程序。 它失敗是因為它調用了 subwin() ,但失敗並隨后被視為致命錯誤。 (請注意,這與我上面描述的行為不同。也就是說,該應用程序在前台啟動之前不會啟動。到目前為止,我無法重現這一點)。 奇怪的是,如果我在運行應用程序之前附加屏幕,它就可以工作。 調用 subwin() 和應用程序的 rest。 我想明白為什么。

  • 我已經嘗試過tmux ,現在可以正常工作了。 它不需要附加 window。

我使用來自 bash 的tmux的解決方案包括以下元素。

用於執行程序定時運行並捕獲其退出狀態的包裝器腳本:

cat - >$WSDIR/runprog <<EOF
#!/bin/bash
echo running program >$WSDIR/stdout
cd $WSDIR
echo 0 >$WSDIR/exit_status
timeout --foreground --preserve-status --signal=HUP $RUNTIME runprogramhere 2>$WSDIR/stderr
STATUS=\$?
echo \$STATUS >$WSDIR/exit_status
stty sane
clear
echo done STATUS=\$STATUS >>$WSDIR/stdout
exit \$STATUS
EOF
chmod u+x $WSDIR/runprog

使用 tmux 運行程序的腳本:

cat - >$WSDIR/exercise <<EOF
tmux new-session -d -s $SESSIONNAME -x 132 -y 80 "bash -l"
tmux send-keys "cd $WSDIR"
tmux send-keys Enter
tmux send-keys ./runprog
tmux send-keys Enter

# watch for interesting things to happen...

EOF
chmod u+x $WSDIR/exercise

使用上面的腳本執行定時運行,允許事情不起作用。

SESSIONNAME=testFoobar-case1-$$

cleanUp () {
   tmux kill-session $SESSIONNAME 2>/dev/null
}

trap cleanUp 0 TERM

timeout 10s $WSDIR/exercise

這是如何工作的:

  • tmux new-session - 開始一個新的 session

  • -d - 啟動它分離(因此它可以在沒有“真實”終端的腳本中工作)

  • -s - 給我們一個名為 session 的引用 - 這樣我們的腳本就可以整理

  • tmux send-keys - 將擊鍵發送到 session,無論它是在后台還是在前台

  • 超時對於在出現問題時強制程序退出很有用

  • --preserve-status 強制超時以保留程序運行的狀態。

  • 我們將退出狀態存儲在文件中以便於訪問

  • trap 在我們退出時調用 cleanUp 例程

  • 因此 kill-session 在退出時殺死 tmux session

  • 我們為每個測試腳本生成一個唯一的 session 名稱


screen可以采用類似的方案:

screen -S sessionName bash -l
screen -d   - detach the current session
screen -r   - resume a session
screen -S sessionName -X stuff "echo hello^M"  - send keys

除了屏幕不適用於我正在測試的應用程序之外,差異很小。 Tmux 有特殊鍵的名稱。 屏幕改為使用控制字符。

使用expect或類似工具編寫與 tmux(或屏幕)session 的通信腳本可能很有用。

tmuxscreen都有命令讓你截屏,如果這對你的測試有用的話:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM