Selenium RC (Selenium 1)

Selenium 的原始版本

簡介

在 WebDriver/Selenium 合併產生更強大的工具 Selenium 2 之前,Selenium RC 長期以來是主要的 Selenium 專案。值得強調的是,Selenium 1 已不再支援。

Selenium RC 的運作方式

首先,我們將描述 Selenium RC 的組件如何運作,以及每個組件在執行您的測試腳本中扮演的角色。

RC 組件

Selenium RC 組件包括

  • Selenium 伺服器,它啟動和關閉瀏覽器、解釋和執行從測試程式傳遞的 Selenese 指令,並充當HTTP proxy,攔截和驗證在瀏覽器和 AUT 之間傳遞的 HTTP 訊息。
  • 客戶端函式庫,提供每種程式語言和 Selenium RC 伺服器之間的介面。

以下是簡化的架構圖

Architecture Diagram Simple

此圖顯示客戶端函式庫與伺服器通信,傳遞每個 Selenium 指令以供執行。然後,伺服器使用 Selenium-Core JavaScript 指令將 Selenium 指令傳遞到瀏覽器。瀏覽器使用其 JavaScript 解譯器執行 Selenium 指令。這會執行您在測試腳本中指定的 Selenese 動作或驗證。

Selenium 伺服器

Selenium 伺服器從您的測試程式接收 Selenium 指令,解釋它們,並向您的程式報告執行這些測試的結果。

RC 伺服器捆綁了 Selenium Core 並自動將其注入到瀏覽器中。當您的測試程式開啟瀏覽器(使用客戶端函式庫 API 函數)時,就會發生這種情況。Selenium-Core 是一個 JavaScript 程式,實際上是一組 JavaScript 函數,它使用瀏覽器的內建 JavaScript 解譯器來解釋和執行 Selenese 指令。

伺服器使用簡單的 HTTP GET/POST 請求從您的測試程式接收 Selenese 指令。這表示您可以使用任何可以發送 HTTP 請求的程式語言來自動化瀏覽器上的 Selenium 測試。

客戶端函式庫

客戶端函式庫提供程式設計支援,讓您可以從您自己設計的程式執行 Selenium 指令。每種支援的語言都有不同的客戶端函式庫。Selenium 客戶端函式庫提供程式設計介面 (API),即一組函數,可從您自己的程式執行 Selenium 指令。在每個介面中,都有一個程式設計函數支援每個 Selenese 指令。

客戶端函式庫接收 Selenese 指令,並將其傳遞給 Selenium 伺服器,以針對受測應用程式 (AUT) 處理特定動作或測試。客戶端函式庫也會接收該指令的結果,並將其傳遞回您的程式。您的程式可以接收結果並將其儲存到程式變數中,並將其報告為成功或失敗,或者在發生意外錯誤時採取更正措施。

因此,要建立測試程式,您只需編寫一個使用客戶端函式庫 API 執行一組 Selenium 指令的程式。而且,如果您已經在 Selenium-IDE 中建立了一個 Selenese 測試腳本,您可以選擇產生 Selenium RC 程式碼。Selenium-IDE 可以將其 Selenium 指令(使用其「匯出」選單項目)轉換為客戶端驅動程式的 API 函數呼叫。有關從 Selenium-IDE 匯出 RC 程式碼的詳細資訊,請參閱 Selenium-IDE 章節。

安裝

對於 Selenium 而言,「安裝」這個詞有點用詞不當。Selenium 擁有一組以您選擇的程式語言提供的函式庫。您可以從下載頁面下載它們。

一旦您選擇了要使用的語言,您只需要

  • 安裝 Selenium RC 伺服器。
  • 使用特定語言的客戶端驅動程式設定程式設計專案。

安裝 Selenium 伺服器

Selenium RC 伺服器只是一個 Java jar 檔案 (selenium-server-standalone-.jar),不需要任何特殊安裝。只需下載 zip 檔案並將伺服器解壓縮到所需的目錄中即可。

執行 Selenium 伺服器

在開始任何測試之前,您必須啟動伺服器。前往 Selenium RC 伺服器所在的目錄,然後從命令列主控台執行以下命令。

    java -jar selenium-server-standalone-<version-number>.jar

這可以簡化,方法是建立一個批次或 shell 可執行檔(Windows 上為 .bat,Linux 上為 .sh),其中包含上述指令。然後在您的桌面上建立該可執行檔的捷徑,只需雙擊圖示即可啟動伺服器。

為了使伺服器能夠執行,您需要安裝 Java,並且 PATH 環境變數已正確設定,以便從主控台執行它。您可以透過在主控台上執行以下命令來檢查您是否已正確安裝 Java。

       java -version

如果您取得版本號碼(需要為 1.5 或更高版本),您就可以開始使用 Selenium RC 了。

使用 Java 客戶端驅動程式

  • 從 SeleniumHQ 下載頁面下載 Selenium java 客戶端驅動程式 zip 檔。
  • 解壓縮 selenium-java-.jar 檔案
  • 開啟您想要的 Java IDE(Eclipse、NetBeans、IntelliJ、Netweaver 等)
  • 建立一個 java 專案。
  • 將 selenium-java-.jar 檔案作為參考新增到您的專案中。
  • 將檔案 selenium-java-.jar 新增到您的專案類別路徑中。
  • 從 Selenium-IDE,將腳本匯出到 Java 檔案並將其包含在您的 Java 專案中,或者使用 selenium-java-client API 在 Java 中編寫您的 Selenium 測試。API 將在本章稍後介紹。您可以使用 JUnit 或 TestNg 來執行您的測試,或者您可以編寫您自己的簡單 main() 程式。這些概念將在本節稍後說明。
  • 從主控台執行 Selenium 伺服器。
  • 從 Java IDE 或從命令列執行您的測試。

有關 Java 測試專案組態的詳細資訊,請參閱附錄章節「使用 Eclipse 組態 Selenium RC」和「使用 Intellij 組態 Selenium RC」。

