[英]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
這種工作但是:
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 的通信腳本可能很有用。
tmux
和screen
都有命令讓你截屏,如果這對你的測試有用的話:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.