Selenium RC (Selenium 1)

Selenium 的原始版本

简介

在 WebDriver/Selenium 合并带来更强大的工具 Selenium 2 之前,Selenium RC 长期以来一直是主要的 Selenium 项目。值得强调的是,Selenium 1 已不再受支持。

Selenium RC 的工作原理

首先,我们将描述 Selenium RC 的组件如何操作,以及每个组件在运行测试脚本中的作用。

RC 组件

Selenium RC 组件包括

  • Selenium 服务器,它启动和关闭浏览器,解释和运行从测试程序传递的 Selenese 命令,并充当HTTP 代理,拦截和验证浏览器与 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 文件添加到您的项目 classpath 中。
  • 从 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 文档_

从 Selenese 到程序

使用 Selenium RC 的主要任务是将您的 Selenese 转换为编程语言。在本节中,我们将提供几个不同的特定于语言的示例。

示例测试脚本

让我们从一个示例 Selenese 测试脚本开始。假设使用 Selenium-IDE 记录以下测试。

打开/
输入qselenium rc
点击并等待btnG
断言文本存在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 等测试引擎平台,或 .NET 的 NUnit。

在这里,我们展示特定于语言的示例。特定于语言的 API 往往彼此不同,因此您会发现对每个 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。如果您正在使用这两种语言中的任何一种来使用 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 套接字。在某些客户端驱动程序中,这也是可选的。

  • browser 要在其中运行测试的浏览器。这是一个必需的参数。

  • url 被测应用程序的基本 URL。所有客户端库都需要此参数,并且是启动浏览器-代理-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 时,毫无疑问,您将开始输入您自己的“打印语句”以报告进度。这可能会逐渐导致您开发自己的报告,并可能与使用库或测试框架并行进行。无论如何,在最初的,但很短的学习曲线之后,您自然会开发出最适合您自己情况的方法。

测试报告示例

为了说明这一点,我们将引导您使用 Selenium 支持的其他语言中的一些特定工具。此处列出的工具是常用的,并且已被本指南的作者广泛使用(因此推荐)。

Java 中的测试报告

  • 如果使用 JUnit 开发 Selenium 测试用例,则可以使用 JUnit Report 生成测试报告。

  • 如果使用 TestNG 开发 Selenium 测试用例,则无需执行外部任务即可生成测试报告。TestNG 框架会生成一个 HTML 报告,其中列出了测试的详细信息。

  • ReportNG 是 TestNG 框架的 HTML 报告插件。它旨在替代默认的 TestNG HTML 报告。ReportNG 提供了简单的、颜色编码的测试结果视图。

记录 Selenese 命令
  • 记录 Selenium 可用于生成测试中所有 Selenese 命令的报告以及每个命令的成功或失败情况。记录 Selenium 扩展了 Java 客户端驱动程序以添加此 Selenese 记录功能。

Python 的测试报告

  • 使用 Python 客户端驱动程序时,可以使用 HTMLTestRunner 生成测试报告。

Ruby 的测试报告

  • 如果在 Ruby 中使用 RSpec 框架编写 Selenium 测试用例,则可以使用其 HTML 报告来生成测试报告。

为您的测试添加一些亮点

现在我们将讨论使用 Selenium RC 的全部原因:在测试中添加编程逻辑。它与任何程序都相同。程序流程使用条件语句和迭代来控制。此外,您可以使用 I/O 报告进度信息。在本节中,我们将展示一些示例,说明如何将编程语言结构与 Selenium 结合使用来解决常见的测试问题。

您会发现,当您从简单的页面元素存在性测试过渡到涉及多个网页和不同数据的动态功能测试时,您将需要编程逻辑来验证预期结果。基本上,Selenium-IDE 不支持迭代和标准条件语句。您可以通过在 Selenese 参数中嵌入 JavaScript 来执行一些条件,但是迭代是不可能的,而且大多数条件在
编程语言中会更容易实现。此外,您可能需要异常处理来进行错误恢复。出于这些原因以及其他原因,我们编写本节旨在说明如何使用常见的编程技巧,以便在自动化测试中为您提供更大的“验证能力”。

本节中的示例使用 C# 和 Java 编写,尽管代码很简单,可以很容易地适应其他支持的语言。如果您有一些面向对象编程语言的基本知识,那么您应该不难理解本节内容。

迭代

迭代是人们在测试中最常需要做的事情之一。例如,您可能需要多次执行搜索。或者,为了验证您的测试结果,您可能需要处理从数据库返回的“结果集”。

使用我们之前使用的相同的 Google 搜索示例,让我们检查 Selenium 的搜索结果。此测试可以使用 Selenese

