您的位置:軟件測試 > 開源軟件測試 > 開源功能測試工具 > Selenium
用Selenium和TestNG做編程式測試
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2013/1/5 13:18:00 ] 推薦標(biāo)簽:

可重復(fù)的驗(yàn)收測試

在執(zhí)行 Selenium 測試時(shí),必須運(yùn)行 Selenium 服務(wù)器以及要檢驗(yàn)的 Web 應(yīng)用程序。言外之意,還必須運(yùn)行應(yīng)用程序中所有相關(guān)的架構(gòu)依賴關(guān)系 —— 對于大多數(shù) Java™ Web 應(yīng)用程序來說,即 Servlet 容器和相關(guān)的數(shù)據(jù)庫。

正如在我的另一篇文章 repeatable system tests 中解釋的一樣,DbUnit 和 Cargo 是兩種我喜歡的技術(shù),可以在依賴數(shù)據(jù)庫的 Web 應(yīng)用程序中實(shí)現(xiàn)邏輯重復(fù)。DbUnit 管理數(shù)據(jù)庫中的數(shù)據(jù),而 Cargo 使容器管理以通用的方式實(shí)現(xiàn)自動(dòng)化。下面幾節(jié)將向您展示如何結(jié)合使用 Selenium 和 TestNG 從而確保實(shí)現(xiàn)邏輯重復(fù)的驗(yàn)收測試。

DbUnit 再次登場

您可能回想起,DbUnit 通過有效地管理測試場景中的數(shù)據(jù)簡化了使用數(shù)據(jù)庫的工作。通過使用 DbUnit,可以在測試前將一組已知的數(shù)據(jù)加載到數(shù)據(jù)庫中,這意味著您可以依賴這些在測試過程中呈現(xiàn)的數(shù)據(jù)。此外,在完成測試后,還可以從數(shù)據(jù)庫中刪除測試結(jié)果產(chǎn)生的數(shù)據(jù)。DbUnit 作為一種方便的 fixture(JUnit 或 TestNG)簡化了所有這些工作,它能夠讀取包含測試數(shù)據(jù)的種子文件,邏輯插入、刪除數(shù)據(jù),或更新數(shù)據(jù)到相應(yīng)的數(shù)據(jù)庫表中。

由于這里使用了 TestNG 驅(qū)動(dòng) Selenium,我將創(chuàng)建一個(gè) DbUnit fixture,它將在測試 級別上運(yùn)行。TestNG 支持在五種粒度級別上運(yùn)行 fixture。低的兩種級別,方法和類是常見的 —— 用于每個(gè)測試方法的 fixture 或者用于整個(gè)類的 fixture。之后,TestNG 為一個(gè)測試集合(定義在 TestNG 配置文件中并由 test 元素指定)定義了一個(gè) fixture,為一組 測試(定義在 TestNG 的 Test 注釋中)定義了一個(gè) fixture。

測試細(xì)節(jié)

創(chuàng)建一個(gè) DbUnit fixture 并在測試級別上運(yùn)行,這意味著運(yùn)行任何測試之前,測試類的集合將共享相同的邏輯,為數(shù)據(jù)庫正確地播種。在本文的示例中,在運(yùn)行每個(gè)邏輯測試集合前,我希望數(shù)據(jù)庫具有一組干凈的數(shù)據(jù)。使用 DbUnit 的 CLEAN_INSERT 命令確保在先前運(yùn)行的測試中創(chuàng)建的行被刪除掉 —— 因此,我可以重新運(yùn)行測試,該測試可以不斷創(chuàng)建數(shù)據(jù)并且不用考慮數(shù)據(jù)庫約束。

此外,我希望 fixture 能夠依賴參數(shù)化數(shù)據(jù),這使我在運(yùn)行某個(gè)測試之前,能夠靈活地切換種子文件,甚至是特定數(shù)據(jù)庫的位置。將 TestNG 與參數(shù)相關(guān)聯(lián)起來再簡單不過了:我所需做的僅僅是使用 Parameters 注釋裝飾 fixtrue,聲明方法簽名中相應(yīng)的參數(shù),并提供 TestNG 配置文件中的值。

清單 8 定義了一個(gè)簡單的 DbUnit fixture,它使用所需的種子文件播種數(shù)據(jù)庫。請注意:該 fixture 被定義為包含五個(gè) 參數(shù)。(這可能非常多,但是在 fixture 中包含參數(shù)不是很好嗎?)

清單 8. 測試集合的 DbUnit fixture

               
public class DatabaseFixture {

 @Parameters({"seed-path","db-driver","db-url","db-user","db-psswrd"})
 @BeforeTest
 public void seedDatabase(String seedpath, String driver,
   String url, String user, String pssword) throws Exception {

  IDatabaseConnection conn = this.getConnection(driver, url, user, pssword);
  IDataSet data = this.getDataSet(seedpath);

  try {
   DatabaseOperation.CLEAN_INSERT.execute(conn, data);
  }finally {
   conn.close();
  }
 }

 private IDataSet getDataSet(String path) throws IOException, DataSetException {
  return new FlatXmlDataSet(new File(path));
 }

