Selenium自動化測試框架研究

Selenium自動化測試框架研究

1. 介紹

Selenium這個單詞的字面意思是""Selenium的官方網站是http://www.seleniumhq.org./

2. 編譯Selenium

可以從http://selenium.googlecode.com/git/取得Selenium項目的全部源代碼。

git clone http://selenium.googlecode.com/git/ selenium

terminal下進入selenium目錄,輸入,

./go

或者,

./go clean release

等待編譯完成。

我在編譯過程出現依賴性錯誤,需要libibus-dev包。

3. Selenium IDE

Selenium IDE是一個Firefox下的插件,可以使用Firefox直接從selenium的網站上安裝。

Selenium IDE是一個簡單的Selenium的腳本錄製、編輯和驗證工具,可以用於測試用例的錄製,並且可以把selenium的測試腳本轉換成其它的語言,如:javapython等。

4. Selenium Remote Control

Selenium Remote Control是測試服務,可以使用selenium client把測試任務指派給selenium rc,讓其執行。

通常情況下都是使用selenium rc + selenium client + selenium ide的模式來完成測試任務。

5. Selenium的編譯環境

5.1. 概述

Selenium編譯是從目錄下的go(for linux)/go.bat(for windows)這兩個文件開始的。 go文件的內容如下:

Toggle line numbers   1#!/bin/bash

  2

  3# we want jruby-complete to take care of all things ruby

  4unset GEM_HOME

  5unset GEM_PATH

  6

  7JAVA_OPTS="-client"

  8

  9java $JAVA_OPTS -Xmx2048m -XX:MaxPermSize=1024m -XX:ReservedCodeCacheSize=256m -jar third_party/jruby/jruby-complete.jar -X-C -S rake $*

go.bat的大致相同。

RakefileRake構建工程使用的工程文件,相當於MakefileRakefile的語法是基於ruby的。

5.2. Rakefile

5.2.1. 介紹

Selenium使用Rake作爲構建環境,rake是一個基於ruby語言的與makefile相似的跨平臺的多任務的構建系統,其官方網站是http://rake.rubyforge.org/

Rake構建系統的構建文件是Rakefile,到selenium項目的根目錄下,可以找到seleniumRakefile文件。Rakefile的語法基礎是ruby,可以從rake的官方網站上找到具體的語法說明及例程。

5.2.2. SeleniumRakefile

5.2.2.1. 導入crazyfun依賴

Toggle line numbers   1# The CrazyFun build grammar. There's no magic here, just ruby

  2require'rake-tasks/crazy_fun'

  3require'rake-tasks/crazy_fun/mappings/android'

  4require'rake-tasks/crazy_fun/mappings/export'

  5require'rake-tasks/crazy_fun/mappings/folder'

  6require'rake-tasks/crazy_fun/mappings/gcc'

  7require'rake-tasks/crazy_fun/mappings/java'

  8require'rake-tasks/crazy_fun/mappings/javascript'

  9require'rake-tasks/crazy_fun/mappings/mozilla'

 10require'rake-tasks/crazy_fun/mappings/python'

 11require'rake-tasks/crazy_fun/mappings/rake'

 12require'rake-tasks/crazy_fun/mappings/rename'

 13require'rake-tasks/crazy_fun/mappings/ruby'

 14require'rake-tasks/crazy_fun/mappings/visualstudio'

5.2.2.2. 導入其它的依賴

Toggle line numbers   1# The original build rules

  2require'rake-tasks/task-gen'

  3require'rake-tasks/checks'

  4require'rake-tasks/dotnet'

  5require'rake-tasks/zip'

  6require'rake-tasks/c'

  7require'rake-tasks/java'

  8require'rake-tasks/iphone'

  9require'rake-tasks/selenium'

 10require'rake-tasks/se-ide'

 11require'rake-tasks/ie_code_generator'

 12require'rake-tasks/ci'

 13

 14require'rake-tasks/gecko_sdks'

5.2.2.3. 使用crazyfun