使用 Python 客戶端驅動程式

  • 透過 PIP 安裝 Selenium,說明連結位於 SeleniumHQ 下載頁面
  • 在 Python 中編寫您的 Selenium 測試,或將腳本從 Selenium-IDE 匯出到 python 檔案。
  • 從主控台執行 Selenium 伺服器
  • 從主控台或您的 Python IDE 執行您的測試

有關 Python 客戶端驅動程式組態的詳細資訊,請參閱附錄「Python 客戶端驅動程式組態」。

使用 .NET 客戶端驅動程式

  • 從 SeleniumHQ 下載頁面下載 Selenium RC
  • 解壓縮資料夾
  • 下載並安裝 NUnit(注意:您可以使用 NUnit 作為您的測試引擎。如果您還不熟悉 NUnit,您也可以編寫一個簡單的 main() 函數來執行您的測試;但是 NUnit 作為測試引擎非常有用。)
  • 開啟您想要的 .Net IDE(Visual Studio、SharpDevelop、MonoDevelop)
  • 建立類別庫 (.dll)
  • 新增對以下 DLL 的參考:nmock.dll、nunit.core.dll、nunit. framework.dll、ThoughtWorks.Selenium.Core.dll、ThoughtWorks.Selenium.IntegrationTests.dll 和 ThoughtWorks.Selenium.UnitTests.dll
  • 以 .Net 語言(C#、VB.Net)編寫您的 Selenium 測試,或將腳本從 Selenium-IDE 匯出到 C# 檔案,並將此程式碼複製到您剛剛建立的類別檔案中。
  • 編寫您自己的簡單 main() 程式,或者您可以在專案中包含 NUnit 以執行您的測試。這些概念將在本章稍後說明。
  • 從主控台執行 Selenium 伺服器
  • 從 IDE、NUnit GUI 或從命令列執行您的測試

有關使用 Visual Studio 進行 .NET 客戶端驅動程式組態的具體詳細資訊,請參閱附錄「.NET 客戶端驅動程式組態」。

使用 Ruby 客戶端驅動程式

  • 如果您還沒有 RubyGems,請從 RubyForge 安裝它。
  • 執行 gem install selenium-client
  • 在您的測試腳本頂部,新增 require "selenium/client"
  • 使用任何 Ruby 測試框架(例如 Test::Unit、Mini::Test 或 RSpec)編寫您的測試腳本。
  • 從主控台執行 Selenium RC 伺服器。
  • 以您執行任何其他 Ruby 腳本的相同方式執行您的測試。

有關 Ruby 客戶端驅動程式組態的詳細資訊,請參閱 Selenium-Client documentation_

從 Selenese 到程式

使用 Selenium RC 的主要任務是將您的 Selenese 轉換為程式語言。在本節中,我們提供幾個不同的特定語言範例。

範例測試腳本

讓我們從一個範例 Selenese 測試腳本開始。想像一下使用 Selenium-IDE 錄製以下測試。

open/
typeqselenium rc
clickAndWaitbtnG
assertTextPresentResults * for selenium rc

注意:此範例適用於 Google 搜尋頁面 http://www.google.com

Selenese 作為程式碼

以下是(透過 Selenium-IDE)匯出到每種支援的程式語言的測試腳本。如果您至少具備物件導向程式語言的基本知識,您將透過閱讀這些範例來了解 Selenium 如何執行 Selenese 指令。若要查看特定語言的範例,請選取以下按鈕之一。

CSharp


        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }

Java

      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }

Php

      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>

Python


     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)

Ruby


      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end

在下一節中,我們將說明如何使用產生的程式碼來建置測試程式。

編寫您的測試程式

現在,我們將說明如何使用每種支援的程式語言的範例來編寫您自己的測試程式。基本上有兩個任務

  • 從 Selenium-IDE 將您的腳本產生為程式語言,並選擇性地修改結果。
  • 編寫一個非常簡單的 main 程式來執行產生的程式碼。

或者,如果您正在使用 Java 或 .NET 等語言,您可以採用 JUnit 或 TestNG 等 Java 測試引擎平台,或 .NET 的 NUnit。

在這裡,我們展示特定語言的範例。特定語言的 API 往往彼此不同,因此您會找到針對每種語言的個別說明。

  • Java
  • C#
  • Python
  • Ruby
  • Perl, PHP

Java

對於 Java,人們使用 JUnit 或 TestNG 作為測試引擎。
某些開發環境(例如 Eclipse)透過外掛程式直接支援這些引擎。這讓事情變得更容易。教導 JUnit 或 TestNG 超出了本文檔的範圍,但是可以在網路上找到相關資料,並且也有出版品可供參考。如果您已經是「java-shop」,您的開發人員很可能已經具備其中一種測試框架的經驗。

您可能需要將測試類別從「NewTest」重新命名為您自己選擇的名稱。此外,您需要變更陳述式中的瀏覽器開啟參數

    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");

Selenium-IDE 產生的程式碼如下所示。此範例已手動新增註解以提高清晰度。

   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }

C#

.NET 客戶端驅動程式適用於 Microsoft.NET。它可以與任何 .NET 測試框架搭配使用,例如 NUnit 或 Visual Studio 2005 Team System。

Selenium-IDE 假設您將使用 NUnit 作為您的測試框架。您可以在以下產生的程式碼中看到這一點。它包含 NUnit 的 using 陳述式以及對應的 NUnit 屬性,用於識別測試類別的每個成員函數的角色。

您可能必須將測試類別從「NewTest」重新命名為您自己選擇的名稱。此外,您需要變更陳述式中的瀏覽器開啟參數

    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");

產生的程式碼看起來會類似於這樣。


    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }

您可以允許 NUnit 管理您的測試執行。或者,您可以編寫一個簡單的 main() 程式,該程式會實例化測試物件並依序執行 SetupTest()TheNewTest()TeardownTest() 這三個方法。

Python

Pyunit 是用於 Python 的測試框架。

基本測試結構是


   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found

Ruby