 private IDatabaseConnection getConnection(String driver,
   String url, String user, String pssword ) throws ClassNotFoundException,
    SQLException {
  Class.forName(driver);
  Connection jdbcConnection =
    DriverManager.getConnection(url, user, pssword);
  return new DatabaseConnection(jdbcConnection);
 }
}


要將實(shí)際的值與清單 8 中的參數(shù)相關(guān)聯(lián),我必須在 TestNG 的 testng.xml 文件中定義它們,如清單 9 所示:

清單 9. TestNG 的 testng.xml 文件中定義的特定于 DbUnit 的參數(shù)

               
 <parameter name="seed-path" value="test/conf/gt15-seed.xml"/>
 <parameter name="db-driver" value="org.hsqldb.jdbcDriver"/>
 <parameter name="db-url" value="jdbc:hsqldb:hsql://127.0.0.1"/>
 <parameter name="db-user" value="sa"/>
 <parameter name="db-psswrd" value=""/>


通用參數(shù)值

現(xiàn)在我已經(jīng)定義了一個(gè)靈活的 fixture,它將處理數(shù)據(jù)庫狀態(tài)和相應(yīng)測試,F(xiàn)在可以準(zhǔn)備使用 TestNG 將所有內(nèi)容連接起來。通常,第一步是了解希望實(shí)現(xiàn)的內(nèi)容。在本例中,我想完成以下任務(wù):

    我希望在運(yùn)行任何邏輯測試集合前,DbUnit fixture 能夠完成自己任務(wù)。
    我希望將相同的測試集合運(yùn)行兩次:一次用于 Firefox,一次用于 Internet Explorer。

TestNG 的 parameter 元素的作用域是局部的,這對我來說是件好事。這樣,我可以很容易地在 TestNG 配置文件中定義通用參數(shù)值,并且當(dāng)需要時(shí)在 TestNG 的 test 組元素中重寫它們。

比如,要運(yùn)行兩組測試,簡單創(chuàng)建兩個(gè) test 元素。我可以通過 TestNG 的 package 元素將我的 fixture 和相關(guān)測試包括進(jìn)來,package 元素能夠使包結(jié)構(gòu)中所有測試(或 fixture)的查找變得簡單。接著,我可以在兩個(gè)定義了的 test 組中將 Firefox 和 Internet Explorer 的 brwsr-path 參數(shù)關(guān)聯(lián)起來。所有這些都顯示在了 testng.xml 文件中,如清單 10 所示:

清單 10. 使 DbUnit 運(yùn)行的靈活的 testng.xml 文件

               
<suite name="User Acceptance Tests" verbose="1" >
 
 <!-- required for DbUnit fixture   -->
 <parameter name="seed-path" value="test/conf/gt15-seed.xml"/>
 <parameter name="db-driver" value="org.hsqldb.jdbcDriver"/>
 <parameter name="db-url" value="jdbc:hsqldb:hsql://127.0.0.1"/>
 <parameter name="db-user" value="sa"/>
 <parameter name="db-psswrd" value=""/>
 
 <!-- required for Selenium fixture -->
 <parameter name="selen-svr-addr" value="localhost"/>
 <parameter name="aut-addr" value="http://localhost:8080/gt15/"/>  

 <test name="GT15 CRUDs- Firefox" >
 
  <parameter name="brwsr-path" value="*firefox"/>

  <packages>
   <package name="test.com.acme.gt15.Web.selenium" />
   <package name="test.com.acme.gt15.Web.selenium.fixtures" />
  </packages>
 </test>

 <test name="GT15 CRUDs- IE" >
 
  <parameter name="brwsr-path" value="*iexplore"/>

  <packages>
   <package name="test.com.acme.gt15.Web.selenium" />
   <package name="test.com.acme.gt15.Web.selenium.fixtures" />
  </packages>
 </test>
</suite>


我很高興地宣布,我已經(jīng)完成了創(chuàng)建一套可重復(fù)驗(yàn)收測試所需的所有事情。剩下的工具是處理 Web 應(yīng)用程序容器本身。幸運(yùn)地是,我可以使用 Cargo 來完成。

Cargo 執(zhí)行加載

Cargo 是一個(gè)創(chuàng)新的以通用方式自動(dòng)化容器管理的開源項(xiàng)目,比如,用于將 WAR 文件部署到 JBoss 的相同 API 還可以啟動(dòng)和停止 Tomcat。Cargo 還可以自動(dòng)下載并安裝容器 —— Cargo API 的用途很廣泛,從 Java 代碼到 Ant 任務(wù),甚至是 Maven。

諸如 Cargo 這樣的工具將處理編寫邏輯重復(fù)測試用例所面對的一個(gè)大的挑戰(zhàn),它避免一種潛在的假設(shè),即運(yùn)行 的容器具有新好的應(yīng)用程序代碼。此外,還可以構(gòu)造一個(gè)利用 Cargo 的能力自動(dòng)完成以下任務(wù)的編譯過程(例如在 Ant 內(nèi)):

    下載所需的容器。
    安裝該容器。
    啟動(dòng)容器。
    將選擇的 WAR 或 EAR 文件部署到容器上。