Toggle line numbers   1# The build system used by webdriver is layered on top of rake, and we call it

  2# "crazy fun" for no readily apparent reason.

  3

  4# First off, create a new CrazyFun object.

  5crazy_fun = CrazyFun.new

  6

  7# Secondly, we add the handlers, which are responsible for turning a build

  8# rule into a (series of) rake tasks. For example if we're looking at a file

  9# in subdirectory "subdir" contains the line:

 10#

 11# java_library(:name => "example", :srcs => ["foo.java"])

 12#

 13# we would generate a rake target of "//subdir:example" which would generate

 14# a Java JAR at "build/subdir/example.jar".

 15#

 16# If crazy fun doesn't know how to handle a particular output type ("java_library"

 17# in the example above) then it will throw an exception, stopping the build

 18AndroidMappings.new.add_all(crazy_fun)

 19ExportMappings.new.add_all(crazy_fun)

 20FolderMappings.new.add_all(crazy_fun)

 21GccMappings.new.add_all(crazy_fun)

 22JavaMappings.new.add_all(crazy_fun)

 23JavascriptMappings.new.add_all(crazy_fun)

 24MozillaMappings.new.add_all(crazy_fun)

 25PythonMappings.new.add_all(crazy_fun)

 26RakeMappings.new.add_all(crazy_fun)

 27RenameMappings.new.add_all(crazy_fun)

 28RubyMappings.new.add_all(crazy_fun)

 29VisualStudioMappings.new.add_all(crazy_fun)

這裏可以看到rakefile通過crazyfun實現了對各種編譯環境的支持,如:AndroidJavaGccVS等。

5.2.2.4. 創建crazyfun的任務

Toggle line numbers   1# Finally, find every file named "build.desc" in the project, and generate

  2# rake tasks from them. These tasks are normal rake tasks, and can be invoked

  3# from rake.

  4crazy_fun.create_tasks(Dir["**/build.desc"])

這裏在工程的所有子目錄中查找build.desc文件,並根據build.desc創建rake中的任務。

5.3. CrazyFunBuild

5.3.1. 介紹

關於crazyfun的介紹可以直接訪問,https://code.google.com/p/selenium/wiki/CrazyFunBuild

如果需要修改或是擴展Selenium中的包或庫,就要修改對應的包或庫的build.desc文件,把增加的源代碼和路徑顯式的或隱式的添加到對應的包/庫中。

5.3.2. CrazyFun的簡單說明

其實在rakefilecrazyfun那一段中也有一個簡單的Java的例子,如下:

Toggle line numbers   1java_library(name="example",

  2resources=["example.java"],

  3deps=[":base"])

上面這個build.desc的說明:

  • Java編譯,生成一個名爲example.jar的包;

  • 編譯的源文件是當前目錄下的example.java

  • example項目編譯依賴於base.jar

5.3.3. Selenium進行Java二次開發

5.3.3.1. 創建Java工程

根據Selenium的目錄結構來看,可以使用Eclipse或其它的IDE創建Java工程,工程創建完成後,如果需要在Rakefile中統一編譯,則需要在對應的源代碼目錄中增加build.desc

下面代碼是{$SeleniumHome}/java/server/src/org/openqa/selenium/server目錄下的build.desc文件,

