在測試中,一個更難的問題是模擬用戶交互。因此第三個問題是:我們應該在那里放置斷言(assertion)。 一些測試框架通過在Web瀏覽器中重現用戶交互來測試整個應用程序,這些測試有其適用之處,但他們并不適合在開發時使用。
在一個模擬的JSF環境中,SeamTest可以讓你編寫腳本化(scripted)測試。 這些腳本化測試的用處是為了重現視圖和Seam組件之間的交互,換句話說,你要假裝你是JSF的實現!
這種方法可以測試除了視圖以外的所有事物。
讓我們來看一個JSP視圖,此視圖對應的組件就是上述單元測試過那個組件:
<html>
<head>
<title>Register New User</title>
</head>
<body>
<f:view>
<h:form>
<table border="0">
<tr>
<td>Username</td>
<td><h:inputText value="#{user.username}"/></td>
</tr>
<tr>
<td>Real Name</td>
<td><h:inputText value="#{user.name}"/></td>
</tr>
<tr>
<td>Password</td>
<td><h:inputSecret value="#{user.password}"/></td>
</tr>
</table>
<h:messages/>
<h:commandButton type="submit" value="Register" action="#{register.register}"/>
</h:form>
</f:view>
</body>
</html>
我們想測試一下應用程序的注冊功能(即當用戶點擊注冊按鈕要發生的事情)。我們可以在TestNG的自動測試中重現JSF的請求生命周期:
public class RegisterTest extends SeamTest
{
@Test
public void testRegister() throws Exception
{
new FacesRequest() {
@Override
protected void processValidations() throws Exception
{
validateValue("#{user.username}", "1ovthafew");
validateValue("#{user.name}", "Gavin King");
validateValue("#{user.password}", "secret");
assert !isValidationFailure();
}
@Override
protected void updateModelValues() throws Exception
{
setValue("#{user.username}", "1ovthafew");
setValue("#{user.name}", "Gavin King");
setValue("#{user.password}", "secret");
}
@Override
protected void invokeApplication()
{
assert invokeMethod("#{register.register}").equals("success");
}
@Override
protected void renderResponse()
{
assert getValue("#{user.username}").equals("1ovthafew");
assert getValue("#{user.name}").equals("Gavin King");
assert getValue("#{user.password}").equals("secret");
}
}.run();
}
...
}
值得注意的是:我們繼承了SeamTest,其為我們的組件提供了一個Seam環境,并且我們還需要寫一個繼承了SeamTest.FacesRequest的匿名類,此匿名類模擬JSF的請求生命周期(還有一個SeamTest.NonFacesRequest是測試GET請求的)。 為了模擬JSF對我們組件的調用,我們已經完成了JSF不同階段的方法實現,接著我們還加入了各種斷言。
文章來源于領測軟件測試網 http://www.kjueaiud.com/