打开/
输入qselenium rc
点击并等待btnG
断言文本存在selenium rc 的结果 *
输入qselenium ide
点击并等待btnG
断言文本存在selenium ide 的结果 *
输入qselenium grid
点击并等待btnG
断言文本存在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 引用的是 selenium 窗口,而不是测试窗口。

服务器选项

启动服务器时,可以使用命令行选项来更改默认的服务器行为。

回想一下,服务器是通过运行以下命令启动的。

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

要查看选项列表,请使用 -h 选项运行服务器。

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

您将看到可以使用服务器的所有选项列表以及每个选项的简短描述。提供的描述并不总是足够,因此我们提供了一些更重要选项的解释。

代理配置

如果您的 AUT 位于需要身份验证的 HTTP 代理后面,则应使用以下命令配置 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 Server 这一点

   -singlewindow 

指定 Firefox 配置文件

除非您为每个实例指定单独的配置文件,否则 Firefox 不会同时运行两个实例。Selenium RC 1.0 及更高版本会自动在单独的配置文件中运行,因此如果您使用的是 Selenium 1.0,则可能可以跳过本节。但是,如果您使用的是较旧版本的 Selenium,或者您需要为测试使用特定的配置文件(例如添加 https 证书或安装某些插件),则需要显式指定配置文件。

首先,要创建单独的 Firefox 配置文件,请按照此步骤操作。打开 Windows“开始”菜单,选择“运行”,然后键入并输入以下命令之一

   firefox.exe -profilemanager 
   firefox.exe -P 

使用对话框创建新配置文件。然后,在运行 Selenium Server 时,使用服务器命令行选项 -firefoxProfileTemplate 并指定配置文件的路径及其文件名和目录路径,告知它使用此新的 Firefox 配置文件。

   -firefoxProfileTemplate "path to the profile" 

警告:请务必将您的配置文件放在与默认配置分开的新文件夹中!如果您删除配置文件,Firefox 配置文件管理器工具将删除文件夹中的所有文件,而不管它们是否是配置文件。

有关 Firefox 配置文件的更多信息,请参见 Mozilla 知识库

使用 -htmlSuite 在服务器中直接运行 Selenese

您可以通过将 html 文件传递给服务器的命令行,在 Selenium Server 中直接运行 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 Server 报告的有价值的调试信息记录到文本文件中。

   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 Server 日志更有用。要访问浏览器端日志,请将 -browserSideLog 参数传递给 Selenium Server。

   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 命令)必须与被测应用程序位于相同的来源(相同的 URL)。

从历史上看,Selenium-Core 受此问题的限制,因为它是在 JavaScript 中实现的。但是,Selenium RC 不受同源策略的限制。它使用 Selenium Server 作为代理来避免此问题。它本质上是告诉浏览器,浏览器正在服务器提供的单个“欺骗”网站上工作。

注意:您可以在 Wikipedia 上有关同源策略和 XSS 的页面上找到有关此主题的其他信息。

代理注入