舊版 (2.0 之前) 的 Selenium-IDE 產生的 Ruby 程式碼需要舊的 Selenium gem。因此,建議更新 IDE 產生的任何 Ruby 腳本,如下所示

  1. 在第 1 行,將 require "selenium" 變更為 require "selenium/client"

  2. 在第 11 行,將 Selenium::SeleniumDriver.new 變更為 Selenium::Client::Driver.new

您可能還需要將類別名稱變更為比「Untitled」更具資訊性的名稱,並將測試方法名稱變更為「test_untitled」以外的名稱。

以下是透過修改 Selenium IDE 產生的 Ruby 程式碼(如上所述)建立的簡單範例。


   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end

Perl, PHP

文件團隊的成員尚未使用 Perl 或 PHP 搭配 Selenium RC。如果您正在使用 Perl 或 PHP 搭配 Selenium RC,請聯絡文件團隊(請參閱關於貢獻的章節)。我們很樂意收錄您的一些範例和經驗,以支援 Perl 和 PHP 使用者。

學習 API

Selenium RC API 使用命名慣例,假設您了解 Selenese,則大部分介面
將是不言自明的。但是,在這裡我們說明最關鍵且可能不太明顯的方面。

啟動瀏覽器

CSharp

      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();

Java


      setUp("http://www.google.com/", "*firefox");

Perl

      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );

Php

      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");

Python

      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()

Ruby

      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start

這些範例中的每一個都會開啟瀏覽器,並透過將「瀏覽器實例」指派給程式變數來表示該瀏覽器。然後,此程式變數用於從瀏覽器呼叫方法。這些方法執行 Selenium 指令,例如 opentypeverify 指令。

建立瀏覽器實例時所需的參數為

  • host 指定伺服器所在的電腦的 IP 位址。通常,這與執行客戶端的電腦是同一部機器,因此在這種情況下,會傳遞 localhost。在某些客戶端中,這是一個可選參數。

  • port 指定伺服器正在監聽等待客戶端建立連線的 TCP/IP Socket。在某些客戶端驅動程式中,這也是可選的。

  • browser 您要在其中執行測試的瀏覽器。這是一個必要參數。

  • url 受測應用程式的基本 URL。這是所有客戶端函式庫都需要的,並且是啟動瀏覽器-Proxy-AUT 通訊的必要資訊。

請注意,某些客戶端函式庫需要透過呼叫其 start() 方法來明確啟動瀏覽器。

執行指令

一旦您初始化瀏覽器並將其指派給變數(通常命名為「selenium」),您就可以透過從瀏覽器變數呼叫各自的方法,使其執行 Selenese 指令。例如,呼叫 selenium 物件的 type 方法

    selenium.type("field-id","string to type")

在背景中,瀏覽器實際上將執行 type 操作,這基本上與使用者在瀏覽器中輸入輸入相同,透過
使用您在方法呼叫期間指定的定位器和字串。

報告結果

Selenium RC 沒有自己的報告結果機制。相反地,它允許您使用您選擇的程式語言的功能來建置針對您的需求自訂的報告。這很棒,但是如果您只是想要一些快速且已完成的事情呢?通常,現有的函式庫或測試框架可以比開發您自己的測試報告程式碼更快地滿足您的需求。

測試框架報告工具

測試框架適用於許多程式語言。這些框架除了提供彈性的測試引擎來執行您的測試的主要功能外,還包括用於報告結果的函式庫程式碼。例如,Java 有兩個常用的測試框架,JUnit 和 TestNG。.NET 也有自己的框架 NUnit。

我們不會在這裡教導框架本身;這超出了本使用者指南的範圍。我們將只介紹與 Selenium 相關的框架功能以及您可以應用的一些技術。但是,有關於這些測試框架的優秀書籍,以及網際網路上的資訊。

測試報告函式庫

還有專門為以您選擇的程式語言報告測試結果而建立的第三方函式庫。這些函式庫通常支援各種格式,例如 HTML 或 PDF。

最佳方法是什麼?

大多數剛接觸測試框架的人員將從框架的內建報告功能開始。從那裡,大多數人將檢查任何可用的函式庫,因為這比開發自己的函式庫更省時。當您開始使用 Selenium 時,無疑地您將開始放入您自己的「print 陳述式」以報告進度。這可能會逐漸引導您開發自己的報告,可能與使用函式庫或測試框架並行。無論如何,在最初但短暫的學習曲線之後,您自然會開發出最適合您自身情況的方法。

測試報告範例

為了說明,我們將引導您了解 Selenium 支援的其他語言中的一些特定工具。此處列出的工具是常用的,並且已由本指南的作者廣泛使用(因此推薦)。

Java 中的測試報告

  • 如果 Selenium 測試案例是使用 JUnit 開發的,則可以使用 JUnit Report 來產生測試報告。

  • 如果 Selenium 測試案例是使用 TestNG 開發的,則無需執行外部任務即可產生測試報告。TestNG 框架會產生 HTML 報告,其中列出測試的詳細資訊。

  • ReportNG 是 TestNG 框架的 HTML 報告外掛程式。它旨在取代預設的 TestNG HTML 報告。ReportNG 提供測試結果的簡單、顏色編碼檢視。

記錄 Selenese 指令
  • 記錄 Selenium 可用於產生測試中所有 Selenese 指令的報告,以及每個指令的成功或失敗狀態。記錄 Selenium 擴充了 Java 客戶端驅動程式,以新增此 Selenese 記錄功能。

Python 的測試報告

  • 當使用 Python 客戶端驅動程式時,可以使用 HTMLTestRunner 來產生測試報告。

Ruby 的測試報告

  • 如果 RSpec 框架用於在 Ruby 中編寫 Selenium 測試案例,則可以使用其 HTML 報告來產生測試報告。

為您的測試增添趣味

現在我們將討論使用 Selenium RC 的整個原因,即將程式設計邏輯新增到您的測試中。這與任何程式相同。程式流程是使用條件陳述式和迭代來控制的。此外,您可以使用 I/O 報告進度資訊。在本節中,我們將展示一些範例,說明如何將程式語言建構與 Selenium 結合使用,以解決常見的測試問題。

