通過 JNI 技術使用 ClearQuest Java API 實現與 Rational ClearQuest Test Manager(CQTM )系統的集成
簡介:Rational ClearQuest 是一個缺陷和變更的管理系統,ClearQuest Test Manager (CQTM) 作為 一個模型運行在 ClearQuest V7 的頂層。其管理功能可覆蓋測試的整個生命周期,包括測試計劃、測試 編寫、測試執行和測試報告。為了能夠更好地使用CQTM提供的強大功能,自如地與其他應用系統集成, Rational ClearQuest 提供了基於 VBScript 和 Perl 的兩套編程接口。目前,已有相關文章對此進行了 介紹。但考慮到開發人員對於使用 Java API 實現 CQTM 相關功能的需求,本文將向您詳細地介紹如何通 過 JNI 技術使用 Java API 實現與 CQTM 系統的集成。
開始之前
預備知識
本教程針對使用過 Rational ClearQuest Test Management 的人員。需要你了解 CQTM 中的基本概念 。另外你最好了解 Eclipse,但不是必需的。
系統需求
您可以安裝 IBM WebSphere Integration Developer 來運行本文中的示例程序。
Rational ClearQuest Test Manager(CQTM)簡介
目前,測試部門面臨著許多嚴峻的問題。他們需要迅速地適應市場變化,協調分散在世界各地的團隊 間的合作,與來自外部的服務提供商之間進行交互,等等。為了能夠及時地發布高質量的應用,IBM Rational將企業測試管理能力融入到了IBM Rational ClearQuest v7.0產品中,這一新特性稱為 ClearQuest test management (CQTM)。
Rational ClearQuest是一個知名的變更(新的需求、軟件缺陷、各種工單等)管理工具。CQTM作為該 產品的一個新增特性,能夠有效地幫助Rational ClearQuest用戶實現測試的計劃、創建、執行和報告。 作為Eclipse Test and Performance Tools Platform (TPTP) 功能的擴展,CQTM能夠支持各種類型的測 試,從純手工的測試一直到完全自動的測試,包括單元測試、功能回歸測試和性能測試。
CQTM提供了四種類型的客戶端
Rational ClearQuest Eclipse Client:包括兩種基於Eclipse技術的客戶端。Rational ClearQuest Client,是一個基於Eclipse Rich Client Platform (RCP) 技術開發的獨立的客戶端;Rational ClearQuest Client for Eclipse, 作為Eclipse插件安裝在支持的Eclipse內核上。
Rational ClearQuest Web Client:是一個基本浏覽器的圖形用戶接口。
Rational ClearQuest for Windows Client:是一個Microsoft Windows接口,允許用戶創建報告和圖 表。
Rational ClearQuest Client for Visual Studio.NET:允許用戶在Microsoft Visual Studio.NET環 境中訪問ClearQuest數據庫。
對於不同類型的客戶端,它們所支持的功能集不同。其中Rational ClearQuest Client for Eclipse 支持的功能最為全面,因此,本文將使用Rational ClearQuest Client for Eclipse v7.0.1.0向您展示 示例程序的執行結果。
對於一般用戶和管理員來說,可以直接通過ClearQuest客戶端完成ClearQuest的各項任務,包括提交 、修改和追蹤變更請求等。但是,在某些情況下您可能需要通過編程的方式來訪問ClearQuest的數據。例 如,如果您的部門需要將自身的應用和ClearQuest進行集成,以便增加測試管理的功能。此時,您就需要 使用ClearQuest API進行集成開發。
Rational ClearQuest提供了基於VB和Perl的兩種腳本語言的編程接口。其中,VB腳本的API通過一個 名為cqole.dll的COM library來實現,Perl腳本的API通過一個名為CQPerlExt的Perl package實現。關於 具體的類及其方法的使用描述,請參見ClearQuest隨身附帶的文檔"cq_api.pdf"。本文討論的 主要內容是,如何幫助開發人員使用Java API來實現與ClearQuest的集成。
Rational CQTM 中的重要概念
在開始介紹ClearQuest Java API之前,我們有必要對ClearQuest涉及的基本概念以及特定於CQTM的概 念做一個簡單的介紹,這將有利於您對本文中示例代碼的理解。
對於ClearQuest范圍的概念有:
變更請求(change requests):一個變更請求是用來記錄和跟蹤與項目相關的各種類型變更活動的對 象,這些對象以記錄的形式存儲在用戶數據庫中。不同的變更請求使用不同類型的記錄存儲,記錄類型定 義了關於變更請求的字段、顯示樣式和狀態遷移模型等。當用戶操作變更請求時,變更請求會從一個狀態 遷移到另一個狀態。常見的狀態包括已被提交(submitted)、已被分配(assigned)、繼續進行 (working on)、已決 (resolved) 和已被驗證 (validated)。
模式 (schemas):記錄與用戶數據庫相關的所有屬性信息,包括變更請求記錄的字段定義、展示樣式 的定義、狀態遷移模型定義以及執行狀態遷移的角色定義等。
模式數據庫 (schema repository):作為master數據庫,用來存儲模式相關的數據。
用戶數據庫(user databases):用來存儲可以被最終用戶訪問和輸入的所有數據。每一個用戶數據 庫都和一個特定版本的模式相關聯,可以說,用戶數據庫是特定版本模式的一個實例。一個特定版本的模 式可以與多個用戶數據庫關聯。需要注意的是,當用戶添加或修改變更請求的信息時,用戶更改的是用戶 數據庫中的數據,並不影響與之相關聯的模式。
數據庫集/連接 (dbset/connection):包括一個模式數據庫以及所有與該數據庫相關的用戶數據庫。 通常,一個項目所涉及的所有模式和數據庫都被歸為一個連接。當然,一個連接也可以支持多個項目,或 者一個項目也可以有多個連接。
圖1為模式、模式數據庫和用戶數據庫之間的關系示例。
圖1. 數據庫關系結構
以下是針對CQTM特性的基本概念。CQTM的各種測試資產都用ClearQuest的記錄類型來表示,存儲在 ClearQuest的用戶數據庫中。如圖2所示,展示了各種記錄的層次結構:
資產注冊(asset registry):記錄類型為TMAssetRegistry。資產注冊是測試計劃層次結構的入口。用 於定義測試的范圍,作為測試計劃、測試套件、文件位置和迭代記錄信息的容器。如CQSTF Test.
測試計劃(test plan):記錄類型為TMTestPlan。測試計劃是有狀態的記錄,表示預計要執行的測試的 分類。測試計劃可以包含子測試計劃,也可以包含若干測試用例。如測試計劃Plan2包含測試用例case1以 及三個子測試計劃CQTM01V1、STF01V1、withdraw。
測試用例(test case):記錄類型為TMTestCase。代表需要在被測系統中進行驗證的行為單元。一個測 試用例包含若干個配置的測試用例,如case1 – Maximum Memory Windows XP, case1 – Minimum Memory Windows XP。
配置的測試用例(configured test case):記錄類型為TMConfiguredTestCase。配置的測試用例是具 有關聯配置和迭代信息的測試用例的可執行格式。每個已配置的測試用例都與父測試用例相關聯,單個測 試用例可與多個已配置的測試用例關聯,用於測試不同的配置。
配置(configurations):記錄類型為TMConfiguration。一條配置記錄用於定義測試環境,是多個屬性 值的集合,如
Operating System – Windows XP
Processor – 3 Ghz
Memory – 1GB
Network – 100 Mbs
配置記錄信息獨立與資產注冊,應用於創建配置的測試用例和測試集。
測試套件(Test Suites):記錄類型為TMTestSuite。表示可按順序執行的已配置測試用例的有序列表 。
迭代(iterations):記錄類型為TMIteration。包含迭代信息,代表開發正在接受測試的系統期間的特 定裡程碑。
文件地址(File Locations):記錄類型為TMFileLocation。用於為外部的引用文件指定文件地址。
測試日志 (test log):記錄類型為TMTestLog。顯示執行的已配置測試用例記錄的摘要結果。
圖2. 測試計劃的結構
ClearQuest Java API簡介
在文章開頭我們提到,Rational ClearQuest提供了基於VB和Perl兩種腳本語言的編程接口,而並沒有 直接提供Java語言的編程接口。但在它的安裝目錄中,包含有一個名為cqjni.jar的包,可用於支持Java API。它通過JNI技術,實現使用Java語言完成對ClearQuest功能的調用。JAVA通過JNI調用本地方法,而 本地方法是以庫文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX機器上是SO文件形式)。通 過調用本地的庫文件的內部方法,使JAVA可以實現和本地機器的緊密聯系,調用系統級的各接口方法。在 Windows平台的ClearQuest的安裝目錄下,您可以發現相應的庫文件cqjniporxy.dll.
ClearQuest Java API包括用戶數據庫對象、模式數據庫對象、模式數據庫對象集合以及其他對象。其 中,主要的入口點對象有兩個:
會話對象(CQSession):提供對用戶數據庫對象的訪問。
管理員會話對象 (CQAdminSession):提供對模式數據庫對象的訪問。
會話對象
Rational ClearQuest使用會話對象驗證訪問用戶數據庫的用戶身份。因此,開發人員在對用戶數據庫 執行任何操作之前,必須通過該對象登錄到指定的用戶數據庫。作為用戶數據庫對象的根對象,開發人員 可以使用CQSession對象完成以下任務:
登錄到用戶數據庫
創建新的數據庫記錄或查看、修改已經存在的記錄
創建查詢對象,用於查詢數據庫中的特定記錄
用戶數據庫對象
圖3展示了可以通過CQSession對象訪問的用戶數據庫對象及其之間的關系。圖中的箭頭表示對象間的 關系,可以概括為兩種類型:
簡單關系:例如,通過會話對象,開發人員可以直接訪問多個不同類型的對象,包括CQDatabaseDesc, CQEntity, CQEntityDef, CQQueryDef和CQResultSet對象。
復雜關系:例如,開發人員需要同時使用CQQueryDef和CQResultSet兩個對象實現查詢,CQResultSet 對象通過CQQueryDef對象創建,並使用CQQueryDef對象中定義的規則信息執行查詢,而這兩個對象又是各 自通過會話對象單獨創建。
從圖中我們可以看出,訪問用戶數據庫涉及的主要對象包括
CQEntity對象:代表數據庫中的一條記錄,用於查看和修改記錄中的數據。
CQEntityDef對象:用於查看數據庫記錄的只讀元數據,包括字段、hook、狀態等。
CQQueryDef對象:定義查詢規則。
CQResultSet對象:包含查詢得到的結果。
CQQueryFilterNode對象: 為查詢規則添加比較過濾器。
CQDatabaseDesc對象:提供數據庫的描述信息。
CQEventObject對象:提供關於數據庫記錄,即CQEntity對象的調用方法的只讀上下文信息。
CQFieldInfo對象:提供數據庫記錄字段的只讀信息。
圖3. 用戶數據庫對象
管理員會話對象
管理員會話對象提供對模式數據庫的管理服務。作為模式數據庫對象的根對象,開發人員可以利用管 理員會話對象完成以下任務:
創建數據庫
刪除數據庫
訂閱用戶到一個數據庫
訂閱組到一個數據庫
管理員會話對象必須在執行對模式數據庫任何操作進行之前創建,它與會話對象之間沒有重疊的功能 。
模式數據庫對象
模式數據庫對象用於訪問和設置模式數據庫的元數據。圖4展示了模式數據庫對象及其之間的關系。主 要包括以下對象
CQDatabase對象:用於存儲用戶數據庫的信息。CQDatabases對象代表該對象的集合。
CQSchema對象:表示模式數據庫中的模式,該對象提供若干模式修訂用於更新數據庫。開發人員不能 通過編程方式修改該對象。CQSchemas對象代表該對象的集合。
CQSchemaRev對象:每一次對模式數據庫中模式的修訂,都會產生一個SchemaRev對象。開發人員不能 通過編程修改該對象,而只能使用Rational ClearQuest Designer工具對模式進行修改。CQSchemaRevs對 象代表該對象的集合。
CQGroup對象:代表模式數據庫中的一個用戶組。該對象包含基本的組信息,組成員信息以及該組訂閱 的數據庫信息。CQGroups對象代表該對象的集合。
CQUser對象:代表模式數據庫中的一個用戶。該對象包含用戶的基本信息,該用戶所屬組的信息以及 訂閱的數據庫信息。CQUsers對象代表該對象的集合。
CQPackageRev對象:該對象不被API支持。CQPackageRevs對象代表該對象的集合。
圖4. 模式數據庫對象
使用CQ Java API 實現與Rational CQTM集成
本文中示例的應用場景是一個使用Java語言開發的Web服務測試工具,測試人員需要使用該測試工具進 行Web服務測試並將測試結果錄入到CQTM中實現對測試結果的管理。因此,測試人員需要為CQTM的每個測 試用例創建日志記錄,並將測試工具的執行結果逐項地填寫到測試日志中。例如,測試人員在測試工具中 分別創建了兩個測試用例case1和case2,用於對serviceA和serviceB進行測試。執行後得到兩個執行結果 , case1執行成功,表明serviceA的功能正常,但是由於serviceB的實現存在問題,導致case2執行失敗 ,得到異常信息。接下來,測試人員需要將得到的執行結果記錄到CQTM中進行管理。首先,他先在CQTM的 測試計劃中找到對應於case1和case2的兩個測試用例,然後為測試用例創建一個空的日志記錄並根據測試 工具中的執行結果,依次填寫測試結果(成功、失敗、不確定等)、測試時間,測試執行人員、導致測試 失敗的原因等信息。從中我們可以看出,當待測服務數量比較大的時候,創建日志是一件非常耗時並容易 出錯的事情。因此,為了解決這個問題,測試工具的開發人員決定利用CQ Java API實現測試工具與CQTM 的集成,使得測試人員可以將測試工具中的執行結果很方便地導入到CQTM的測試管理框架中。
該測試工具是一個Web應用,運行於應用服務器WAS之上。為了能夠與CQTM實現集成,我們必須將 ClearQuest client與應用服務器安裝在同一台機器上,ClearQuest的數據庫系統可以安裝在任何一台機 器上。系統的基本架構如圖5所示。安裝完畢後,需要進行以下配置。
設置系統環境變量:將ClearQuest安裝目錄添加到系統環境變量PATH中,例如C:\Program Files\Rational\common。
在ClearQuest的安裝目錄下,將cqjni.jar和cqjniproxy.dll拷貝到WAS的lib目錄下。
圖5. 集成系統架構
在正確配置環境之後,您便可以開始實現測試工具與CQTM功能的集成。為了能夠在CQTM中自動為每個 測試用例創建日志記錄,並將測試工具中得到的測試結果寫入日志記錄中,我們首先必須登錄到CQTM數據 庫,這是調用CQTM 其他功能的前提。然後我們將執行相應的查詢活動,得到創建日志記錄所需的相關信 息。接下來,我們將會為CQTM中的每個測試用例創建日志類型的記錄,填充必要的日志信息並保存到數據 庫中。
為了讓讀者能夠更多地了解CQTM的功能,在本文接下來的討論中,我們除了對導入日志所需的功能進 行介紹外,還會對其他一些比較常用的功能進行介紹,盡可能地讓您了解到更多的CQ API。此外,我們在 逐一向您講解實現集成功能的代碼的同時,還會與通過ClearQuest Client實現該功能的步驟進行對比, 幫助您更好地理解程序代碼。
登錄到用戶數據庫
該功能將向您展示如何連接到Rational ClearQuest的用戶數據庫。獲取連接是執行其他各項操作的前 提。我們首先向您介紹如何通過ClearQuest Client創建一個連接並登錄到指定的用戶數據庫,幫助您更 好地理解此項功能。之後,向您講解相應的實現代碼。
1. 打開ClearQuest Client,在頂部的菜單欄中,點擊連接按鈕,在彈出的下拉列表中,選擇New Connection.
圖6. 創建新連接
2. 在模式數據庫頁面從下拉列表中選擇所需的模式數據庫。
圖7. 模式數據庫選擇頁面
3. 在額外連接信息頁面,填寫登錄用戶名,並點擊Finish按鈕關閉此對話框。
圖8. 額外登錄信息頁面
4. 在連接對話框中,填寫登錄密碼並選擇登錄到的用戶數據庫。選中 Remember the password復選框 ,這將為後續操作保存密碼。
圖9. 連接對話框
5. 如果填寫的信息正確,您將成功地登錄到指定的用戶數據庫。此時,在Test Manager視圖中,您將 會看到出現一個新的連接信息。
圖10. Test Manager視圖
通過以上操作,您可以創建一個連接並登錄到指定的用戶數據庫,相應的實現代碼清單1所示。該代碼 片斷中用到的主要對象為CQSession對象。對於外部的應用程序來說,必須創建一個CQSession對象並使用 該對象登錄到數據庫。成功登錄後,開發人員還可以使用該對象,完成多種任務,包括創建新的數據庫記 錄和查詢,編輯已經存在的記錄以及查看數據庫的信息。該功能的具體實現步驟為:
第1行,創建一個新的CQSession對象。
第2-6行,為了確保我們登錄到的用戶數據庫名稱,我們可以通過CQSession對象的 GetAccessibleDatabases方法得到與一個特定的模式數據庫相關的所有用戶數據庫信息。 GetAccessibleDatabases方法的語法為
需要注意的是,該方法只返回允許指定用戶訪問的用戶數據庫信息。如果方法中第二個參數 user_login_name為空字符串的話,該方法將返回所有與指定模式數據庫(master_db_name) 關聯的用戶數 據庫信息。開發人員可以進一步訪問得到的每一個CQDatabaseDesc對象,從而得到相應的數據庫名稱,數 據庫集合的名稱以及其他登錄所需的信息。
第8行,指定具體的登錄信息,通過CQSession對象的UserLogon方法,登錄到指定的用戶數據庫。其中 ,UserLogon方法的語法結構為
其中,第一個參數對應步驟3中指定的UserID信息, 中間兩個參數對應步驟4中指定的Password和 Database信息,第四個參數對應步驟2中指定的Schema Repository.
清單1. 連接到用戶數據庫
// get a cqsession object
1 CQSession cqSession = new CQSession();
// get a list of dbs associated with a schema repository
2 CQDatabaseDescs dbDescs = cqSession.GetAccessibleDatabases(
“master_db_name”,
“user_login_name”,
“database_set”);
3 CQDatabaseDesc dbDesc = null;
4 for(int i=0; i<dbDescs.count(); i++){
5 dbDesc = dbDescs.item(i);
6 String dbName = dbDesc.getDatabaseName();
7 If(dbName.equals(“db”)){
// log on to the specified user db
8 cqSession.UserLogon(
“userName”,
“userPwd”,
dbName,
dbDesc.getDatabaseSetName()
);
9 break;
10 }
11 }
在成功地登錄到數據庫之後,創建的CQSession對象將對整個登錄會話有效,像JSP中的session對象一 樣,我們可以在CQSession對象中設置會話變量用於保存全局的信息並在之後讀取該變量的值。示例代碼 如清單2所示。
第1行,使用CQSession對象的SetNameValue方法,創建一個會話變量,第一個參數為變量的名稱,第 二個參數為賦予該變量的值。如果該會話變量已經存在,SetNameValue方法將會使用新值覆蓋掉原來的變 量值。
第2行,利用HasValue方法判斷會話變量是否存在。
第3行,利用CQSession對象的GetNameValue方法獲取會話變量的值,其中的參數為變量的名稱。
清單2. 使用會話變量
1 cqSession.SetNameValue("userAge", "25");
2 if(cqSession.HasValue("userAge")){
3 System.out.println(cqSession.GetNameValue("userAge"));
4 }
在本節中,我們向您介紹了如何通過API登錄到指定的CQTM數據庫。在成功登錄之後,為了創建日志記 錄,我們需要查詢構造記錄所需的其他信息,包括迭代信息、配置信息等。下面,我們就以查詢配置信息 為例,向您介紹如何創建數據庫查詢。
創建數據庫查詢
查詢用於指定從數據庫中獲取數據的規則。在CQ中,創建查詢主要有以下幾個步驟:
構造一個查詢(CQQueryDef對象),指定欲查找的數據。CQQueryDef對象包含查詢的規則定義。
創建一個數據集(CQResultSet對象)存儲查詢得到的數據。
執行查詢,將查詢結果寫入數據集中。
遍歷數據集,對查詢結果進行分析。
本節我們以 查詢測試的配置信息為例(如圖11),向您展示如何構造查詢規則、執行查詢以及解析查 詢結果。
圖11. 配置信息
實現程序的代碼片段如清單3所示。具體的實現步驟為:
第1行,利用CQSession對象的BuildQuery方法,構造一個CQQueryDef對象。其中的參數為測試記錄類 型的名稱。本例中,配置記錄類型名為TMConfiguration。關於其他記錄類型請參考本文第二部分對CQTM 術語的介紹。如果您對記錄類型不明確的話,也可以使用BuildSQLQuery方法,通過構造SQL表達式,定義 查詢規則。
第2行,利用CQQueryDef對象的BuildField方法指定包含在查詢結果中的字段。在執行查詢之前,您必 須指定至少一個字段包含在結果集中。每指定一個字段,都要調用一次BuildField方法。本例中,只添加 了一個字段Name, 即配置的名稱。
第3行,利用CQSession對象的BuildResultSet方法,構造一個結果集,用於執行查詢並記錄查詢結果 。CQResultSet對象將按照BuildField方法添加字段的順序記錄查詢結果。
第4行,利用CQResultSet對象的ExecuteAndCountRecords方法,執行查詢並返回查詢結果數量。您也 可以使用Execute方法執行查詢,再利用其他方法得到結果的數量。
第5行,利用ResultSet對象的MoveNext方法,將光標移動到結果集中的下一條記錄。如果返回值為1, 表示光標移動成功,即存在下一條記錄。
第6行,利用ResultSet對象的GetColumnValue方法,得到當前行中指定列的值。列的計數從1開始。
清單3. 查詢配置信息
// create a query for record "TMConfiguration"
1 CQQueryDef queryDef = cqSession.BuildQuery(“TMConfiguration”);
// set display fields
2 queryDef.BuildField("Name");
3 CQResultSet resultSet = cqSession.BuildResultSet(queryDef);
4 long records = resultSet.ExecuteAndCountRecords();
5 while (resultSet.MoveNext()== 1) {
6 String name = resultSet.GetColumnValue(1);
}
在本節中,我們向您介紹了如何通過API查詢數據庫記錄。細心的您會發現,使用本節介紹的API得到 的結果集包括特定數據表的所有記錄,而不能有選擇地進行查詢,即查詢具有特定約束條件的記錄。為了 實現對數據庫查詢的過濾,請您閱讀下一節“過濾數據庫查詢”。
過濾數據庫查詢
如果您的查詢規則包含比較運算的話,就需要通過一個過濾器(filter)實現,即CQQueryFilterNode對 象。一個過濾器允許您將一個字段與單個值或一個范圍進行比較,過濾器中的操作符指定比較的類型。關 於操作符的描述請見表格1。
我們將查詢表達式組成一棵樹的形式,樹中的節點為邏輯運算符。通過邏輯運算符,可以將多個過濾 器連接起來。每個過濾器可以包含一個條件表件式或多個條件表達式,它們之間通過And或者Or運算符關 聯在一起。
對於清單4中的查詢表達式,需要查詢關於缺陷 (defect) 描述的信息,要求缺陷的提交日期不超過 01/03/2008,而且提交者必須為bill或admin. 相應的實現代碼請見清單5.
第1行,創建一個關於缺陷記錄類型(TMDEFECT)的CQQueryDef對象。
第2行,指定結果集中包含的字段是缺陷的描述信息。
第3行,調用QueryDef對象的BuildFilterOperator方法創建查詢樹中的根節點(CQQueryFilterNode對 象) 。QueryDef對象的該方法是構造一個查詢表達式的入口點。開發人員必須調用該方法得到查詢表達式 中的第一個過濾器。從這個節點出發, 進而構造查詢規則中的其他過濾節點。其中, BuildFilterOperator方法的參數為一個long型的整數,代表邏輯操作符(1為邏輯與,2為邏輯或)。
第4行,通過CQQueryFilterNode對象的BuildFilterOperator方法創建一個內嵌的CQQueryFilterNode 對象包含指定的邏輯運算符。
第5-7行,通過調用BuildFilter方法為邏輯運算符節點增加一個過濾器,該方法將一個字段和一個或 一組值進行比較。其中,第一個參數為字段的名稱,第二個參數為比較運算符,第三個參數為字符串數組 。
清單4. 查詢表達式
Select id from CQSTF_DEFECT where state = “Fixed” AND
(owner = ‘bill’ OR owner = ‘admin’)
清單5. 過濾查詢代碼
// create a query for record " TMDEFECT"
1 CQQueryDef queryDef = cqSession.BuildQuery(“TMDEFECT”);
// set display fields
2 queryDef.BuildField("id");
3 CQQueryFilterNode filterNode1 = queryDef.BuildFilterOperator(1);
4 CQQueryFilterNode filterNode2 = filterNode1.BuildFilterOperator(2);
5 filterNode2.BuildFilter("Owner", 1, new String[]{“bill”});
6 filterNode2.BuildFilter("Owner", 1, new String[]{“bill”});
7 filterNode1.BuildFilter("State", 1, new String[]{“Fixed”});
8 CQResultSet resultSet = cqSession.BuildResultSet(queryDef);
9 resultSet.Execute ();
表格1. 比較運算符
常量值 描述 1 等於運算符(=) 2 不等於運算符(<>) 3 小於運算符 (<) 4 小於等於運算符 (<=) 5 大於運算符 (>) 6 大於等於運算符 (>=) 7 Like運算符(值是指定字段字符串值的子串) 8 Not-like運算符(值不是指定字段字符串值的子串) 9 Between操作符(值在指定的多個分隔值之中) 10 Not-between操作符(值不在指定的多個分隔值之中) 11 Is-NULL操作符(字段不包含任何值) 12 Is-Not-NULL操作符(字段包含值) 13 In操作符(值在指定的集合中) 14 Not-In操作符(值不在指定的集合中)
在本節中,我們向您介紹了如何過濾數據庫查詢。在查詢得到了所需的信息之後,我們便可以創建日 志記錄,並填充記錄的相關信息。下面,我們就一起來看看如何創建一個數據庫記錄。
創建數據庫記錄
數據庫使用記錄組織和存儲信息。在ClearQuest中,記錄(CQEntity)指的是一種結構信息,用於將 特定記錄類型 (CQEntityDef) 的實例的信息組織起來。ClearQuest使用CQEntity對象組織和管理記錄數 據。每一個CQEntity對象提供對記錄中任何已定義的字段數據的訪問,包括記錄的歷史數據,與該記錄相 關聯的文件信息等。
本節通過為已配置的測試用例創建日志記錄為例,向您介紹如何創建一個特定類型的用戶數據庫記錄 。在ClearQuest Client中,為已配置的測試用例手動創建日志記錄的步驟如下:
1. 選擇一個已配置的測試用例,點擊右鍵,選擇New Test Log選項。
圖12. 創建日志記錄
在彈出的創建日志記錄對話框中,填寫必要的信息。其中,紅色圓圈標識的字段為必填字段,包括
Verdict:記錄配置測試用例的執行結果。有四種類型,Pass, Fail, Inconclusive, Error.
Start Time/End Time: 測試腳本執行的啟動和終止時間。
Owner: 創建該日志記錄的用戶。
圖13. 日志記錄主頁面
對應於上述操作的實現代碼請見清單6. 該代碼片段實現了為指定的配置測試用例創建一個日志記錄的 功能。
第1行,利用CQSession對象的BuildEntity方法,創建一條指定類型的記錄(類型為TMTestLog的 CQEntity對象)。此外,該方法還初始化了一個提交(submit)活動,使得開發人員可以對記錄的內容進行 編輯(不必調用EditEntity方法將記錄設為可編輯的狀態)。
第2-9行,利用CQEntity對象的SetFieldValue方法,為記錄的指定字段賦值。該方法的第一個參數為 字段的名稱,第二個參數為賦予該字段的值,返回一個包含結果信息的字符串。通過返回的字符串,可以 看出賦予該字段的值是否有效。如果該值有效,則返回空字符串;如果字段是不可更改的,在返回的字符 串中會指明為什麼該字段不可改變,典型的返回值包括”no such field”, “record is not being edited”, “field is read-only”等。如果該字段可以包含多個值,可 以使用AddFieldValue方法為其添加多個值。SetFieldValue方法只適用於可以被編輯的CQEntity對象,為 了讓一個CQEntity對象可以被編輯,我們可以通過調用CQSession對象的EditEntity方法實現,這將在後 續的介紹中涉及。
第10行,調用CQEntity對象的validate方法,對創建的CQEntity對象進行驗證並報告出現的錯誤。在 一個CQEntity對象被提交之前,即使沒有字段被改變,我們也建議您需對其進行驗證。如果驗證中出現錯 誤,該方法會返回一個包含錯誤信息的字符串,否則,返回空字符串。請不要通過編程方式試圖對包含錯 誤信息的字符串做進一步的處理,因為在後續的版本中,返回的字符串中的錯誤信息很可能會發生變化。
第11-22行,如果驗證正確的話,我們需要調用CQEntity對象的commit方法將新創建的日志記錄提交到 用戶數據庫。該方法可以提交任何改變到數據庫。如果在提交過程中出現錯誤的話,該錯誤將被作為異常 拋出。如果在提交完成之後出現錯誤的話,錯誤信息將被包含在字符串中返回。
清單6. 過濾查詢代碼
1 CQEntity record = cqSession.BuildEntity(“TMTestLog”);
2 record.SetFieldValue("ConfiguredTestCase", selectedCQLog[i]);
3 record.SetFieldValue("Owner", owner);
4 record.SetFieldValue("Verdict",mapping.get(i).getResult());
5 record.SetFieldValue("StartTime",
new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss").format(new Date()));
6 record.SetFieldValue("EndTime",
new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss").format(new Date()));
7 record.SetFieldValue("Build", buildNum);
8 record.SetFieldValue("BuildNum", buildNum);
9 record.SetFieldValue("Iteration", iteration);
// save the record
10 String result = record.Validate();
11 if (result.equals("")) {
// if there is no validation errors
12 try{
13 result = record.Commit();
14 if (!result.equals("")) {
15 throw exception;
16 }
17 }catch(Exception e){
18 throw e;
19 }
20 } else {
21 throw exception;
22 }
到此,我們就已經完成了對一條日志記錄的創建和存儲。在測試工具的代碼中,我們就是通過以上的 步驟,將測試工具中得到的測試結果一條一條地導入到CQTM中。接下來,我們將一起討論CQTM中其他的常 用功能。
編輯已存在的數據庫記錄
本節主要向您講述如何獲取已經存在的數據庫記錄並對該記錄進行編輯。CQ提供了多種方法從用戶數 據庫中獲取一條記錄 (CQEntity)。如果您知道該實體對象的ID值,可以使用CQSession對象的GetEntity 或者GetEntityByDbId方法得到實體對象。否則,可以使用CQSession對象的BuildQuery方法創建一個查詢 ,執行後得到符合條件的實體對象。通過以上方法得到的實體對象都是只讀的,為了能夠對實體對象進行 編輯,開發人員必須調用CQSession對象的EditEntity方法。清單7中的示例代碼用於得到一個缺陷記錄列 表,並修改其中的特定缺陷記錄。
第1-5行,構建一個對缺陷記錄的查詢對象,指定結果集為缺陷記錄的id字段和Headline字段。
第8-10行,執行後遍歷結果集,得到每條記錄的id信息。調用CQSession對象的GetEntity方法,得到 相應的實體對象。GetEntity方法的語法結構為:
第一個參數為記錄類型的名稱,第二個參數為記錄的顯示名稱。通常,為記錄的ID字段的值。您也可 以通過調用CQEntity對象的GetDisplayName方法查看。
之前,我們提到過,除了使用GetEntity方法,我們也可以通過GetEntityByDbId方法得到實體對象, 該方法也包含兩個參數,第一個參數與GetEntity方法相同,為記錄類型的名稱,第二個參數為數據庫ID (db_id), 可以通過調用CQEntity對象的GetDbId獲得。
第11行,得到每條記錄的Headline字段的值,注意,這裡我們使用了CQEntity對象的 GetFieldStringValue方法來獲取字段的值,而不是GetColumnValue方法。
第13行,我們通過調用CQSession對象的EditEntity方法,將指定的實體對象設置為可編輯的狀態。這 裡需要注意的是,如果實體對象是通過GetEntityByDbId或GetEntity方法或執行查詢得到的,就需要調用 EditEntity方法設置實體對象的狀態。如果實體對象時使用BuildEntity方法創建的而且還未提交到數據 庫,則該實體對象已經處於可編輯的狀態,因此,不需要使用EditEntity方法。該方法的語法為
第一個參數為CQEntity對象,第二個參數為一個字符串,用於指定編輯的行為。對於特定記錄類型的 實例的編輯行為,我們可以通過清單8中的方法查看。
第14行,通過CQEntity對象的SetFieldValue方法改變實體對象的值。
第15-16行,驗證通過後,提交對實體記錄的修改到用戶數據庫。
清單7. 修改已存在的記錄
1 CQQueryDef queryDef = cqSession.BuildQuery("TMDEFECT");
// set display fields
2 queryDef.BuildField("id");
3 queryDef.BuildField("Headline");
4 CQResultSet resultSet = cqSession.BuildResultSet(queryDef);
5 resultSet.Execute();
6 String id = null;
7 String headline = null;
8 while(resultSet.MoveNext() == 1){
9 id = resultSet.GetColumnValue(1);
10 CQEntity entity = cqSession.GetEntity("TMDEFECT", id);
11 headline = entity.GetFieldStringValue("HeadLine");
12 if(id.equals("CQSTF00000141")){
13 cqSession.EditEntity(entity, "Modify");
14 entity.SetFieldValue("Description", "This defect has been modified");
15 entity.Validate();
16 entity.Commit();
17 }
18 }
清單8. 獲取編輯活動名稱
1 CQEntityDef entityDef = cqSession.GetEntityDef("TMDEFECT");
2 String[] actions = entityDef.GetActionDefNames();
3 for(String action: actions){
4 System.out.println(action);
5 }
訪問模式數據庫
通常,用戶都通過Rational ClearQuest Designer工具修改模式數據庫 (master數據庫)。但是,在某 些情況下,開發人員需要通過API實現對模式數據庫的訪問並進行一定的修改。由於模式數據庫與用戶數 據庫不同,您不能使用CQSession對象登錄到模式數據庫並訪問其中的數據。而必須使用CQAdminSession 對象來完成這樣的操作。通過CQAdminSession對象,您可以訪問與指定模式數據庫相關聯的用戶數據庫信 息。每個用戶數據庫都被表示為一個Database對象。您可以使用該對象得到並設置用戶數據庫的某些信息 ,如登錄用戶名、密碼以及數據庫自身的設置等。我們將分別三個部分向您介紹對模式數據庫的訪問功能 ,包括模式數據庫登錄、訪問模式數據庫中的對象、更新用戶數據庫信息。
登錄模式數據庫
清單9中的代碼片段實現了登錄到指定模式數據庫的功能。首先創建一個CQAdminSession對象,然後指 定登錄的具體信息,包括登錄用戶名、密碼和數據庫集的名稱。
清單9. 登錄模式數據庫
1 CQAdminSession adminSession = new CQAdminSession();
2 adminSession.Logon("admin", "admin", "dbSet");
訪問模式數據庫中的對象
大多數模式數據庫的信息都可以通過訪問對象的屬性信息獲得。例如,CQAdminSession對象包含多個 屬性,可以得到與特定模式數據庫相關的用戶數據庫信息列表、模式列表、所有的用戶和組信息列表。如 果您知道對象名稱的話,也可以通過CQAdminSession對象得到指定的對象。此外,通過CQAdminSession對 象還可以創建新的數據庫、用戶帳戶和用戶組。如清單10中的代碼片段所示,
第1-2行,通過CQAdminSession對象,得到與特定模式數據庫相關聯的數據庫對象列表和組對象列表。 您可以進一步對對象列表中的對象進行解析。
第3行,通過CQAdminSession對象,得到指定名稱的CQUser對象。
第4-7行,通過CQAdminSession對象,創建了一個新的用戶對象,並設置了其中的屬性值,最終將其添 加到指定的用戶組中。
清單10. 訪問模式數據庫中的對象
1 CQDatabases dbs = adminSession.GetDatabases();
2 CQGroups groups = adminSession.GetGroups();
3 CQUser user = adminSession.GetUser("bill");
4 CQUser aUser = adminSession.CreateUser("testUser");
5 user.SetEmail("[email protected]");
6 user.SetPassword("testUser");
7 groups.Item(0).AddUser(aUser);
更新用戶數據庫信息
在提交了新的對象或修改後,這些修改在模式數據庫中會立即生效。但需要注意的是,如果您修改了 關於用戶和組的信息的話,則必須更新關聯的用戶數據庫。例如,如果想要把對模式數據庫中用戶信息的 修改同步到關聯的用戶數據庫中,可以采取以下兩種方法實現:
利用CQUser對象的UpgradInfo方法。該方法可以更新用戶信息(如is-active, e-mail, full name, phone等)到所有該用戶訂閱的數據庫。但該方法不能更新組中成員的信息。
利用CQDatabase對象的UpgradMasgterUserInfo信息。該方法可以更新一個數據庫的所有用戶和組信息 。
對於已經存在的用戶,開發人員可以采取以下方法完成更新同步:
得到指定模式數據庫的用戶數據庫列表,循環訪問每一個用戶數據庫對象,調用該對象的 UpgradMasterUserInfo方法進行更新。
調用用戶對象的UpgradInfo方法.
對於新創建的用戶,如果是通過CQAdminSession對象的CreateUser方法創建的話,您必須循環訪問每 一個用戶數據庫,利用該對象的UpgradMasterUserInfo方法進行更新。UpgradInfo方法只適用於已經存在 的用戶。
結束語
通過閱讀本文,我們可以看出Rational ClearQuest是一個高度可定制化的產品,提供了豐富的程序接 口,幫助開發人員定制自己應用程序,實現與CQTM的功能集成。本文通過多個實例,向您闡述了CQ Java API提供的常用功能。希望通過本文的介紹,能夠幫助開發人員更好地理解和掌握CQ Java API,在未來的 工作中能夠付諸實踐。