幫助文件裏整理了一下
1
.測試對象屬性(控件)的值
Object getProperty(String propertyName);
The following example uses the
getProperty
method to test whether a value of a property is being captured and reproduced correctly. The call to getProperty
retrieves the value of the text property associated with the ThankYouXLabel
object.例子:
public class PropertyFetch extends PropertyFetchHelper
{
public void testMain (Object[] args)
startApp("GetName");
}
checkSetName("Tony");
checkSetName("Maria");
// Window: Functional Test GetName
GetNameFrame().close();
}
public void checkSetName(String name)
{
// Window: Functional Test GetName
// User clicks on button for help
helpgifButton().click();
//Display input name
InputWindow().inputKeys(name);
OKButton().click();
// Fetches value of text property
String ThankyouX_text =
(String)ThankyouXLabel().getProperty("text");
// Compares text property with input name.
// Pass or Fail logged based on the outcome.
logTestResult("name test",
ThankyouX_text.equals("Thank you "+name));
OKButton2().click();
}
}
2.添加靜態的驗證點
IFtVerificationPoint vpManual (java.lang.String vpName, java.lang.Object
actual)
IFtVerificationPoint vpManual (java.lang.String vpName, java.lang.Object
expected, java.lang.Object actual)
例子vpManual ("manual1", "The rain in Spain").performTest();
vpManual ("manual1", "The rain in Spain", "The Rain
in Spain").performTest();//有對照,期望值與實際值。
3.添加動態的驗證點
IFtVerificationPoint vpDynamic (java.lang.String vpName)
IFtVerificationPoint vpDynamic (java.lang.String vpName, TestObject
objectUnderTest)
例子:vpDynamic ("dynamic1").performTest();
vpDynamic ("dynamic1",
AnAWTButtonButton()).performTest();如果在第二次回放中沒有發現AnAWTButtonButton這個按鈕,就會給出一個錯誤報告
4.處理不明確的識別
當有多個瀏覽器打開時,測試又只進行一個,這時對象識別不明確
BrowserToolbar_Back().click();
BrowserToolbar_Forward().click();
改動後
BrowserToolbar_Back(Browser_htmlBrowser(Document_MyHomePage(),
DEFAULT), DEFAULT).click();
再次改動,先定義一個對象
TestObject browserOne = Browser_htmlBrowser(Document_MyHomePage(),
DEFAULT).find();
BrowserToolbar_Back(myBrowser, DEFAULT).click();
一個測試運行多個程序
ProcessTestObject p1 = startApp("SwingTest");
ProcessTestObject p2 = startApp("TryIt");
//b5().click(); ambiguous on playback; which application?
b5(p1, DEFAULT).click();
由於瀏覽器安全等級改變或切換頁面造成警告
錄製的可能腳本
linkThatLeavesSecurePage().click();
Dialog_HtmlDialogButtonOK().click();
CheckboxOnTheUnsecurePage().click();
一個解決辦法就是等待消息出現,如果沒有出現,你就可以繼續了。可以通過以下代碼解決
linkThatLeavesSecurePage().click();
try
{
Dialog_HtmlDialogButtonOK().click();
} catch(ObjectNotFoundException e) {}
CheckboxOnTheUnsecurePage().click();
以上辦法解決了主要目標,如果警告消息出現,我們解除了它;如果沒有出現,我們最後停止等待並繼續。如果我們知道警告消息大概在多少秒後出現,我們可以通過以下方法解決
linkThatLeavesSecurePage().click();
try
{
Dialog_HtmlDialogButtonOK().waitForExistence(5,1);
Dialog_HtmlDialogButtonOK().click();
}
catch(ObjectNotFoundException e) {}
CheckboxOnTheUnsecurePage().click();
最好的解決辦法:在helper super script裏添加執行,然後繼承這個helper super class來處理腳本中的事件。下面爲一個例子,代碼實現了一個基礎類,基礎類實現了方法onObjectNotFound;這個方法檢查所有HTML域和對話框。如果有警告就處理,沒有就繼續運行回放。
import com.rational.test.ft.script.*;
import com.rational.test.ft.object.interfaces.*;
public abstract class HtmlScript extends RationalTestScript
{
public void onObjectNotFound(ITestObjectMethodState testObjectMethodState)
{
boolean dismissedAWindow = false;
DomainTestObject domains[] = getDomains();
for (int i = 0; i < domains.length; ++i)
{
if (domains[i].getName().equals("Html"))
{
// HTML domain is found.
TestObject[] topObjects = domains[i].getTopObjects();
if (topObjects != null)
{
try
{
for (int j = 0; j < topObjects.length; ++j)
{
if (topObjects[j].getProperty(".class").equals("Html.Dialog"))
{
// A top-level HtmlDialog is found.
logWarning("HtmlScript.onObjectNotFound - dismissing dialog.");
try
{
dismissedAWindow = true;
((TopLevelTestObject)topObjects[j]).inputKeys("{enter}");
}
catch(RuntimeException e) {}
}
}
}
finally
{
//unregister all references to top objects
unregister(topObjects);
}
}
}
}
if (dismissedAWindow)
{
// try again
testObjectMethodState.findObjectAgain();
}
else
{
logWarning("HtmlScript.onObjectNotFound; no Html Dialog to dismiss");
}
}
}
6.確定表中單元的值(內容)
import resources.TableTestHelper;
import com.rational.test.ft.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;
import com.rational.test.ft.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;
public class TableTest extends TableTestHelper
{
public void testMain (Object[] args)
{
startApp("TableTest");
{
public void testMain (Object[] args)
{
startApp("TableTest");
// Browser: MS Internet Explorer
// Document: Table Test Page: file:
//D:/Temp/TableTest.html
// Document: Table Test Page: file:
//D:/Temp/TableTest.html
//Click on table to generate an object in the Object Map.
Table_AutoNumber1().click(atCell(
atRow(atIndex(1)), atColumn(
atIndex(1))));
Table_AutoNumber1().click(atCell(
atRow(atIndex(1)), atColumn(
atIndex(1))));
//Query object to find out what kind of data it has.
System.out.println (Table_AutoNumber1().getTestDataTypes());
System.out.println (Table_AutoNumber1().getTestDataTypes());
//Declare variable for table.
ITestDataTable myTable;
myTable = TestDataTable)Table_AutoNumber1().getTestData("grid");
ITestDataTable myTable;
myTable = TestDataTable)Table_AutoNumber1().getTestData("grid");
//Print out total rows & columns.
System.out.println ("Total Rows: " + myTable.getRowCount());
System.out.println ("Total Cols: " + myTable.getColumnCount());
System.out.println ("Total Rows: " + myTable.getRowCount());
System.out.println ("Total Cols: " + myTable.getColumnCount());
//Print out cell values.
for (int row =0;row < myTable.getRowCount();row++)
{
for (int col = 0;col < Table.getColumnCount();col++)
{
System.out.println("Value at cell (" + row+ "," + col+")
is: " + myTable.getCell(row,col));
}
}
for (int row =0;row < myTable.getRowCount();row++)
{
for (int col = 0;col < Table.getColumnCount();col++)
{
System.out.println("Value at cell (" + row+ "," + col+")
is: " + myTable.getCell(row,col));
}
}
Browser_htmlBrowser(Document_TableTestPage(),MAY_EXIT).close();
}
}
}
}
import resources.GetGridDataExampleHelper;
import com.rational.test.ft.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;
public class GetGridDataExample extends GetGridDataExampleHelper
{
public void testMain (Object[] args)
{
// Turn off Log Viewer for this example
setOption(IOptionName.BRING_UP_LOGVIEWER, false);
// Start Classics Java Application
startApp("ClassicsJavaA");
// Navigate to Existing Order Grid
jmbMenuBar().waitForExistence();
jmbMenuBar().click(atPath("Order"));
jmbMenuBar().click(atPath("Order->View Existing Order Status..."));
// Frame: View Order Status
nameComboBComboBox().click();
nameComboBComboBox().click(atText("Claire Stratus"));
okstatuslogon2Button().click();
// Wait for table to be created
existingTableTable().waitForExistence();
// Get the data for the table,第一步:從控制器從取得數據
ITestDataTable orderTable;
orderTable
(ITestDataTable)existingTableTable().getTestData("contents");
// Display the available data types for the grid, total rows and
// columns.通過
getTestDataTypes
方法告知控制器哪些數據是可利用有效的System.out.println ("Available Data Types: " +
existingTableTable().getTestDataTypes())
System.out.println ("Total Rows in table : " +
orderTable.getRowCount());
System.out.println ("Total Cols in table : " +
orderTable.getColumnCount());
// Cycle through all rows(
getColumnCount,
getColumnCount方法開始循環起點爲0)for (int row=0; row < orderTable.getRowCount();++row)
{
// Cycle through all columns
for (int col=0; col < orderTable.getColumnCount();++col)
{
// Print out values of cells at (row,col) coordinates
System.out.println ("Row " + row + ", " +
orderTable.getColumnHeader(col) + ": "
+orderTable.getCell(row,col) );
}
}
// Close the frame
closeorderButton().click();
// Shut down Classics Java Application
ClassicsJavaFrame(ANY,MAY_EXIT).close();
}
}
//沒有參數 callScript("TheCalled");
//數組參數
String[] dataToPass = new String[4];
callScript("TheCalled",dataToPass);
//對象參數
Object[] objdataToPass = new Object[4];
callScript("TheCalled",objdataToPass);
錄製的腳本,使用方法document_htmlDocument()來調用頁面的Document對象,使用方法text_q()來調用搜索輸入框,使用方法button_search()來調用搜索按鈕。這些方法是由腳本SearchLotusLink的父類SearchLotusLinkHelper定義的
protected GuiTestObject document_htmlDocument()
{
return new GuiTestObject(getMappedTestObject("document_htmlDocument"));
}
類:com.rational.test.ft.object.interfaces.TestObject,而它的方法find(Subitem properties)正是用來在某個特定範圍內查找滿足條件的所有對象。改造後,回放過程中所需要用到的頁面對象都是在當前瀏覽器中即時查找得到的。通過目標對象的類型和某個屬性值來定位目標對象
protected GuiTestObject document_htmlDocument() {
return new GuiTestObject(findTestObjectInBrowser(".class","Html.HtmlDocument",null,null));
}
protected TestObject findTestObjectInBrowser(String property1, String value1, String property2,
String value2)
{ TestObject[] foundTOs ;
//
在當前瀏覽器頁面中查找
if(null==property2)
foundTOs = browser_htmlBrowser().find(atDescendant(property1,value1)) ;
else
foundTOs = browser_htmlBrowser().find(atDescendant(property1,value1,property2,value2)) ;
//
如果沒有找到滿足條件的
TestObject
if(foundTOs.length<1)
{
throw new com.rational.test.ft.ObjectNotFoundException("Can NOT find TestObject with
"+property1+"<"+value1+">,"+property2+"<"+value2+">");
} //
如果找到多個
TestObject
滿足條件,
else if(foundTOs.length>1)
{
throw new AmbiguousRecognitionException("Found multi-TestObject with
"+property1+"<"+value1+">,"+property2+"<"+value2+">");
} //
返回唯一的查找結果
return foundTOs[0];
}
10.添加等待時間
- 定長等待
調用Java腳本的公共父類com.rational.test.ft.script.RationalTestScript裏的方法:sleep(double seconds)。這一方法可以使回放過程等待若干秒。
這種方式直觀、簡單。但缺點也是明顯的:固定的時間常常不能適應多變的真實環境:等待時間設置得過長,無疑會拉長測試的回放時間,降低效率;等待時間設置得過短,在某些情況下,又無法起到延時應有的效果,仍然錯過了被測對象。 - 不定長等待
腳本記錄器記錄下的這些頁面對象都是從接口com.rational.test.ft.object.interfaces.TestObject繼承下來的,在TestObject中有一個方法waitForExistence()可以用以實現不定長的等待。在一定的時間限度內,等待該對象的出現;一旦出現後就不再等待,程序繼續往下執行。最大時間限度是在"首選項"的"回放"選項裏設置的。不定長等待既達到靈活等待的目的,又沒有浪費不必要的等待時間,是一個值得推薦的解決方案。
11. 如何提高腳本的複用程度和兼容性
1) 充分利用Rational Functional Tester的強大功能,比如ScriptAssure技術、正則表達式,數據驅動,Rational Functional Tester API等;2) 合理地編寫、優化腳本。提綱挈領地對測試過程進行抽象,對關鍵過程進行必要的驗證。
import resources.GetListDataExampleHelper;
import com.rational.test.ft.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;
public class GetListDataExample extends GetListDataExampleHelper
{
public void testMain (Object[] args)
{
startApp("ClassicsJavaA");
{
public void testMain (Object[] args)
{
startApp("ClassicsJavaA");
// Frame: ClassicsCD
tree2Tree().click(atPath("Composers->Schubert->Location(PLUS_MINUS)"));
tree2Tree().click(atPath("Composers->Schubert->Die schone Mullerin, Op. 25"));
placeOrderButton2Button().click();
tree2Tree().click(atPath("Composers->Schubert->Location(PLUS_MINUS)"));
tree2Tree().click(atPath("Composers->Schubert->Die schone Mullerin, Op. 25"));
placeOrderButton2Button().click();
//Declare variables for list
ITestDataList nameList;
ITestDataElementList nameListElements;
ITestDataElement nameListElement;
ITestDataList nameList;
ITestDataElementList nameListElements;
ITestDataElement nameListElement;
// Frame: Member Logon
nameComboComboBox().waitForExistence();
nameComboComboBox().waitForExistence();
// Available test data types: {selected=Selected List Element, list=List Elements}
java.util.Hashtable ht = nameComboComboBox().getTestDataTypes();
System.out.println(ht);
java.util.Hashtable ht = nameComboComboBox().getTestDataTypes();
System.out.println(ht);
// Get all elements
nameList = (ITestDataList)nameComboComboBox().getTestData("list");
nameList = (ITestDataList)nameComboComboBox().getTestData("list");
nameListElements = nameList.getElements();
int listElemCount = nameList.getElementCount();
for (int i = 0; i < listElemCount; i++)
{
nameListElement = nameListElements.getElement(i);
System.out.println(nameListElement.getElement());
{
nameListElement = nameListElements.getElement(i);
System.out.println(nameListElement.getElement());
// Click on each element
nameComboComboBox().click();
nameComboComboBox().click(atText(nameListElement.getElement().toString()));
};cancelorderlogonButton().click();
nameComboComboBox().click();
nameComboComboBox().click(atText(nameListElement.getElement().toString()));
};cancelorderlogonButton().click();
// Frame: ClassicsCD
ClassicsJavaFrame(ANY,MAY_EXIT).close();
}}
ClassicsJavaFrame(ANY,MAY_EXIT).close();
}}