您會發現,當您從頁面元素存在的簡單測試過渡到涉及多個網頁和不同資料的動態功能測試時,您將需要程式設計邏輯來驗證預期的結果。基本上,Selenium-IDE 不支援迭代和標準條件陳述式。您可以透過在 Selenese 參數中嵌入 JavaScript 來執行一些條件,但是迭代是不可能的,而且大多數條件在
程式語言中會更容易。此外,您可能需要異常處理來進行錯誤恢復。由於這些原因和其他原因,我們撰寫了本節,以說明如何使用常見的程式設計技術,以便在您的自動化測試中提供更大的「驗證能力」。

本節中的範例以 C# 和 Java 編寫,儘管程式碼很簡單,並且可以輕鬆地改編為其他支援的語言。如果您具備物件導向程式語言的一些基本知識,您應該可以輕鬆理解本節。

迭代

迭代是人們在測試中最常需要做的事情之一。例如,您可能想要多次執行搜尋。或者,也許為了驗證您的測試結果,您需要處理從資料庫傳回的「結果集」。

使用我們稍早使用的相同 Google 搜尋範例,讓我們檢查 Selenium 搜尋結果。此測試可以使用 Selenese

open/
typeqselenium rc
clickAndWaitbtnG
assertTextPresentResults * for selenium rc
typeqselenium ide
clickAndWaitbtnG
assertTextPresentResults * for selenium ide
typeqselenium grid
clickAndWaitbtnG
assertTextPresentResults * for selenium grid

程式碼已重複執行相同的步驟 3 次。但是,多個相同程式碼的副本並不是良好的程式設計實務,因為維護起來更費力。透過使用程式語言,我們可以迭代搜尋結果,以獲得更彈性且可維護的解決方案。

C#

   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }

條件陳述式

為了說明如何在測試中使用條件,我們將從一個範例開始。執行 Selenium 測試時遇到的常見問題是,預期的元素在頁面上不可用。例如,當執行以下行時

   selenium.type("q", "selenium " +s);

如果元素 'q' 不在頁面上,則會擲回例外

   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found

這可能會導致您的測試中止。對於某些測試來說,這是您想要的。但是,通常這是不理想的,因為您的測試腳本還有許多其他後續測試要執行。

更好的方法是先驗證元素是否真的存在,然後在不存在時採取替代方案。讓我們使用 Java 來看看這個。

   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }

這種方法的優點是即使某些 UI 元素在頁面上不可用,也可以繼續執行測試。

從您的測試執行 JavaScript

JavaScript 在執行 Selenium 不直接支援的應用程式時非常方便。Selenium API 的 getEval 方法可用於從 Selenium RC 執行 JavaScript。

考量一個應用程式,其中包含沒有靜態識別碼的核取方塊。在這種情況下,可以從 Selenium RC 評估 JavaScript,以取得所有核取方塊的 ID,然後操作它們。

   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }

若要計算頁面上的影像數量

   selenium.getEval("window.document.images.length;");

請記住在使用 DOM 運算式時使用 window 物件,因為預設情況下,selenium 視窗是指測試視窗,而不是測試視窗。

伺服器選項

當伺服器啟動時,可以使用命令列選項來變更預設伺服器行為。

回想一下,伺服器是透過執行以下命令啟動的。

   $ java -jar selenium-server-standalone-<version-number>.jar

若要查看選項清單,請使用 -h 選項執行伺服器。

   $ java -jar selenium-server-standalone-<version-number>.jar -h

您將看到您可以與伺服器一起使用的所有選項的清單,以及每個選項的簡短說明。提供的說明並不總是足夠的,因此我們為一些更重要的選項提供了說明。

Proxy 組態

如果您的 AUT 位於需要驗證的 HTTP Proxy 後面,則您應該使用以下指令組態 http.proxyHost、http.proxyPort、http.proxyUser 和 http.proxyPassword。

   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password

多視窗模式

如果您使用的是 Selenium 1.0,您可以跳過本節,因為多視窗模式是預設行為。但是,在 1.0 版之前,Selenium 預設會在子框架中執行受測應用程式,如下所示。

Single window mode

某些應用程式在子框架中無法正確執行,並且需要載入到視窗的頂層框架中。多視窗模式選項允許 AUT 在單獨的視窗中執行,而不是在預設框架中執行,這樣它就可以擁有所需的頂層框架。

Multiwindow Mode

對於舊版本的 Selenium,您必須使用以下選項明確指定多視窗模式

   -multiwindow 

從 Selenium RC 1.0 開始,如果您想要在單一框架內執行測試(即使用早期 Selenium 版本的標準),您可以使用選項向 Selenium 伺服器說明這一點

   -singlewindow 

指定 Firefox 設定檔

除非您為每個實例指定單獨的設定檔,否則 Firefox 不會同時執行兩個實例。Selenium RC 1.0 及更高版本會自動在單獨的設定檔中執行,因此如果您使用的是 Selenium 1.0,您可以跳過本節。但是,如果您使用的是舊版本的 Selenium,或者您需要為您的測試使用特定的設定檔(例如新增 https 憑證或安裝某些附加元件),您將需要明確指定設定檔。

首先,若要建立單獨的 Firefox 設定檔,請依照以下步驟操作。開啟 Windows「開始」選單,選取「執行」,然後輸入並輸入以下其中一項

   firefox.exe -profilemanager 
   firefox.exe -P 

使用對話方塊建立新的設定檔。然後,當您執行 Selenium 伺服器時,請告知它使用這個新的 Firefox 設定檔,並使用伺服器命令列選項 -firefoxProfileTemplate 並使用其檔案名稱和目錄路徑指定設定檔的路徑。

   -firefoxProfileTemplate "path to the profile" 

警告:務必將您的設定檔放在與預設資料夾分開的新資料夾中!如果您刪除設定檔,Firefox 設定檔管理員工具將刪除資料夾中的所有檔案,無論它們是否為設定檔。

有關 Firefox 設定檔的更多資訊,請參閱 Mozilla 知識庫

