c++與Tcl通過管道通訊,並傳遞引數,獲取測試儀實時測試進度
目前,我在做測試自動化的專案,要用到smartbits,bps,testcenter和mu測試儀。通過呼叫測試儀提供的TCL API操作測試儀,從而實現測試用例的具體流程。我們用測試儀測試TOE時,會發現測試儀上會顯示測試進度(1%,2%...)。以Bps為例,當執行到set objectName [$testObjectName run
-progress "bps::textprogress stdout"]命令時,就會在螢幕上同步輸出當前的測試進度。為了與其他模組方便通訊,我利用c++呼叫TCL指令碼來實現用例。為了將tcl輸出的測試進度獲取並傳遞給其他模組,我利用windows API CreateProcess(),在c++與TCL指令碼之間開闢了一條管道。下面是我的.tcl原始碼和c++原始碼,希望對從事這方面開發的同仁有益。
【.tcl】
set dir [file dirname [info script]]
lappend auto_path $dir
wm withdraw .
proc testProc {ip uname pwd} {
puts "loading bps package..."
package require bps
puts "bps package loading complete."
set var [bps::connect $ip $uname $pwd]
set test1 [$var createTest]
set comName [$test1 createComponent bitblaster bb41 1 2]
puts "test running.."
set fid [open "testProgress.txt" w+]
if [catch {open "testProgress.txt" w+} $fid] {
puts stderr "cann't open "testProgress.txt" w+: $fid"
} else {
set reObj [$test1 run -progress "bps::textprogress stdout"]
puts $fid $reObj
close $fid
}
puts "quit"
}
#------------------------------------------------------------------
# Analyze cmd options
#set proc_list [ info commands ]
#for { set i 0 } { $i < $::argc } { incr i } {
# if { -1 != [ lsearch -exact $proc_list [ lindex $::argv $i ] ] } {
# puts "Try to execute proc '[ lindex $::argv $i ]' ......"
# eval [ lindex $::argv $i ]
# }
#}
#-----------------------------------------------------------------
# Analyze cmd options
set proc_list [ info commands ]
for { set i 0 } { $i < $::argc } { incr i } {
set proc_name [ lindex $::argv $i ]
if { [ expr [ regexp -- {^-} $proc_name ] && \
-1 != [ lsearch -exact $proc_list [ string range $proc_name 1 end ] ] ] } {
set param_list ""
for { set j [ expr $i+1 ] } { $j < $::argc } { incr j } {
set param_name [ lindex $::argv $j ]
if { ![ regexp -- {^-} $param_name ] } {
lappend param_list $param_name
} else {
set i [ expr $j - 1 ]
break
}
}
puts "Try to execute proc '[ string range $proc_name 1 end ]' with params '$param_list' ......"
set eval_code [ list [ string range $proc_name 1 end ] ]
foreach param $param_list { lappend eval_code $param }
eval $eval_code
}
}
【注】:如果testProc不需要引數,則可以將兩條“————”之間的程式碼解註釋,將“----”下面的程式碼註釋掉即可。
【c++】
#include "stdafx.h"
#include <Windows.h>
#include <string>
#include <process.h>
#include <iostream>
#include <stdio.h>
#include "tcl.h"
#include "tclDecls.h"
#pragma comment(lib,"tcl85.lib")
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0)) {
cout<<"Error On CreatePipe()"<<endl;
return 0;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
string str1 = "D:\\Tcl\\bin\\wish85.exe test.tcl";
string str2 = "-";
string str3 = "test";
string str4 = "10.10.0.1";
string str6 = " ";
string str7 = "mobei";
string str8 = "mobei";
string str = str1+str6+str2+str3+str6+str4+str6 + str7 + str6 + str8;
char* strC = const_cast<char*>(str.c_str());
if (!CreateProcess(NULL,strC, NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
cout<<"Error on CreateProcess()"<<endl;
return 0;
}
CloseHandle(hWrite);
char buffer[4096] = {0};
DWORD bytesRead;
while (true)
{
if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL)
{
cout<<"test"<<endl;
break;
}
else
{
string bufStr;
bufStr = buffer;
if (bufStr.find("quit") != -1)
{
break;
}
else
{
sendInfo(bufStr);//將測試進度傳送給其他模組
cout<<"content of buffer is: "<<buffer<<endl;
}
}
}
cout<<"hello world"<<endl;
return 0;
}
由於ReadFile()是個阻塞函式,所以在tcl指令碼里面輸出一個字元,當在bufStr中找到這個字元時就退出迴圈,這裡我輸出的是quit,作為退出迴圈標誌。測試的結果,我分別儲存在了兩個.txt檔案中,可以通過分析檔案獲取,下面是用c++讀取.txt檔案的程式碼。
【readTxt】
// readTxt.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream"
#include <fstream >
#include <string>
using namespace std;
string readTxt(string fileName);
int main(int argc, char* argv[])
{
string result = readTxt("passorfailed.txt");
cout<<"result is: "<<result<<endl;
if (result == "passed")
{
cout<<"test ok"<<endl;
}
else
cout<<"test failed"<<endl;
return 0;
}
string readTxt(string fileName)
{
ifstream infile;
char* fileNamePtr = const_cast<char*>(fileName.c_str());
infile.open (fileNamePtr);
if(!infile)
cout<<"error"<<endl; //判斷檔案是被成功開啟
string num; //定義檔案中的資料型別
char p; //定義一個字元讀取檔案中的空格和/或回車符
int M=1; //這裡首先定義為1是因為最後一行的結束符是EOF,所以用'\n'來判斷行的話, //最後一行會漏悼。所以先把它定義為1,也就相當於加上了最後一行!
int N=0;
while(!infile.eof()) //每次讀入之前都要判斷是否到了檔案末
{
do{
infile.get (p);
if(p=='\n')
{
M++; //統計行數;
N=0; //一個新行開始時,列數置為0
cout<<endl; //一行之後輸出一個換行符
}
}while(isspace((int)p) && !infile.eof ());//結束條件是讀入的是空格或已到達檔案末
N++; //統計列數
infile.putback (p); // 如果前面讀入的不是空格或回車符,則要把剛才讀入的字元返回到檔案流中!
infile>>num; // 讀入一個數
cout<<num<<" "; // 輸出剛才讀入的資料
}
infile.close (); // 關閉檔案
return num;
}
如果從事過這方面開發的同仁有更好的解決方案,歡迎不吝賜教。
相關文章
- 介面測試--獲取動態引數進階
- JSBridge通訊時間測試JS
- OTDR光時域反射儀測試引數設定反射
- Jmeter 通過命令列 (CLI) 模式執行測試示例與引數詳解JMeter命令列模式
- 通過行為引數化傳遞程式碼
- 如何通過WinDbg獲取方法引數值
- 介面測試 - 引數測試
- kettle通過命令列引數傳遞資料庫連線資訊命令列資料庫
- 中興通訊測試專案實踐:敏捷測試特性文件的交付過程實踐探討敏捷測試
- 通過反射獲取上傳檔案方法引數中的檔名反射
- JavaScript 獲取 url 傳遞引數值JavaScript
- 介面測試並不只是測試引數和返回值
- js獲取url傳遞引數,js獲取url?號後面的引數JS
- [譯] 通過測試來解耦 Activity解耦
- 高斯計磁場測試儀磁力檢測儀磁場測磁儀手持磁通計特斯拉計td8620
- 通過構建自己的JavaScript測試框架來了解JS測試JavaScript框架JS
- 介面測試的獲取token變數變數
- JavaScript獲取url傳遞的引數值JavaScript
- Java的通過管道來實現執行緒通訊Java執行緒
- 一個測試用例裡面有多套測試資料,如何用 beautifureport 分別對各組測試資料進行統計測試通過與否
- 測試進度表
- 自動化測試進階課程——Selenium自動化測試通關實戰班
- pytest介面測試之fixture傳引數request
- 如何通過A/B測試提升Push推送訊息點選率?
- 基於目標TPS的效能測試,如何通過手動設定場景進行測試?
- [譯] 更可靠的 React 元件:從"可測試的"到"測試通過的"React元件
- 03----GD32E103RBT6----MISC測試程式碼[測試通過]
- 獲取url中?後面傳遞的引數
- 環信即時通訊有那些測試點,如何弱網
- 匿名管道通訊實現
- [新手開發記錄] 測試通過之後進行重構
- 通過sysbench工具實現MySQL資料庫的效能測試MySql資料庫
- 004 通過連結串列學Rust之測試Rust
- 做一名能文能武的測試員,教你測試與開發溝通時的常勝秘籍
- TCP 的連線建立與關閉狀態及資料傳輸通訊過程【含有 PHP 測試實驗程式碼】TCPPHP
- Laravel 單元測試實戰(4)- 測試成功後的方法重構並再次測試透過Laravel
- 移遠 EC20 模組(4G通訊模組)AT指令測試 TCP 通訊過程TCP
- 介面測試的時候如何一鍵獲取 cookie, 並在其他介面引用?Cookie
- ECU通訊:CAN匯流排模擬測試