2009年10月19日 星期一

Selenium Docs (2) - Remote Control (RC)

Selenium RC 組成
  • Selenium Server:負責打開/關閉瀏覽器、接受並執行指令,就像一個 HTTP proxy。在打開瀏覽器時會在這個瀏覽器中綁上 Selenium-Core, 這個 Selenium-Core 其實就是一堆 JavaScript 函式,幫你把 client 端傳來的指令換成瀏覽器可以執行的 JavaScript 指令。(目前 Selenium Server 是 .jar 檔案,因此要執行它必須有 JVM。)
  • Client libraries:提供一些 API 讓你可以用自己的程式語言與 Server 溝通。目前提供 Java、Python、C#、Ruby、PHP、Perl 等六個語言的 API。

回報結果
Selenium 沒有特別提供這種機制,但可與其它 Test Framework Reporting 工具結合。例如 Java 有 JUnit、TestNG...等。(參考支援的 Testing Frameworks)
題外話:Selenium IDE 有個很不錯的測試環境:Bromine,特別被 Selenium 支援。可以設定 test case 要做什麼事情、在哪些平台上執行、甚至分開到多個 server 同時執行,並且實際執行後回報結果。

在測試程式中執行 JavaScript
getEval(JavaScriptCode) 可以執行一段 JavaScript 程式,並得到它的回傳結果。例如可以用在取得動態網頁元素的 id、或者網頁上的圖片數目(有例子)。另外 JavaScript code 中記得用 window 物件來取得 dom,以免拿到不是測試視窗的內容。

Proxy Injection
由於瀏覽器有「同源策略」(The Same Origin Policy),因此 Selenium-Core 必須與測試網站放在一起才能通過瀏覽器的檢測。但實際上 Selenium 的作法是利用 HTTP proxy 的方式,介於測試網站與瀏覽器之間。瀏覽器設定 localhost:4444 作為 proxy,因此所有 http requests 會通過這個 proxy 傳達,而測試網站的回應也是先丟給這個 proxy 再傳回來。一個 test 大概是這樣初始化的:
  1. 測試程式(client driver)與 Selenium-RC server 建立連線。
  2. Selenium-RC server 開啟瀏覽器並且在 URL 上注入 Selenium-Core 的 JavaScript code。
  3. 測試程式丟一個指令(selenese)給 Selenium-RC server。
  4. Server 解譯這個指令,並且把對應的 JavaScript 指令傳給瀏覽器。
  5. Selenium-Core 指示瀏覽器執行這個操作。(通常第一步是打開某個網頁)
  6. 瀏覽器透過 server (proxy) 請求要這個網頁的內容。
  7. Server 去跟測試網站要內容,拿到之後把它偽裝成跟 Selenium-Core 像是放在同一個 server,這樣就可以通過瀏覽器的同源檢查。
  8. 瀏覽器從 server 那裡拿到內容後,在預設的視窗中呈現出來。


高度特權模式(Heightened Privileges)
它的運作類似 Proxy Injection,但是瀏覽器是以一種特殊模式開啟的,聲稱可以做 XSS (Cross Site Scripting)、自動選檔上傳(一般模式是不行的)之類的事情。而網頁內容也不需要透過 Proxy Server 傳遞,而是瀏覽器直接跟遠端網站要。(因為可以 XSS,所以 Selenium-Core 可以隨意操控?)(感覺很特殊的東西,但沒試過不知道。)

安全連線憑證
對於需要安全驗證(HTTPS)的網站測試,Selenium 在預設的 run mode 中可以處理。當瀏覽器內已經裝了測試網站的安全憑證,一般情況下是不會彈出安全連線的驗證視窗,但是因為執行 Selenium 測試時,並不是真正直接存取那個網站,所以還是會有安全憑證的問題。因此 Selenium RC 的對策是幫你裝一個暫存的安全憑證來騙瀏覽器,所以瀏覽器會覺得是在存取另一個網站而去讀那個安全憑證,來避開這個問題。(不是很確定實際上到底怎麼做到的...)

存取被拒絕(Permission Denied)
測試時最常遇到的情況,原因可能是:(1)違反同源策略;(2)企圖存取不存在的網頁元素。前者通常是用了 third-party application (我自己遇到的),後者會發生在使用 AJAX 的網站,當頁面還沒載完,或者開始 unload 時。這種情況變因太多,通常很難複製(reproduce)問題。

瀏覽器彈出視窗
瀏覽器內建的彈出視窗(popup window)是沒辦法用 Selenium 指令關掉的,因此必須要盡量避免讓他們跳出來,以免測試中斷。這些彈出視窗可以被分為三種型態:
(1) 授權:需要輸入 username/password 的那種,可以透過把 username/password 放在 URL 中解決。像這樣: open("http://myusername:mypassword@myexample.com/blah")
(2) 安全憑證:如同前面所述,通常有安裝過憑證就不會有問題。
(3) JavaScript alert/confirmation/prompt 對話框:正常情況下 Selenium 會自動把這些對話框踢掉,但假如是發生在頁面載入的時候,Selenium 就沒辦法擋。但對於 alert 跟 comfirmation 對話框有指令可以驗證它們存在(e.g., verifyAlertassertConfirmation)。

IE style 屬性
IE 解譯的時候都用大寫,跟人家不一樣,所以在測試多種瀏覽器時,針對 IE 盡量避免用 style 屬性定位某元素。