Toggle line numbers   1java_binary(name = "server",

  2main_class = "org.openqa.selenium.server.SeleniumServer",

  3deps = [

  4":base",

  5":server_resources",

  6"//java/client/src/org/openqa/selenium:client-combined",

  7"//third_party/java/opera-driver",

  8  ])

  9

 10# Light version of the server for drivers that don't need to depend on all other drivers.

 11# We need at least one source file in here to make this build the JAR

 12# TODO(simon): Only resources should be fine

 13java_binary(name = "server_lite",

 14main_class = "org.openqa.selenium.server.SeleniumServer",

 15deps = [

 16":base",

 17":server_resources",

 18  ])

 19

 20java_library(name = "server_resources",

 21resources = [

 22"customProfileDirCUSTFF",

 23"customProfileDirCUSTFFCHROME",

 24"hudsuckr",

 25"konqueror",

 26"opera",

 27"sslSupport",

 28"VERSION.txt",

 29  ],

 30deps = [

 31"//javascript/selenium-core"

 32  ])

 33

 34java_library(name = "logging",

 35srcs = [

 36"RemoteControlConfiguration.java",

 37"SslCertificateGenerator.java",

 38  ],

 39deps = [

 40"//java/client/src/org/openqa/selenium/remote:common",

 41"//java/server/src/org/openqa/jetty",

 42"//java/client/src/org/openqa/selenium/logging:api",

 43"//java/client/src/org/openqa/selenium/logging:logging",

 44"//java/server/src/org/openqa/selenium/remote/server/log",

 45  ])

 46

 47java_library(name = "base",

 48srcs = [

 49"**/*.java",

 50  ],

 51deps = [

 52":logging",

 53"//java/client/src/org/openqa/selenium:codecs",

 54"//java/client/src/org/openqa/selenium:selenium-api",

 55"//java/client/src/org/openqa/selenium/browserlaunchers:launcher-utils",

 56"//java/client/src/org/openqa/selenium/net",

 57"//java/client/src/org/openqa/selenium/support",

 58"//java/server/src/cybervillains",

 59"//java/server/src/org/openqa/selenium/remote/server",

 60"//java/server/src/org/openqa/jetty",

 61"//third_party/java/servlet-api"

 62  ])

從上面代碼可以看出,在srcs中既可以使用完整的路徑,也可以使用通配符*.java

下面單獨以"server"這個task爲例進行說明:

Toggle line numbers   1java_binary(name="server",

  2main_class="org.openqa.selenium.server.SeleniumServer",

  3deps=[

  4":base",

  5":server_resources",

  6"//java/client/src/org/openqa/selenium:client_combined",

  7"//third_party/java/opera-driver"

  8])

說明:

  • java_binary說明這個task是生成一個可以執行的jar包,在生成的MANIFEST.MF文件裏有Main-Class

  • name是指出生成的jar包的名字;

  • main_class指出這個可執行的jar包的入口點是SeleniumServer,這會寫入MANIFEST.MF文件,如:"Main-Class:org.openqa.selenium.server.SeleniumServer"

  • ":base"是本地的依賴關係,"//third_party/java/opera-driver"這樣的寫法是指出非本地的依賴包。

5.3.4. Selenium中進行C or C++ 二次開發

Selenium中的C/C++模塊由cpp目錄下的build.desc在管理,按照Selenium的目錄結構,由CC++開發的庫或應用程序工程都放在cpp目錄,並且在build.desc中添加對應的task

下面具體分析build.desc的內容。

5.3.4.1. GCC編譯

Toggle line numbers   1gcc_library(name = "noblur",

  2srcs = [ "linux-specific/*.c" ],

  3args = "-I/usr/include",

  4arch = "i386")

  5

  6gcc_library(name = "noblur64",

  7srcs = [ "linux-specific/*.c" ],

  8args = "-I/usr/include",

  9arch = "amd64")

說明:

  • "gcc_library"指出輸出一個.a.so的庫文件;

  • "srcs"需要編譯的.c文件的路徑;

  • "args"是一些需要的編譯參數,如:"-I""-L"等;

  • "arch"是編譯器的架構,i38632位,amd6464位。

5.3.4.2. VS編譯

Toggle line numbers   1visualc_library(name = "firefox_dll",

  2platform = "Win32",

  3project = "webdriver-firefox/webdriver-firefox.vcxproj",

  4file_deps = "third_party/gecko-2/win32",

  5out = "Win32/Release/webdriver-firefox.dll"

  6)

  7visualc_release(name = "ie_win32_exe",

  8deps = [

  9":atoms",

 10":ie_result_type_cpp",

 11":sizzle"

 12  ],

 13platform = "Win32",

 14project = "IEDriverServer/IEDriverServer.vcxproj",

 15desc = "InternetExplorerDriver standalone server for 32-bit IE",

 16out = "Win32/Release/IEDriverServer.exe"

 17)

說明:

  • "visualc_library"是輸出一個windows操作系統下的DLL庫文件;

  • "visualc_release"是輸出一個windows操作系統下的可執行文件;

  • "platform"如果是"win32",則輸出32位版本,如果是"x64",則輸出64位的版本;

  • "project"是指vs的工程文件的路徑;

  • "deps"是庫依賴;

6. Selenium工程的調試(for linux)

6.1. 調試環境的準備

Selenium的工程目錄來看,Selenium中的Java部件可以使用EclipseIntellij IDEA打開。

如果需要調試C/C++的代碼需要在windows操作系統下裝有Visual Studio 10以上版本或linux操作系統下gcc + gdb支持。

6.2. Java代碼的調試

6.2.1. Eclipse導入Selenium

eclipsemenu下的"file">>"import"打開import對話框,

import_001.jpg

選擇"Existing Projects into Workspace"

import_003.jpg

選擇selenium工程的頂級目錄,

import_002.jpg

"Projects"中選擇要導入的工程,除了"android"以外的工程,"client""server""selenium-common""third-party"全部都要導入。

eclipse_001.jpg

6.2.2. debug模式啓動Selenium Server

打開"selenium/java/server/src/org/openqa/selenium/server"目錄下的"build.desc"文件,找到如下,

Toggle line numbers   1java_binary(name = "server",

  2main_class = "org.openqa.selenium.server.SeleniumServer",

  3deps = [

  4":base",

  5":server_resources",

  6"//java/client/src/org/openqa/selenium:client-combined",

  7"//third_party/java/opera-driver",

  8  ])

根據main_class中所指出的,打開SeleniumServer.java文件,從工具欄上選擇"Debug As">>"Java Application",如果沒有錯誤,服務器就會正常啓動並監聽0.0.0.0:4444地址。

6.2.3. 訪問測試服務器

使用selenium簡單錄製一個testcase,把這個case轉爲python代碼,如下,

Toggle line numbers   1fromseleniumimportselenium

  2importunittest, time, re

  3

  4classtestng(unittest.TestCase):

  5defsetUp(self):

  6self.verificationErrors = []

  7self.selenium = selenium("localhost", 4444, "*chrome", "http://www.baidu.com/")

  8self.selenium.start()

  9

 10deftest_testng(self):

 11sel = self.selenium

 12sel.open("/")

 13sel.type("id=kw", "testng")

 14sel.click("id=su")

 15sel.wait_for_page_to_load("30000")

 16

 17deftearDown(self):

 18self.selenium.stop()

 19self.assertEqual([], self.verificationErrors)

 20

 21if__name__ == "__main__":

 22unittest.main()

上述內容保存爲test.py文件放到,selenium工程的py目錄下,一種方式是在console裏輸入,

python test.py

另一種方式是用sublimetext打開test.py,快捷鍵Ctrl+B運行。

運行測試代碼後,可以在eclipse下的console窗口看到server運行輸出的log及其它信息。

6.3. C/C++代碼的調試

分析gcc.rb文件後可知,linux版本沒有啓用調試選項,最終輸出的代碼使用了"-Os"優化選項,因此最終輸出的so文件中不包含符號鏈接,可以通過兩種方式解決C/C++代碼的調試,-是在gcc.rb中啓用"-g -DDBUG=1",打開調試,生成debug版本的so文件;另一個方法是在windows下用VS進行調試。

Eclipse中搜索關鍵字"native",可以發現C++的工程生成的DLL或是SO文件都在client中調用,與Server無關。

6.3.1. Visual Studio 12中打開seleniumwebdriver工程

selenium的最上層目錄下,找到webdriver.sln文件,雙擊,讓visual studio打開這個文件(假設已經安裝了Visual Studio 10以上版本)

webdriver_sln.jpg

如果打開沒有發生錯誤,就可以看到如下,

webdriver_vs2012_001.jpg

過濾一下,如下圖所示,

webdriver_vs2012_002.jpg



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章