使用 -htmlSuite 在伺服器中直接執行 Selenese

您可以透過將 html 檔案傳遞到伺服器的命令列,直接在 Selenium 伺服器中執行 Selenese html 檔案。例如

   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"

這將自動啟動您的 HTML 套件,執行所有測試並儲存包含結果的精美 HTML 報告。

注意: 當使用此選項時,伺服器將啟動測試並等待指定的秒數以完成測試;如果測試未在該時間量內完成,則命令將以非零結束代碼結束,並且不會產生結果檔案。

這個命令列非常長,因此在輸入時請務必小心。請注意,這需要您傳入 HTML Selenese 套件,而不是單個測試。另請注意,-htmlSuite 選項與 -interactive 不相容。您不能同時執行兩者。

Selenium 伺服器記錄

伺服器端日誌

啟動 Selenium 伺服器時,可以使用 -log 選項來記錄 Selenium 伺服器回報的有價值偵錯資訊到文字檔。

   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log

此日誌檔比標準主控台日誌更詳細(它包含 DEBUG 層級的日誌訊息)。日誌檔還包括記錄器名稱和記錄訊息的執行緒 ID 編號。例如

   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW

訊息格式為

   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE

此訊息可能是多行的。

瀏覽器端日誌

瀏覽器端 (Selenium Core) 的 JavaScript 也會記錄重要訊息;在許多情況下,這些訊息對終端使用者而言可能比常規 Selenium 伺服器日誌更有用。若要存取瀏覽器端日誌,請將 -browserSideLog 引數傳遞給 Selenium 伺服器。

   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog

-browserSideLog 必須與 -log 引數結合使用,才能將 browserSideLogs(以及所有其他 DEBUG 層級的日誌訊息)記錄到檔案。

指定特定瀏覽器的路徑

您可以為 Selenium RC 指定特定瀏覽器的路徑。如果您有多個相同瀏覽器的版本,並且希望使用特定版本,這會很有用。此外,這也用於允許您的測試針對 Selenium RC 未直接支援的瀏覽器執行。在指定執行模式時,請使用 *custom 指定符,後跟瀏覽器可執行檔的完整路徑

   *custom <path to browser> 

Selenium RC 架構

注意: 本主題試圖解釋 Selenium RC 背後的技術實作。Selenium 使用者不一定要了解這一點,但對於理解您未來可能遇到的一些問題可能會有所幫助。

若要詳細了解 Selenium RC Server 的運作方式以及為何它使用代理注入和提升權限模式,您必須先了解 同源政策_。

同源策略

Selenium 面臨的主要限制是同源政策。此安全限制由市場上的每個瀏覽器應用,其目的是確保網站的內容永遠不會被來自另一個網站的腳本存取。同源政策規定,瀏覽器中載入的任何程式碼都只能在該網站的網域內運作。它無法對另一個網站執行功能。因此,舉例來說,如果瀏覽器在載入 www.mysite.com 時載入 JavaScript 程式碼,則無法針對 www.mysite2.com 執行該載入的程式碼,即使那是您的另一個網站。如果這樣是可行的,那麼放置在您開啟的任何網站上的腳本將能夠讀取您銀行帳戶的資訊(如果您在另一個分頁中開啟了帳戶頁面)。這稱為 XSS(跨網站腳本攻擊)。

為了在此政策範圍內運作,Selenium-Core(及其執行所有神奇操作的 JavaScript 命令)必須與受測應用程式 (Application Under Test, AUT) 處於相同的來源(相同的 URL)。

從歷史上看,Selenium-Core 受限於這個問題,因為它是用 JavaScript 實作的。但是,Selenium RC 不受同源政策的限制。它使用 Selenium Server 作為代理來避免這個問題。從本質上講,它告訴瀏覽器,瀏覽器正在單一「欺騙」網站上工作,而該網站是由伺服器提供的。

注意: 您可以在 Wikipedia 上找到有關同源政策和 XSS 的更多資訊。

Proxy 注入

Selenium 用於避免同源政策的第一種方法是代理注入。在代理注入模式下,Selenium Server 充當用戶端設定的 HTTP 代理伺服器1,它位於瀏覽器和受測應用程式2 之間。然後,它將 AUT 遮罩在虛構的 URL 下(嵌入 Selenium-Core 和測試套件,並將它們傳遞為好像它們來自相同的來源)。

以下是架構圖。

Architectural Diagram 1

當測試套件以您喜愛的語言啟動時,會發生以下情況

  1. 用戶端/驅動程式與 selenium-RC 伺服器建立連線。
  2. Selenium RC 伺服器啟動瀏覽器(或重複使用舊的瀏覽器),並使用將 Selenium-Core 的 JavaScript 注入到瀏覽器載入的網頁中的 URL。
  3. 用戶端驅動程式將 Selenese 命令傳遞給伺服器。
  4. 伺服器解釋該命令,然後觸發對應的 JavaScript 執行,以在瀏覽器內執行該命令。Selenium-Core 指示瀏覽器對第一個指令採取動作,通常是開啟 AUT 的頁面。
  5. 瀏覽器收到開啟請求,並從 Selenium RC 伺服器(設定為瀏覽器要使用的 HTTP 代理伺服器)請求網站的內容。
  6. Selenium RC 伺服器與 Web 伺服器通訊,請求頁面,一旦收到頁面,它就會將頁面傳送給瀏覽器,並遮罩來源,使其看起來像是頁面來自與 Selenium-Core 相同的伺服器(這允許 Selenium-Core 遵守同源政策)。
  7. 瀏覽器接收網頁,並將其呈現在為其保留的框架/視窗中。

提高權限的瀏覽器

此方法中的工作流程與代理注入非常相似,但主要區別在於瀏覽器是以稱為提升權限的特殊模式啟動的,這允許網站執行通常不允許執行的操作(例如執行 XSS_,或填寫檔案上傳輸入,以及對 Selenium 非常有用的東西)。透過使用這些瀏覽器模式,Selenium Core 能夠直接開啟 AUT 並讀取/與其內容互動,而無需將整個 AUT 傳遞到 Selenium RC 伺服器。

以下是架構圖。

Architectural Diagram 1

當測試套件以您喜愛的語言啟動時,會發生以下情況

  1. 用戶端/驅動程式與 selenium-RC 伺服器建立連線。
  2. Selenium RC 伺服器啟動瀏覽器(或重複使用舊的瀏覽器),並使用將在網頁中載入 Selenium-Core 的 URL。
  3. Selenium-Core 從用戶端/驅動程式接收第一個指令(透過另一個對 Selenium RC Server 發出的 HTTP 請求)。
  4. Selenium-Core 對第一個指令採取動作,通常是開啟 AUT 的頁面。
  5. 瀏覽器接收開啟請求,並向 Web 伺服器請求頁面。一旦瀏覽器收到網頁,就會將其呈現在為其保留的框架/視窗中。

處理 HTTPS 和安全性彈出視窗

許多應用程式在需要傳送加密資訊(例如密碼或信用卡資訊)時,會從使用 HTTP 切換到 HTTPS。這在當今的許多 Web 應用程式中很常見。Selenium RC 支援此功能。

為了確保 HTTPS 網站是真實的,瀏覽器將需要安全憑證。否則,當瀏覽器使用 HTTPS 存取 AUT 時,它會假設應用程式不受「信任」。當這種情況發生時,瀏覽器會顯示安全快顯視窗,而這些快顯視窗無法使用 Selenium RC 關閉。

在 Selenium RC 測試中處理 HTTPS 時,您必須使用支援此功能並為您處理安全憑證的執行模式。當您的測試程式初始化 Selenium 時,您會指定執行模式。

在 Selenium RC 1.0 beta 2 及更高版本中,執行模式請使用 *firefox 或 *iexplore。在較早的版本中,包括 Selenium RC 1.0 beta 1,執行模式請使用 *chrome 或 *iehta。使用這些執行模式,您將不需要安裝任何特殊的安全憑證;Selenium RC 會為您處理。

在版本 1.0 中,建議使用執行模式 *firefox 或 *iexplore。但是,還有額外的執行模式 *iexploreproxy 和 *firefoxproxy。這些僅為了向後相容性而提供,除非舊版測試程式需要,否則不應使用。如果您的應用程式開啟其他瀏覽器視窗,使用它們將會對安全憑證處理和執行多個視窗造成限制。

在較早版本的 Selenium RC 中,*chrome 或 *iehta 是支援 HTTPS 和處理安全快顯視窗的執行模式。這些被認為是「實驗性模式」,儘管它們變得非常穩定,並且許多人使用它們。如果您使用的是 Selenium 1.0,則不需要也不應使用這些較舊的執行模式。

安全性憑證說明

通常,您的瀏覽器會透過安裝您已擁有的安全憑證來信任您正在測試的應用程式。您可以在瀏覽器的選項或網際網路屬性中檢查這一點(如果您不知道 AUT 的安全憑證,請詢問您的系統管理員)。當 Selenium 載入您的瀏覽器時,它會注入程式碼來攔截瀏覽器和伺服器之間的訊息。瀏覽器現在認為不受信任的軟體正試圖看起來像您的應用程式。它會透過快顯訊息來警告您。

為了規避這個問題,Selenium RC(再次強調,當使用支援此功能的執行模式時)會暫時將其自己的安全憑證安裝到您的用戶端機器上,放在瀏覽器可以存取的位置。這會欺騙瀏覽器,使其認為它正在存取與您的 AUT 不同的網站,並有效地抑制快顯視窗。

早期版本的 Selenium 使用的另一種方法是安裝 Selenium 安裝隨附的 Cybervillians 安全憑證。但是,大多數使用者不再需要這樣做;如果您在代理注入模式下執行 Selenium RC,您可能需要明確安裝此安全憑證。

支援其他瀏覽器和瀏覽器組態

除了 Internet Explorer 和 Mozilla Firefox 之外,Selenium API 還支援針對多個瀏覽器執行。請參閱 https://selenium.dev.org.tw 網站以了解受支援的瀏覽器。此外,當瀏覽器未直接受支援時,您仍然可以使用「*custom」執行模式(即取代 *firefox 或 *iexplore)針對您選擇的瀏覽器執行 Selenium 測試,當您的測試應用程式啟動瀏覽器時。透過這種方式,您可以將瀏覽器可執行檔的路徑傳遞到 API 呼叫中。這也可以從伺服器在互動模式下完成。

   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com

使用不同的瀏覽器組態執行測試

通常 Selenium RC 會自動設定瀏覽器,但是如果您使用「*custom」執行模式啟動瀏覽器,您可以強制 Selenium RC 以原樣啟動瀏覽器,而不使用自動設定。

例如,您可以像這樣使用自訂設定啟動 Firefox

   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com

請注意,以此方式啟動瀏覽器時,您必須手動設定瀏覽器以使用 Selenium Server 作為代理伺服器。通常,這僅表示開啟您的瀏覽器偏好設定,並將「localhost:4444」指定為 HTTP 代理伺服器,但是針對不同瀏覽器的說明可能會差異很大。請查閱瀏覽器的文件以了解詳細資訊。

請注意,Mozilla 瀏覽器在啟動和停止方面可能會有所不同。可能需要設定 MOZ_NO_REMOTE 環境變數,以使 Mozilla 瀏覽器的行為更可預測一些。Unix 使用者應避免使用 shell 腳本啟動瀏覽器;通常最好直接使用二進位可執行檔(例如 firefox-bin)。

疑難排解常見問題

剛開始使用 Selenium RC 時,會遇到一些常見的潛在問題。我們在此處介紹這些問題及其解決方案。

無法連線到伺服器

當您的測試程式無法連線到 Selenium Server 時,Selenium 會在您的測試程式中擲回例外狀況。它應該顯示此訊息或類似訊息

    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 

