帮助文件里整理了一下
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();
5.处理未预料的活动窗口
由于浏览器安全等级改变或切换页面造成警告
录制的可能脚本
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();
}
}
}
}
7.使用getTestData方法获取表格单元的值
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();
}
}
8.传递参数给callScript方法
//
没有参数
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();
}}