Selenium 用来避免同源策略的第一种方法是代理注入。在代理注入模式下,Selenium Server 充当客户端配置的 HTTP 代理1,位于浏览器和被测应用程序2之间。然后,它会使用虚构的 URL 屏蔽 AUT(嵌入 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。
  3. Selenium-Core 从客户端/驱动程序获取第一个指令(通过向 Selenium RC 服务器发出的另一个 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,则不需要也不应该使用这些旧的运行模式。

安全证书说明

通常,您的浏览器会通过安装您已经拥有的安全证书来信任您正在测试的应用程序。您可以在浏览器的选项或 Internet 属性中检查这一点(如果您不知道 AUT 的安全证书,请咨询您的系统管理员)。当 Selenium 加载您的浏览器时,它会注入代码来拦截浏览器和服务器之间的消息。现在,浏览器认为不受信任的软件正试图看起来像您的应用程序。它通过弹出消息来警告您。

为了解决这个问题,Selenium RC(同样,当使用支持此功能的运行模式时)会将它自己的安全证书临时安装到您的客户端机器上,浏览器可以访问该证书的位置。这会欺骗浏览器认为它正在访问与您的 AUT 不同的站点,并有效地抑制弹出窗口。

早期版本的 Selenium 使用的另一种方法是安装 Selenium 安装提供的 Cybervillians 安全证书。但是,大多数用户不再需要这样做;如果您在代理注入模式下运行 Selenium RC,您可能需要显式安装此安全证书。

支持其他浏览器和浏览器配置

除了 Internet Explorer 和 Mozilla Firefox 之外,Selenium API 还支持针对多个浏览器运行。请访问 https://seleniumcn.cn 网站,查看支持的浏览器。此外,当浏览器没有直接支持时,您仍然可以使用“*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 服务器作为代理。通常,这只需打开您的浏览器首选项并指定“localhost:4444”作为 HTTP 代理,但是不同浏览器的说明可能差异很大。有关详细信息,请查阅浏览器的文档。

请注意,Mozilla 浏览器在启动和停止的方式上可能有所不同。可能需要设置 MOZ_NO_REMOTE 环境变量,以使 Mozilla 浏览器的行为更可预测一些。Unix 用户应避免使用 shell 脚本启动浏览器;通常最好直接使用二进制可执行文件(例如 firefox-bin)。

解决常见问题

刚开始使用 Selenium RC 时,会遇到一些常见的潜在问题。我们在此处列出这些问题及其解决方案。

无法连接到服务器

当您的测试程序无法连接到 Selenium 服务器时,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 服务器。如果是这样,则 Selenium 客户端库和 Selenium 服务器之间的连接存在问题。

刚开始使用 Selenium RC 时,大多数人开始在其同一台机器上运行测试程序(带有 Selenium 客户端库)和 Selenium 服务器。为此,请使用“localhost”作为您的连接参数。我们建议您以此方式开始,因为它减少了潜在的网络问题的影响,您正在入门。假设您的操作系统具有典型的网络和 TCP/IP 设置,您应该没有什么困难。事实上,很多人选择以这种方式运行测试。

但是,如果您确实想在远程计算机上运行 Selenium 服务器,则假设两台计算机之间具有有效的 TCP/IP 连接,则连接应该没有问题。

如果您在连接时遇到困难,可以使用常用的网络工具(如 pingtelnetifconfig(Unix)/ipconfig (Windows) 等)来确保您具有有效的网络连接。如果您不熟悉这些工具,您的系统管理员可以帮助您。

无法加载浏览器

好的,这不是友好的错误消息,抱歉,但是如果 Selenium 服务器无法加载浏览器,您可能会看到此错误。

    (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 服务器时没有指定单独的配置文件。测试程序的错误如下所示

    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 和最广泛使用的浏览器版本。

启动服务器时出现错误消息:“(不支持的 major.minor 版本 49.0)”

此错误表示您没有使用正确的 Java 版本。Selenium 服务器需要 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 服务器未正确配置为代理。“selenium-server” 目录在 google.com 上不存在;它仅在正确配置代理时才会显示存在。代理配置高度取决于浏览器使用 firefox、iexplore、opera 或自定义方式启动。

  • iexplore: 如果使用 *iexplore 启动浏览器,您可能遇到了 Internet Explorer 的代理设置问题。Selenium Server 尝试在 Internet 选项控制面板中配置全局代理设置。您必须确保在 Selenium Server 启动浏览器时这些设置已正确配置。请查看您的 Internet 选项控制面板。单击“连接”选项卡,然后单击“局域网设置”。

    • 如果您需要使用代理来访问您想要测试的应用程序,您需要使用“-Dhttp.proxyHost”启动 Selenium Server;有关更多详细信息,请参阅 Proxy Configuration_。
    • 您也可以尝试手动配置代理,然后使用 *custom 或 *iehta 浏览器启动器启动浏览器。
  • custom: 当使用 *custom 时,您必须正确(手动)配置代理,否则您将收到 404 错误。请仔细检查您是否正确配置了代理设置。要检查您是否正确配置了代理,可以尝试故意错误地配置浏览器。尝试将浏览器配置为使用错误的代理服务器主机名或错误的端口。如果您成功地错误配置了浏览器的代理设置,则浏览器将无法连接到互联网,这是确保您正在调整相关设置的一种方法。

  • 对于其他浏览器(*firefox、*opera),我们会自动为您硬编码代理,因此此功能没有已知问题。如果您遇到 404 错误并且已经仔细遵循了本用户指南,请将您的结果发布到用户组,以获取用户社区的帮助。

权限被拒绝错误

此错误最常见的原因是您的会话尝试通过跨越域边界(例如,访问来自 http://domain1 的页面,然后访问来自 http://domain2 的页面)或切换协议(从 http://domainX 移动到 https://domainX)来违反同源策略。

当 JavaScript 尝试查找尚未可用(在页面完全加载之前)或不再可用(在页面开始卸载之后)的 UI 对象时,也可能发生此错误。这在处理页面或子框架的 AJAX 页面中最常见,这些页面或子框架独立于较大的页面加载和/或重新加载。

此错误可能是间歇性的。通常,使用调试器无法重现此问题,因为问题源于当调试器的开销添加到系统时无法重现的竞争条件。教程中详细介绍了权限问题。请仔细阅读有关 The Same Origin Policy_ 和 Proxy Injection_ 的部分。

处理浏览器弹出窗口

在 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)