如果您看到類似這樣的訊息,請確保您已啟動 Selenium Server。如果已啟動,則表示 Selenium 用戶端程式庫與 Selenium Server 之間的連線存在問題。

剛開始使用 Selenium RC 時,大多數人從在同一部機器上執行其測試程式(使用 Selenium 用戶端程式庫)和 Selenium Server 開始。若要執行此操作,請使用「localhost」作為您的連線參數。我們建議從這種方式開始,因為它可以減少潛在網路問題的影響,而您正在開始。假設您的作業系統具有典型的網路和 TCP/IP 設定,您應該不會遇到太多困難。事實上,許多人選擇以這種方式執行測試。

但是,如果您確實想要在遠端機器上執行 Selenium Server,則假設您在兩部機器之間具有有效的 TCP/IP 連線,則連線應該沒有問題。

如果您在連線時遇到困難,可以使用常見的網路工具,例如 pingtelnetifconfig(Unix)/ipconfig (Windows) 等,以確保您具有有效的網路連線。如果您不熟悉這些工具,您的系統管理員可以協助您。

無法載入瀏覽器

好的,錯誤訊息不太友善,抱歉,但是如果 Selenium Server 無法載入瀏覽器,您可能會看到此錯誤。

    (500) Internal Server Error

這可能是由以下原因造成的

  • Firefox(在 Selenium 1.0 之前)無法啟動,因為瀏覽器已開啟,並且您未指定單獨的設定檔。請參閱伺服器選項下的 Firefox 設定檔章節。
  • 您正在使用的執行模式與您機器上的任何瀏覽器都不符。請檢查當您的程式開啟瀏覽器時,您傳遞給 Selenium 的參數。
  • 您明確指定了瀏覽器的路徑(使用「*custom」—請參閱上方),但是路徑不正確。請檢查以確保路徑正確。另請檢查使用者群組,以確保您的瀏覽器和「*custom」參數沒有已知的問題。

Selenium 找不到 AUT

如果您的測試程式成功啟動瀏覽器,但是瀏覽器未顯示您正在測試的網站,則最可能的原因是您的測試程式未使用正確的 URL。

這很容易發生。當您使用 Selenium-IDE 匯出您的腳本時,它會插入一個虛擬 URL。您必須手動將 URL 變更為要測試的應用程式的正確 URL。

Firefox 拒絕在準備設定檔時關閉

當您針對 Firefox 執行 Selenium RC 測試程式時,最常發生這種情況,但是您已經有一個 Firefox 瀏覽器工作階段正在執行,並且在啟動 Selenium Server 時,您未指定單獨的設定檔。來自測試程式的錯誤看起來像這樣

    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 

以下是來自伺服器的完整錯誤訊息

    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 

若要解決此問題,請參閱指定單獨的 Firefox 設定檔章節

版本問題

請確保您的 Selenium 版本支援您的瀏覽器版本。例如,Selenium RC 0.92 不支援 Firefox 3。有時您可能會很幸運(我就是)。但是,請不要忘記檢查您正在使用的 Selenium 版本支援哪些瀏覽器版本。如有疑問,請將最新發行版本的 Selenium 與最廣泛使用的瀏覽器版本一起使用。

錯誤訊息:「(Unsupported major.minor version 49.0)」在啟動伺服器時

此錯誤表示您沒有使用正確的 Java 版本。Selenium Server 需要 Java 1.5 或更高版本。

若要再次檢查您的 Java 版本,請從命令列執行此操作。

   java -version

您應該會看到顯示 Java 版本的訊息。

   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)

如果您看到較低的版號,您可能需要更新 JRE,或者您可能只需要將其新增到您的 PATH 環境變數中。

執行 getNewBrowserSession 指令時出現 404 錯誤

如果您在嘗試開啟「http://www.google.com/selenium-server/"」上的頁面時收到 404 錯誤,則必定是因為 Selenium Server 未正確設定為代理伺服器。「selenium-server」目錄在 google.com 上不存在;只有在正確設定代理伺服器時才會出現。代理伺服器設定高度取決於瀏覽器是如何使用 firefox、iexplore、opera 或 custom 啟動的。

  • iexplore:如果瀏覽器是使用 *iexplore 啟動的,則您可能遇到 Internet Explorer 的代理伺服器設定問題。Selenium Server 嘗試設定網際網路選項控制面板中的全域代理伺服器設定。您必須確保在 Selenium Server 啟動瀏覽器時,這些設定已正確設定。嘗試查看您的網際網路選項控制面板。按一下「連線」索引標籤,然後按一下「區域網路設定」。

    • 如果您需要使用代理伺服器來存取您要測試的應用程式,則需要使用「-Dhttp.proxyHost」啟動 Selenium Server;請參閱 代理伺服器設定_ 以了解更多詳細資訊。
    • 您也可以嘗試手動設定您的代理伺服器,然後使用 *custom 或 *iehta 瀏覽器啟動器啟動瀏覽器。
  • custom:當使用 *custom 時,您必須正確(手動)設定代理伺服器,否則您將收到 404 錯誤。再次檢查您是否已正確設定您的代理伺服器設定。檢查您是否已正確設定代理伺服器的一種方法是嘗試故意不正確地設定瀏覽器。嘗試將瀏覽器設定為使用錯誤的代理伺服器主機名稱或錯誤的連接埠。如果您已成功不正確地設定瀏覽器的代理伺服器設定,則瀏覽器將無法連線到網際網路,這是確保調整相關設定的一種方法。

  • 對於其他瀏覽器(*firefox、*opera),我們會自動為您硬式編碼代理伺服器,因此此功能沒有已知的問題。如果您遇到 404 錯誤並且已仔細遵循本使用者指南,請將您的結果發佈到使用者群組,以尋求使用者社群的一些協助。

權限遭拒錯誤

此錯誤最常見的原因是您的工作階段正嘗試透過跨網域邊界(例如,存取來自 http://domain1 的頁面,然後存取來自 http://domain2 的頁面)或切換協定(從 http://domainX 移至 https://domainX)來違反同源政策。

當 JavaScript 嘗試尋找尚未可用的 UI 物件(在頁面完全載入之前)或不再可用的 UI 物件(在頁面開始卸載之後)時,也可能發生此錯誤。這最常發生在使用 AJAX 頁面的情況下,這些頁面正在處理頁面的區段或子框架,這些區段或子框架會獨立於較大的頁面載入和/或重新載入。

此錯誤可能是間歇性的。通常,由於問題源於當將偵錯器的額外負荷新增到系統時無法重現的競爭條件,因此無法使用偵錯器重現該問題。教學課程中詳細介紹了權限問題。請仔細閱讀有關 同源政策_、代理注入_ 的章節。

處理瀏覽器彈出視窗

在 Selenium 測試期間,您可能會收到幾種「快顯視窗」。如果這些快顯視窗是由瀏覽器而不是您的 AUT 啟動的,您可能無法透過執行 Selenium 命令來關閉這些快顯視窗。您可能需要知道如何管理這些快顯視窗。每種類型的快顯視窗都需要以不同的方式處理。

  • HTTP 基本身分驗證對話方塊:這些對話方塊會提示輸入使用者名稱/密碼以登入網站。若要登入需要 HTTP 基本身分驗證的網站,請在 URL 中使用使用者名稱和密碼,如 RFC 1738_ 中所述,如下所示:open("http://myusername:myuserpassword@myexample.com/blah/blah/blah")

  • SSL 憑證警告:當啟用 Selenium RC 作為代理伺服器時,它會自動嘗試欺騙 SSL 憑證;有關此方面的更多資訊,請參閱 HTTPS 章節。如果您的瀏覽器設定正確,您永遠不應該看到 SSL 憑證警告,但是您可能需要設定您的瀏覽器以信任我們危險的「CyberVillains」SSL 憑證授權單位。同樣,請參閱 HTTPS 章節,以了解如何執行此操作。

  • 強制回應 JavaScript 警示/確認/提示對話方塊:Selenium 嘗試對您隱藏這些對話方塊(透過取代 window.alert、window.confirm 和 window.prompt),以便它們不會停止頁面的執行。如果您看到警示快顯視窗,則可能是因為它在頁面載入過程中觸發,這通常太早以至於我們無法保護頁面。Selenese 包含用於斷言或驗證警示和確認快顯視窗的命令。請參閱第 4 章中關於這些主題的章節。

在 Linux 上,為什麼我的 Firefox 瀏覽器工作階段沒有關閉?

在 Unix/Linux 上,您必須直接調用「firefox-bin」,因此請確保可執行檔位於路徑中。如果透過 shell 腳本執行 Firefox,則當需要終止瀏覽器時,Selenium RC 將終止 shell 腳本,而讓瀏覽器保持執行狀態。您可以直接指定 firefox-bin 的路徑,如下所示。

   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com

Firefox *chrome 無法與自訂設定檔一起運作

檢查 Firefox 設定檔資料夾 -> prefs.js -> user_pref(“browser.startup.page”, 0); 註解掉此行,如下所示:「//user_pref(“browser.startup.page”, 0);」,然後重試。

在父頁面載入時(即在父頁面的 javascript window.onload() 函數執行之前)載入自訂彈出視窗是否可以?

否。Selenium 依賴攔截器來判斷視窗名稱,因為它們正在載入。如果視窗是在 onload() 函數之後載入的,則這些攔截器在捕獲新視窗方面效果最佳。Selenium 可能無法識別在 onload 函數之前載入的視窗。

Linux 上的 Firefox

在 Unix/Linux 上,1.0 之前的 Selenium 版本需要直接調用「firefox-bin」,因此如果您使用的是先前版本,請確保真正的可執行檔位於路徑中。

在大多數 Linux 發行版上,真正的 firefox-bin 位於

   /usr/lib/firefox-x.x.x/ 

其中 x.x.x 是您目前擁有的版本號碼。因此,若要將該路徑新增到使用者的路徑,您將必須將以下內容新增到您的 .bashrc 檔案中

   export PATH="$PATH:/usr/lib/firefox-x.x.x/"

如有必要,您可以在測試中直接指定 firefox-bin 的路徑,如下所示

   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"

IE 和樣式屬性

如果您在 Internet Explorer 上執行測試,並且無法使用其 style 屬性找到元素。例如

    //td[@style="background-color:yellow"]

這在 Firefox、Opera 或 Safari 中可以完美運作,但在 IE 中則不行。IE 將 @style 中的鍵解釋為大寫。因此,即使原始碼是小寫,您也應該使用

    //td[@style="BACKGROUND-COLOR:yellow"]

如果您的測試旨在在多個瀏覽器上運作,這會是一個問題,但是您可以輕鬆地編碼您的測試以偵測情況並嘗試僅在 IE 中運作的替代定位器。

在關閉 *googlechrome 瀏覽器時遇到錯誤 - 「無法將物件轉換為基本值」

為了避免此錯誤,您必須使用禁用同源政策檢查的選項啟動瀏覽器

   selenium.start("commandLineFlags=--disable-web-security");

在 IE 中遇到錯誤 - 「無法開啟應用程式視窗;是否啟用了彈出視窗封鎖程式?」

為了避免此錯誤,您必須設定瀏覽器:停用快顯視窗封鎖程式,並取消選取「工具」»「網際網路選項」»「安全性」中的「啟用保護模式」選項。


  1. 代理伺服器是位於兩部分之間的第三者,負責在兩部分之間傳遞球。它充當「Web 伺服器」,將 AUT 傳遞到瀏覽器。作為代理伺服器,Selenium Server 具有「謊報」AUT 真實 URL 的能力。 ↩︎

  2. 瀏覽器啟動時使用的設定檔已將 localhost:4444 設定為 HTTP 代理伺服器,這就是為什麼瀏覽器執行的任何 HTTP 請求都將通過 Selenium 伺服器,並且回應將通過它,而不是來自真實伺服器。 ↩︎

上次修改日期:2022 年 1 月 10 日:更多 wiki (#907) [部署網站] (adcf706a1ad)