稍后,您還可以使 Cargo 停止所選的容器。(并且,不需要對下載和安裝容器發(fā)出警告,或者,如果本地機(jī)器中已經(jīng)存在了正確的版本,Cargo 將跳過步驟 1 和 2。)

我希望使用 Cargo 來確保啟動(dòng)并運(yùn)行新和好的 Web 應(yīng)用程序。并且,我不需要考慮在哪里部署 WAR 文件,或者必須確保正在使用的是新的 WAR 文件。我真正想達(dá)到的目的是使用戶驗(yàn)收測試實(shí)現(xiàn)無事件 —— 我僅需要發(fā)出一個(gè) 命令,然后坐下來等待結(jié)果。甚至可以更好,在一個(gè) CI 環(huán)境中,我不用等待;當(dāng)測試完成后我將獲得一個(gè)通知!

測試容器管理

要在 Ant 內(nèi)設(shè)置 Cargo,我需要定義一個(gè)任務(wù),它將下載特定版本的 Tomcat 并將其安裝到本地機(jī)器上的臨時(shí)目錄。接下來,將新版本的代碼部署到 Tomcat 上,如清單 11 所示:

清單 11. 設(shè)置 Cargo 的任務(wù)

               
<target name="ua-test" depends="compile-tests,war">

 <taskdef resource="cargo.tasks">
  <classpath>
  <pathelement location="${libdir}/${cargo-jar}" />
  <pathelement location="${libdir}/${cargo-ant-jar}" />
  </classpath>
 </taskdef>
 
 <cargo containerId="tomcat5x" action="start" wait="false" id="${tomcat-refid}">
  <zipurlinstaller installurl="${tomcat-installer-url}" />
  <configuration type="standalone" home="${tomcatdir}">
   <property name="cargo.remote.username" value="admin" />
   <property name="cargo.remote.password" value="" />
   <deployable type="war" file="${wardir}/${warfile}" />
  </configuration>
 </cargo>

 <antcall target="_start-selenium" />

 <cargo containerId="tomcat5x" action="stop" refid="${tomcat-refid}" />
</target>


清單 11 中的 target 使用 antcall 調(diào)用另一個(gè) target。實(shí)際上,清單 11 中后的 cargo 任務(wù)封裝了 _start-selenium target,并且確保運(yùn)行測試后停止 Tomcat。

在清單 12 中定義的 _start-selenium target 中,我需要啟動(dòng)(并稍后停止)Selenium 服務(wù)器。在此過程中,我的測試還將連接到其 Selenium fixture 中的服務(wù)器實(shí)例。請注意:該 target 是如何引用另一個(gè) target ——

清單 12. 啟動(dòng)和停止 Selenium 服務(wù)器

               
<target name="_start-selenium">
 <java jar="${libdir}/${selenium-srvr-jar}" fork="true" spawn="true" />
 <antcall target="_run-ua-tests" />
 <get dest="${testreportdir}/results.txt"
        src="${selenium-srvr-loc}/selenium-server/driver/?cmd=shutDown" />
</target>


后,該組中后的 target 將通過 TestNG 實(shí)際運(yùn)行我的編程式 Selenium 測試。注意,我是如何通過使用清單 13 中的 _run-ua-tests target 的 xmlfileset 元素,使 TestNG 使用我的 testng.xml 文件。

清單 13. 運(yùn)行 TestNG testng.xml 文件中的測試

<target name="_run-ua-tests">
 <taskdef classpathref="build.classpath" resource="testngtasks" />
 <testng outputDir="${testreportdir}"
         classpath="${testclassesdir};${classesdir}" haltonfailure="true">
  <xmlfileset dir="./test/conf" includes="testng.xml" />
  <classpath>
   <path refid="build.classpath" />
  </classpath>
 </testng>
</target>

結(jié)束語

正如您看到的一樣,Selenium 極大地簡化了用戶驗(yàn)收測試,尤其當(dāng)使用 TestNG 驅(qū)動(dòng)的時(shí)候。雖然編程式測試并不適用于所有人(非開發(fā)人員可能更喜歡 Selenium 的 Fit 樣式的表),它確實(shí)讓您了解到了 TestNG 非凡的靈活性。編程式測試還允許您使用 DbUnit 和 Cargo 構(gòu)建自己的測試框架,從而確保測試的邏輯可重復(fù)性。

開源 Web 測試框架的發(fā)展絕不會停止,這對于追求代碼質(zhì)量的完美主義者是個(gè)好消息。Selenium 是驅(qū)動(dòng)瀏覽器的開源 Web 測試框架中新出現(xiàn)的工具之一,它能夠使用戶驗(yàn)收測試自動(dòng)化 —— 因此,它非常。結(jié)合使用 Selenium 和 TestNG,正如我在本文中演示的一樣,您將獲得一個(gè)非常好的測試驅(qū)動(dòng),并從依賴性測試以及參數(shù)測試中獲得巨大的優(yōu)勢。嘗試使用 Selenium 和 TestNG 吧,您的用戶將為此感謝您。

上一頁123下一頁
軟件測試工具 | 聯(lián)系我們 | 投訴建議 | 誠聘英才 | 申請使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd