軟件測試入門④——測試腳本【講義】

六天入門四_新版公眾號首圖_2018.10.23(2).png

Day 4 測試腳本講義

經(jīng)過了前面三天的課程內(nèi)容母赵,我們應該初步基本的掌握了手工測試。接下來我們來面對另一個高度的挑戰(zhàn)悠砚,就是自動化測試。自動化測試是近期的一個熱門概念堂飞,在一線城市的軟件測試招聘中灌旧,經(jīng)常會出現(xiàn)自動化測試的要求,而且在面試的過程中绰筛,企業(yè)和面試官也是會涉及到自動化測試相關的內(nèi)容枢泰。接下來我們用兩張圖來說明自動化測試的內(nèi)容。

首先我們來看看手工測試铝噩。

img
img

再來看自動化測試衡蚂。

img
img

本次講義,主要解決的問題如下:

  • 自動化測試的本質(zhì)是什么骏庸?
  • Web UI 自動化測試的對象怎么理解毛甲?
  • Selenium 是一個什么樣的工具?

注意:本講義探討的自動化測試是 Web UI 自動化測試具被。

0 主要內(nèi)容

  • 1 T5_自動化測試分析
  • 2 T6_自動化測試環(huán)境準備
  • 3 T7_自動化測試腳本編寫

1 T5_自動化測試分析

1.1 自動化測試的出發(fā)點

還記得上一屆內(nèi)容中對“回歸測試”的描述么玻募?在敏捷開發(fā)的實踐中,每一次新版本的發(fā)布一姿,都會要求對過往版本已經(jīng)測試過的功能進行回歸測試补箍。一般會挑選重要的測試用例,加入到回歸測試的用例集合中啸蜜,然后在每一次的新版本中坑雅,重新執(zhí)行。

這樣的要求衬横,如果單純依靠手工測試裹粤,那么工作量會相當大,而且也會增加測試人員的疲倦情緒,于是遥诉,自動化測試就閃亮登場了拇泣。目前自動化測試其實主要解決的就是回歸測試的問題,而不能夠做到完全替代手工測試矮锈。

1.2 自動化測試的對象分析

本次講義的內(nèi)容霉翔,我們重點分析的就是 Web UI(瀏覽器界面)的自動化測試,并且我們已知“自動化測試就是人類讓電腦替自己做測試執(zhí)行”的過程苞笨,那么我們首先要分析一下债朵,瀏覽器界面的執(zhí)行因素。

如果你還不明白講義在這里指代的內(nèi)容是什么瀑凝,那么我們用瀏覽器自帶的開發(fā)者工具查看瀏覽器渲染的 html 源碼序芦。

image.png

瀏覽器渲染的內(nèi)容是由一個個tag組成的。我們平時通過手工測試點擊瀏覽器粤咪,實際上就是選擇了瀏覽器渲染出來的 html 標簽谚中,并且對其進行操作的。

1.3 自動化測試的工具要求

自動化測試就需要做到下面的事情寥枝,即可宪塔。

  • 讓電腦明白去找哪個瀏覽器的哪個標簽
  • 找到標簽后做什么樣具體的操作
  • 操作以后,檢查操作是否成功

2 T6_自動化測試環(huán)境準備

2.1 選擇并安裝編程語言

從上面一節(jié)囊拜,我們知道蝌麸,讓電腦替我們做事情,并且要讓電腦給出檢查結(jié)果艾疟,這是需要通過編程語言來實現(xiàn)的。因為“電腦不懂人話”……

現(xiàn)在主流的可以選擇的編程語言進行測試敢辩,主要集中在 Python 和 Java 上蔽莱。部分工具也會選擇 C#。我們這里選擇 Python戚长。

Python 語言的選擇盗冷,便捷

  • 測試人員的編程能力普遍不是很強,而Python作為一種腳本語言同廉,不僅功能強大仪糖,而且語法優(yōu)美,支持多種自動化測試工具迫肖,而且學習上手比較容易锅劝。
  • Python的社區(qū)發(fā)展比較好,有著非常多的文檔和支持庫蟆湖,另外Python也可以在Web開發(fā)故爵、數(shù)據(jù)處理、科學計算等縱多領域有著非常好的應用前景隅津。
  • 對于有一定編程基礎的人員诬垂,使用Python作為自動化測試的語言可以非常順暢的轉(zhuǎn)換劲室,幾乎沒有學習成本。同時Python是標準的面向?qū)ο蟮木幊陶Z言结窘,對于C#很洋、Java等面向?qū)ο蟮恼Z言有著非常好的示例作用,通過Python的示例可以非常輕松的觸類旁通隧枫,使用其他語言進行Selenium2.0的WebDriver的使用喉磁。
  • 讀音:/'pa?θ?n/
  • Python的創(chuàng)始人為Guido Van Rossum。1989年圣誕節(jié)期間悠垛,在阿姆斯特丹线定,Guido為了打發(fā)圣誕節(jié)的無趣,決心開發(fā)一個新的腳本解釋程序确买,做為ABC 語言的一種繼承斤讥。之所以選中Python(大蟒蛇的意思)作為程序的名字,是因為他是一個叫Monty Python的喜劇團體的愛好者湾趾。
  • Python 語言除了在自動化測試領域有出色的表現(xiàn)外芭商,在系統(tǒng)編程,網(wǎng)絡編程搀缠,web 開發(fā)铛楣,GUI開發(fā),科學計算艺普,游戲開發(fā)等多個領域應用非常廣泛簸州,而且具有非常良好的社區(qū)支持。也就是說學習和掌握python 編程歧譬,其實是為你打開了一道更廣闊的大門岸浑。

安裝 Python 語言

Python的官方網(wǎng)站:http://www.python.org

Python 目前并行了兩套版本,2.x 和 3.x瑰步。如果你之前沒有 Python 的使用經(jīng)驗矢洲,建議使用 Python 3.x 版本。兩套版本互相不兼容缩焦,并且 Python 從 3.5(含)開始读虏,不再支持 Windows XP 系統(tǒng),請注意袁滥。

  • 選擇安裝目錄

    • 3.4或者3.4以下的版本盖桥,都是 C:\python34
    • 3.5以上的目錄,默認裝個人文件夾题翻,建議用類似上面的目錄葱轩,比如C:\python35
    Snap1.jpg
  • 勾選添加環(huán)境變量

    勾選Add Python.exe to PATH

    Snap2.jpg
  • 安裝過程中不要關閉彈出來的命令行窗口

  • 關于 Python 的安裝,也可以選擇一些第三方的Python 安裝包,典型的有 Anaconda3靴拱,這樣的包有豐富的第三方庫垃喊,在使用 Python 的過程中會更加方便。

    Anaconda 的官網(wǎng):https://www.continuum.io/anaconda-overview

2.2 設置測試工具與驅(qū)動

Selenium 是開源的自動化測試工具袜炕,它主要是用于Web 應用程序的自動化測試本谜,不只局限于此,同時支持所有基于web 的管理任務自動化偎窘。

  • Selenium官網(wǎng)的介紹

    Selenium is a suite of tools to automate web browsers across many platforms.

    • runs in many browsers and operating systems
    • can be controlled by many programming languages and testing frameworks.

    Selenium 是用于測試 Web 應用程序用戶界面 (UI) 的常用框架乌助。它是一款用于運行端到端功能測試的超強工具。您可以使用多個編程語言編寫測試陌知,并且 Selenium 能夠在一個或多個瀏覽器中執(zhí)行這些測試他托。

    Selenium 誕生于 2004 年,當在 ThoughtWorks 工作的 Jason Huggins 在測試一個內(nèi)部應用時仆葡。作為一個聰明的家伙赏参,他意識到相對于每次改動都需要手工進行測試,他的時間應該用得更有價值沿盅。他開發(fā)了一個可以驅(qū)動頁面進行交互的 Javascript 庫把篓,能讓多瀏覽器自動返回測試結(jié)果。那個庫最終變成了 Selenium 的核心腰涧,它是 Selenium RC(遠程控制)和 Selenium IDE 所有功能的基礎韧掩。Selenium RC 是開拓性的,因為沒有其他產(chǎn)品能讓你使用自己喜歡的語言來控制瀏覽器窖铡。這就是 Selenium 1疗锐。

    在 2006 年,一名 Google 的工程師费彼, Simon Stewart 開始基于這個項目進行開發(fā)滑臊,這個項目被命名為 WebDriver。此時敌买,Google 早已是 Selenium 的重度用戶,但是測試工程師們不得不繞過它的限制進行工具阶界。Simon 需要一款能通過瀏覽器和操作系統(tǒng)的本地方法直接和瀏覽器進行通話的測試工具虹钮,來解決Javascript 環(huán)境沙箱的問題。WebDriver 項目的目標就是要解決 Selenium 的痛點膘融。

    到了 2008 年芙粱,Selenium 和 WebDriver 兩個項目合并。Selenium 有著豐富的社區(qū)和商業(yè)支持氧映,但 WebDriver 顯然代表著未來的趨勢春畔。兩者的合并為所有用戶提供了一組通用功能,并且借鑒了一些測試自動化領域最閃光的思想。這就是 Selenium 2律姨。

    2016 年振峻,Selenium 3 誕生。移除了不再使用的 Selenium 1 中的 Selenium RC择份,并且官方重寫了所有的瀏覽器驅(qū)動扣孟。

    • 安裝 Selenium 工具包

      由于 安裝好的 Python 默認有 pip Python 包管理工具,可以通過 pip 非常方便的安裝 Selenium荣赶。

      • 啟動命令行工具:Win+R | 輸入 cmd | 回車

      • 輸入命令:

        pip install selenium
        

        該命令的執(zhí)行需要有互聯(lián)網(wǎng)聯(lián)網(wǎng)環(huán)境凤价。此外該命令有以下幾種選項可以使用

        • 安裝指定的版本,例如安裝指定的 Selenium 3.4.3

          pip install selenium==3.4.3
          

          ?

        • 安裝最新版的 Selenium

          pip install -U selenium
          # -U 也可以用 --upgrade
          pip install --upgrade selenium
          

          ?

        • 卸載安裝當前的 Selenium

          pip uninstall selenium
          
      • 當然拔创,如果您的機器處于非接入互聯(lián)網(wǎng)的環(huán)境利诺,您可以事先下載 Selenium 的 Python 安裝包,再進行手動安裝剩燥。

  • 配置 瀏覽器 和 驅(qū)動

    • Selenium 2 可以默認支持Firefox 46.0或者更低版本,對于其他瀏覽器需要額外安裝驅(qū)動比伏。

    • Selenium 3 對于所有的瀏覽器都需要安裝驅(qū)動胜卤,本文以 Chrome 和 Firefox、IE為例設置瀏覽器和驅(qū)動赁项。

    • 瀏覽器驅(qū)動的配置

      • 首先舰攒,將下載好的對應版本的瀏覽器安裝。
      • 其次悔醋,在 Python 的根目錄中摩窃,放入瀏覽器驅(qū)動。
      • 最好再重啟電腦芬骄,一般情況下不重啟也可以的猾愿。

2.3 使用 IDE 進行腳本編寫

  • JetBrains PyCharm 的介紹

PyCharm 是 JetBrains 公司針對Python推出的IDE(Integrated Development Environment,集成開發(fā)環(huán)境)账阻。是目前最好的Python IDE之一蒂秘。目前包含了兩個版本:

  • 社區(qū)版,Community Edition
  • 專業(yè)版淘太,Professional Edition
    • 付費
    • 比社區(qū)版主要多了Web開發(fā)框架

我們推薦使用免費的社區(qū)版本姻僧,進行Python腳本的編寫和自動化測試執(zhí)行规丽。

PyCharm可以在官網(wǎng)下載,http://www.jetbrains.com

PyCharm 安裝后撇贺,如果也安裝過 Python 環(huán)境赌莺,可以直接進行操作。否則請在 1.2.3 中安裝好 Python显熏,再使用 PyCharm雄嚣。

  • 安裝按照默認的步驟安裝

    • 使用方式

      • Create New Project:

        創(chuàng)建新的項目,選擇項目創(chuàng)建的位置喘蟆,選擇Python的解釋器

        Snap3.jpg
        Snap4.jpg
        • 設置location缓升,項目的路徑和名稱
          • 名稱必須以英文字母開頭
          • 名稱不可以有空格
          • 位置不可以在 C:\Pytho34中,應該放到普通的目錄中
        • 設置interpreter
          • 一個電腦可以裝多個 Python
          • 這里選擇一個你需要的 Pythpn

        新建Python文件

        Snap11.jpg
        Snap8.jpg

        在創(chuàng)建的文件中編寫第一個Python語句

        print("hello Python!")
        
        Snap9.jpg

        右鍵該文件蕴轨,選擇Run hello港谊,運行該語句,在下面的運行框中會顯示運行結(jié)果

        C:\Python35\python.exe D:/Git/WeekendSelenium/untitled/hello.py
        hello python!
        
        Process finished with exit code 0
        

        如圖

        Snap10.jpg
      • Open

        打開已經(jīng)存在的項目橙弱,比如別人發(fā)給你的項目歧寺,或者已經(jīng)創(chuàng)建過的項目

        Snap5.jpg
        Snap7.jpg
  • 安裝后進行設置如下:

    • 設置行號的顯示

      永久設置主儡。File --> Settings -->Editor -->Appearance , 之后勾選Show Line Numbers竭鞍。

      Snap12.jpg

      ?

    • 設置字體

      選擇 Settings | Editor | Colors & Fonts | Fonts

      Save AS 主題

      選擇 Source Code Pro(建議選擇,等寬字體)

編寫第一個腳本

通過上一節(jié)的環(huán)境安裝成功以后邓夕,我們可以進行第一個對Selenium 的使用蛀缝,就是最簡腳本編寫顷链。腳本如下:

# 聲明一個司機,司機是個Chrome類的對象
driver = webdriver.Chrome()

# 讓司機加載一個網(wǎng)頁
driver.get("http://demo.ranzhi.org")

# 給司機3秒鐘去打開
sleep(3)

# 開始登錄
# 1. 讓司機找用戶名的輸入框
we_account = driver.find_element_by_css_selector('#account')
we_account.clear()
we_account.send_keys("demo")

# 2. 讓司機找密碼的輸入框
we_password = driver.find_element_by_css_selector('#password')
we_password.clear()
we_password.send_keys("demo")

# 3. 讓司機找 登錄按鈕 并 單擊
driver.find_element_by_css_selector('#submit').click()
sleep(3)

實際上一段20行的代碼屈梁,也不能算太少了嗤练。但是這段代碼的使用,確實體現(xiàn)了 Selenium 的最簡單的使用在讶。我們在下面內(nèi)容進行闡述煞抬。

  • 關于面向?qū)ο缶幊?/p>

    通過前面的介紹,我們知道 Selenium 支持多種語言构哺,并且推薦使用面向?qū)ο蟮姆绞竭M行編程革答。接下來我們將著重介紹如何使用面向?qū)ο蟮姆绞竭M行編程。

    我們利用 Python 進行面向?qū)ο缶幊淌锴浚枰紫攘私庖粋€概念:類

    • 類是任何面向?qū)ο缶幊痰恼Z言的基本組成残拐,描述了使用的基本方法。我們可能在目前旗扑,還不是特別明白類的含義蹦骑,但是我們可以通過類的使用慈省,來進一步了解臀防。

    • 類的使用

      類眠菇,通過實例化進行使用。比如有一個類: Driver袱衷,該類有一個方法: head(road)

      那么關于這個類的使用捎废,只需要兩個步驟:

      1. 實例化該類:d = Driver()
      2. 調(diào)用類的方法:d.head("中山路")
    • 了解上述例子和使用以后,我們來看具體的 Selenium 的使用致燥。

    ?

  • 具體的對象的使用

    在面向?qū)ο蟮睦砟羁磥淼橇疲魏蔚木幋a,都是由對象而來的嫌蚤,這里也不例外辐益。和之前介紹 WebDriver 時候的描述對應,我們需要用到兩種主要的類脱吱,并將其實例化智政。

    • WebDriver 類:主要靠直接實例化該類為對象,然后用其對象直接調(diào)用該類的方法和屬性
    • WebElement 類:主要通過 WebDriver 類實例化的對象箱蝠,通過對頁面元素的查找续捂,得到 WebElement 類的對象,然后調(diào)用該類的方法和屬性宦搬。

    上述代碼中牙瓢,使用了一個 WebDriver 類 的對象,即第2行间校,聲明了該類的對象矾克,并賦值給變量 driver,接著變量 driver 作為 WebDriver 類的對象撇簿,使用了多個 WebDriver 類的方法聂渊。

    注意:Chrome 是 WebDriver 的子類,是 WebDriver 類的一種

    • get(url): 第5行四瘫,打開網(wǎng)址
    • find_element_by_css_selector(selector): 第12汉嗽、17、22行都使用了該方法找蜜,同時通過對該方法的調(diào)用饼暑,分別各產(chǎn)生了一個 WebElement類的對象,we_account洗做,we_password和最后一個匿名的對象弓叛,并通過產(chǎn)生的三個對象,調(diào)用 WebElement 類的方法
      • clear():清理頁面元素中的文字
      • send_keys(text):給頁面元素中诚纸,輸入新的文字
      • click():鼠標左鍵點擊頁面元素

    正是通過這樣的面向?qū)ο蟮姆绞阶辏a(chǎn)生 Web司機(WebDriver類的對象),并且通過 Web司機不懈的努力畦徘,尋找到各種 Web元素(WebElement類的對象)進行操作毕籽,這樣便實現(xiàn)了 Selenium WebDriver 作為一款出色的瀏覽器測試工具抬闯,進行瀏覽器UI界面的自動化測試的代碼編寫和用例執(zhí)行。

3 T7_自動化測試腳本編寫

3.1 WebDriver 類的使用

通過上述最簡腳本的使用关筒,我們可以來進一步了解 Selenium 的使用溶握。事實上,上一節(jié)用的蒸播,便是 Selenium 的 WebDriver API睡榆。API(Application Programming Interface,應用程序編程接口袍榆,即通過編程語言胀屿,操作 WebDriver 的方法集合)

Selenium WebDriver API 官方參考:http://seleniumhq.github.io/selenium/docs/api/py/

具體API文檔地址:https://seleniumhq.github.io/selenium/docs/api/py/api.html

  • API 使用: 用現(xiàn)成的類(大部分情況)的方法進行編程
    • WebDriver
    • WebElement
  • API 文檔
    • 編程使用說明
    • 介紹了每個方法的使用
      • 方法的作用
      • 方法的參數(shù)
      • 方法的返回值

3.1.1 控制瀏覽器

瀏覽器的控制也是自動化測試的一個基本組成部分,我們可以將瀏覽器最大化包雀,設置瀏覽器的高度和寬度以及對瀏覽器進行導航操作等碉纳。

# 瀏覽器打開網(wǎng)址
driver.get("https://www.baidu.com")

# 瀏覽器最大化
driver.maximize_window()

# 設置瀏覽器的高度為800像素,寬度為480像素
driver.set_window_size(480, 800)

# 瀏覽器后退
driver.back()

# 瀏覽器前進
driver.forward()

# 瀏覽器關閉
driver.close()

# 瀏覽器退出
driver.quit()

3.1.2 元素定位操作

WebDriver提供了一系列的定位符以便使用元素定位方法馏艾。常見的定位符有以下幾種:

  • id
  • name
  • class name
  • tag
  • link text
  • partial link text
  • xpath
  • css selector

那么我們以下的操作將會基于上述的定位符進行定位操作劳曹。

對于元素的定位,WebDriver API可以通過定位簡單的元素和一組元素來操作琅摩。在這里铁孵,我們需要告訴Selenium如何去找元素,以至于他可以充分的模擬用戶行為房资,或者通過查看元素的屬性和狀態(tài)蜕劝,以便我們執(zhí)行一系列的檢查。

在Selenium2中轰异,WebDriver提供了多種多樣的find_element_by方法在一個網(wǎng)頁里面查找元素岖沛。這些方法通過提供過濾標準來定位元素。當然WebDriver也提供了同樣多種多樣的find_elements_by的方式去定位多個元素搭独。

盡管上述的方式婴削,可以進行元素定位,實際上我們也是更多的用組合的方式進行元素定位牙肝。

依據(jù)ID查找

請查看如下HTML的代碼唉俗,以便實現(xiàn)通過ID的屬性值去定義一個查找文本框的查找:

<input id="search" type="text" name="q" value=""
       class="input-text" maxlength="128" autocomplete="off"/>

根據(jù)上述代碼,這里我們使用find_element_by_id()的方法去查找搜索框并且檢查它的最大長度maxlength屬性配椭。我們通過傳遞ID的屬性值作為參數(shù)去查找虫溜,參考如下的代碼示例:

def test_search_text_field_max_length(self):
    # get the search textbox
    search_field = self.driver.find_element_by_id("search")
    # check maxlength attribute is set to 128
    self.assertEqual("128", search_field.get_attribute("maxlength"))

如果使用find_elements_by_id()方法,將會返回所有的具有相同ID屬性值的一系列元素股缸。

依據(jù)名稱name查找

這里還是根據(jù)上述ID查找的HTML代碼衡楞,使用find_element_by_name的方法進行查找。參考如下的代碼示例:

# get the search textbox
self.search_field = self.driver.find_element_by_name("q")

同樣敦姻,如果使用find_elements_by_name()方法瘾境,將會返回所有的具有相同name屬性值的一系列元素坎背。

依據(jù)class name查找

除了上述的ID和name的方式查找,我們還可以使用class name的方式進行查找和定位寄雀。

事實上,通過ID陨献,name或者類名class name查找元素是最提倡推薦的和最快的方式盒犹。當然Selenium2 WebDriver也提供了一些其他的方式,在上述三類方式條件不足眨业,查找無效的時候急膀,可以通過這些其他方式來查找。這些方式將會在后續(xù)的內(nèi)容中講述龄捡。

請查看如下的HTML代碼卓嫂,通過改代碼進行練習和理解.

<button type="submit" title="Search" class="button">
  <span><span>Search</span></span>
</button>

根據(jù)上述代碼,使用find_element_by_class_name()方法去定位元素聘殖。

def test_search_button_enabled(self):
    # get Search button
    search_button = self.driver.find_element_by_class_name("button")
    # check Search button is enabled
    self.assertTrue(search_button.is_enabled())

同樣的如果使用find_elements_by_class_name()方法去定位元素晨雳,將會返回所有的具有相同name屬性值的一系列元素。

依據(jù)標簽名tag name查找

利用標簽的方法類似于利用類名等方法進行查找奸腺。我們可以輕松的查找出一系列的具有相同標簽名的元素餐禁。例如我們可以通過查找表中的<tr>來獲取行數(shù)。

下面有一個HTML的示例突照,這里在無序列表中使用了<img>標簽帮非。

<ul class="promos">
    <li>
        <a >
            <img src="/media/wysiwyg/homepage-three-column-promo-
        01B.png" alt="Physical &amp; Virtual Gift Cards">
        </a>
    </li>
    <li>
        <a >
            <img src="/media/wysiwyg/homepage-three-column-promo-
        02.png" alt="Shop Private Sales - Members Only">
        </a>
    </li>
    <li>
        <a href="http://demo.magentocommerce.com/accessories/
        bags-luggage.html">
            <img src="/media/wysiwyg/homepage-three-columnpromo-
        03.png" alt="Travel Gear for Every Occasion">
        </a>
    </li>
</ul>

這里面我們使用find_elements_by_tag_name()的方式去獲取全部的圖片,在此之前讹蘑,我們將會使用find_element_by_class_name()去獲取到指定的<ul>末盔。

具體代碼如下:

def test_count_of_promo_banners_images(self):
    # get promo banner list
    banner_list = self.driver.find_element_by_class_name("promos")
    # get images from the banner_list
    banners = banner_list.find_elements_by_tag_name("img")
    # check there are 20 tags displayed on the page
    self.assertEqual(20, len(banners))
依據(jù)鏈接文字link查找

鏈接文字查找通常比較簡單。使用find_element_by_link_text請查看以下示例

<a href="#header-account" class="skip-link skip-account">
    <span class="icon"></span>
    <span class="label">ACCOUNT Description</span>
</a>

測試代碼如下:

def test_my_account_link_is_displayed(self):
    # get the Account link
    account_link =
    self.driver.find_element_by_link_text("ACCOUNT Description")
    # check My Account link is displayed/visible in
    # the Home page footer
    self.assertTrue(account_link.is_displayed())
依據(jù)部分鏈接文字partial text查找

這里依舊使用上述的列子進行代碼編寫:

def test_account_links(self):
    # get the all the links with Account text in it
    account_links = self.driver.\
    find_elements_by_partial_link_text("ACCOUNT")
    # check Account and My Account link is
    # displayed/visible in the Home page footer
    self.assertTrue(2, len(account_links)) 
依據(jù)XPath進行查找

XPath是一種在XML文檔中搜索和定位節(jié)點node的一種查詢語言座慰。所有的主流Web瀏覽器都支持XPath陨舱。Selenium2可以用強大的XPath在頁面中查找元素。

常用的XPath的方法有starts-with()版仔,contains()ends-with()

若想要了解更多關于XPath的內(nèi)容隅忿,請查看http://www.w3schools.com/XPath/

如下有一段HTML代碼,其中里面的<img>沒有使用ID邦尊,name或者類屬性背桐,所以我們無法使用之前的方法。亞這里我們可以通過<img>alt屬性蝉揍,定位到指定的tag链峭。

<ul class="promos">
    <li>
        <a >
            <img src="/media/wysiwyg/homepage-three-column-promo-
        01B.png" alt="Physical &amp; Virtual Gift Cards">
        </a>
    </li>
    <li>
        <a >
            <img src="/media/wysiwyg/homepage-three-column-promo-
        02.png" alt="Shop Private Sales - Members Only">
        </a>
    </li>
    <li>
        <a href="http://demo.magentocommerce.com/accessories/
        bags-luggage.html">
            <img src="/media/wysiwyg/homepage-three-columnpromo-
        03.png" alt="Travel Gear for Every Occasion">
        </a>
    </li>
</ul>

具體代碼如下:

def test_vip_promo(self):
    # get vip promo image
    vip_promo = self.driver.\
    find_element_by_xpath("http://img[@alt='Shop Private Sales - Members Only']")
    # check vip promo logo is displayed on home page
    self.assertTrue(vip_promo.is_displayed())
    # click on vip promo images to open the page
    vip_promo.click()
    # check page title
    self.assertEqual("VIP", self.driver.title)

當然,如果使用find_elements_by_xpath()的方法又沾,將會返回所有匹配了XPath查詢的元素弊仪。

依據(jù)CSS選擇器進行查找

CSS是一種設計師用來描繪HTML文檔的視覺的層疊樣式表熙卡。一般來說CSS用來定位多種多樣的風格,同時可以用來是同樣的標簽使用同樣的風格等励饵。類似于XPath驳癌,Selenium2也可以使用CSS選擇器來定位元素。

請查看如下的HTML文檔役听。

<div class="minicart-wrapper">
    <p class="block-subtitle">Recently added item(s)
        <a class="close skip-link-close" href="#" title="Close">×</a>
    </p>
    <p class="empty">You have no items in your shopping cart.
    </p>
</div>

我們來創(chuàng)建一個測試颓鲜,驗證這些消息是否正確。

def test_shopping_cart_status(self):
    # check content of My Shopping Cart block on Home page
    # get the Shopping cart icon and click to open the
    # Shopping Cart section
    shopping_cart_icon = self.driver.find_element_by_css_selector("div.header-minicart\
                                 span.icon")
    shopping_cart_icon.click()
    # get the shopping cart status
    shopping_cart_status = self.driver.find_element_by_css_selector("p.empty").text
    self.assertEqual("You have no items in your shopping cart.", shopping_cart_status)
    # close the shopping cart section
    close_button = self.driver.find_element_by_css_selector("div.minicart-wrapper a.close")
    close_button.click()
特殊 iframe 操作

iframe 元素會創(chuàng)建包含另外一個文檔的內(nèi)聯(lián)框架(即行內(nèi)框架)典予。

iframe: 紫禁城

在一個<html>中甜滨,包含了另一個<html>

示例

<html>
  <head>
    <title>iframe示例</title>
  </head>
  <body>
    <h1>
      這里是H1,標記了標題
    </h1>
    <p>
      這里是段落瘤袖,標記一個段落衣摩,屬于外層
    </p>
    <div>
      <iframe id="iframe-1">
        <html>
          <body>
            <p>
              這里是個段落,屬于內(nèi)層捂敌,內(nèi)聯(lián)框架中的
            </p>
            <div id="div-1">
              <p class="hahahp">
                這里是div中的段落艾扮,需要被定位
              </p>
            </div>
          </body>
        </html>
      </iframe>
    </div>
  </body>
</html>

需要定位上面示例中的<p>:這里是div中的段落,需要被定位

如下是selenium WebDiriver的代碼

## 查找并定位 iframe
element_frame = driver.find_element_by_css_selector('#iframe-1')
## 切換到剛剛查找到的 iframe
driver.switch_to.frame(element_frame)
## 定位 <p>
driver.find_element_by_css_selector('#div-1 > p')
## TODO....
## 退出剛剛切換進去的 iframe
driver.switch_to.default_content()
特殊 Select 操作

<select> 是選擇列表

Select 是個selenium的類selenium.webdriver.support.select.Select

Select 類的路徑:

C:\Python35\Lib\site-packages\selenium\webdriver\support\select.py

<select id="brand">
  <option value ="volvo">Volvo</option>
  <option value ="saab">Saab</option>
  <option value="opel">Opel</option>
  <option value="audi">Audi</option>
</select>

示例占婉,選擇 Audi

## 查找并定位到 select
element_select = driver.find_element_by_css_selector('#brand')
## 用Select類的構(gòu)造方法栏渺,實例化一個對象 object_select
object_select = Select(element_select)
## 操作 object_select
object_select.select_by_index(3)
## 也可以這樣
object_select.select_by_value('audi')
## 還可以這樣
object_select.select_by_visible_text('Audi')
組合操作

自動化經(jīng)驗的積累,需要100%按照手工的步驟進行操作锐涯。

比如步驟如下:

  1. 點擊一個 <a id="customer_chosen">
  2. 自動產(chǎn)生了一個 <ul id="customer_list">
  3. 點擊<ul>的第五個<li>

代碼示例

driver.find_element_by_css_selector('#customer_chosen').click()
sleep(1)
driver.find_element_by_css_selector('#customer_list > li:nth-child(5)')

3.1.3 鼠標事件操作

Web測試中磕诊,有關鼠標的操作,不只是單擊纹腌,有時候還要做右擊霎终、雙擊、拖動等操作升薯。這些操作包含在ActionChains類中莱褒。

常用的鼠標方法:

  • context_click() # 右擊
  • double_click() # 雙擊
  • drag_and_drop() # 拖拽
  • move_to_element() # 鼠標停在一個元素上
  • click_and_hold() # 按下鼠標左鍵在一個元素上

例子:

# 方法模擬鼠標右鍵,參考代碼如下:
# 引入ActionChains 類
from selenium.webdriver.common.action_chains import ActionChains
...
# 定位到要右擊的元素
right =driver.find_element_by_xpath("xx")
# 對定位到的元素執(zhí)行鼠標右鍵操作
ActionChains(driver).context_click(right).perform()
...
# 定位到要雙擊的元素
double = driver.find_element_by_xpath("xxx")
# 對定位到的元素執(zhí)行鼠標雙擊操作
ActionChains(driver).double_click(double).perform()

3.1.4 鍵盤事件操作

鍵盤操作經(jīng)常處理的如下:

代碼 描述
send_keys(Keys.BACKSPACE) 刪除鍵(BackSpace)
send_keys(Keys.SPACE) 空格鍵(Space)
send_keys(Keys.TAB) 制表鍵(Tab)
send_keys(Keys.ESCAPE) 回退鍵(Esc)
send_keys(Keys.ENTER) 回車鍵(Enter)
send_keys(Keys.CONTROL,'a') 全選(Ctrl+A)
send_keys(Keys.CONTROL,'c') 復制(Ctrl+C)

代碼如下

from selenium import webdriver

# 引入Keys 類包
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

# 輸入框輸入內(nèi)容
driver.find_element_by_id("kw").send_keys("selenium")
time.sleep(3)

# 刪除多輸入的一個m
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
time.sleep(3)

# 輸入空格鍵+“教程”
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
driver.find_element_by_id("kw").send_keys("教程")
time.sleep(3)

# ctrl+a 全選輸入框內(nèi)容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')

3.1.5 截圖操作

截圖的方法:save_screenshot(file)

3.2 單元測試框架的引入

在上一節(jié)涎劈,我們對 Selenium WebDriver 的使用广凸,僅僅停留在讓網(wǎng)頁自動的進行操作的階段,并沒有對任何一個步驟進行“檢查”蛛枚。當然谅海,這樣沒有“檢查”的操作,實際上是沒有測試意義的蹦浦。那么第一項扭吁,我們需要解決的便是“檢查”的問題。

所謂“檢查”,實際上就是斷言侥袜。對需要檢查的步驟操作蝌诡,通過對預先設置的期望值,和執(zhí)行結(jié)果的實際值之間的對比枫吧,得到測試的結(jié)果浦旱。在這里,我們并不需要單獨的寫 if 語句進行各種判定九杂,而是可以使用編程語言中對應的單元測試框架颁湖,即可解決好此類問題。

目前 Java 語言主流的單元測試框架有 JUnit 和 TestNG尼酿。Python 語言主流的單元測試框架有 unittest 。本小節(jié)的內(nèi)容植影,主要介紹 unittest 的使用裳擎,探討單元測試框架如何幫助自動化測試。

接下來我們將會使用 Python 語言的unittest框架展開“檢查”思币。unittest框架的原本的名字是PyUnit鹿响。是從JUnit 這樣一個被廣泛使用的 經(jīng)典的Java應用開發(fā)的單元測試框架創(chuàng)造而來。類似的框架還有NUnit(.Net開發(fā)的單元測試框架)等谷饿。我們可以使用unittest框架為任意Python項目編寫可理解的單元測試集合』涛遥現(xiàn)在這個unittest已經(jīng)作為Python的標準庫模塊發(fā)布。我們安裝完Python以后博投,便可以直接使用unittest绸贡。

使用unittest需要以下簡單的三步:

  • 引入unittest模組
  • 繼承unittest.TestCase基類
  • 測試方法以test開頭

unittest 并未使用 Java 語言常見的注解方式,依舊停留在 比較早期的 Java 版本中依靠方法名稱進行識別的方式毅哗。主要有以下兩個固定名字的方法:

  • setUp():在每個測試方法運行前听怕,執(zhí)行。是測試前置條件虑绵。
  • tearDown():在每個測試方法運行后執(zhí)行尿瞭,是測試清理操作。

具體的代碼如下:

## 引入unittest模組
import unittest

## 定義測試類翅睛,名字為DemoTests
## 該類必須繼承unittest.TestCase基類
class DemoTests(unittest.TestCase):

    ## 使用'@'修飾符声搁,注明該方法是類的方法
    ## setUpClass方法是在執(zhí)行測試之前需要先調(diào)用的方法
    ## 是開始測試前的初始化工作
    @classmethod
    def setUpClass(cls):
        print("call setUpClass()")
    
    ## 每一個測試開始前的預置條件
    def setUp(self):
        print("call setUp()")
        
    ## 每一個測試結(jié)束以后的清理工作
    def tearDown(self):
        print("call tearDown()")

    ## 測試一(務必以test開頭)
    def test_01(self):
        print("call test_01()")
        pass

    ## 測試三(務必以test開頭)
    def test_02(self):
        print("call test_02()")
        pass

    ## 測試三(務必以test開頭)
    def test_03(self):
        print("call test_03()")
        pass

    ## tearDownClass方法是執(zhí)行完所有測試后調(diào)用的方法
    ## 是測試結(jié)束后的清除工作
    @classmethod
    def tearDownClass(cls):
        print("call tearDownClass()")

# 執(zhí)行測試主函數(shù)
if __name__ == '__main__':
    ## 執(zhí)行main全局方法,將會執(zhí)行上述所有以test開頭的測試方法
    unittest.main(verbosity=2)

需要注意步驟:

  1. 引入 unittest 模組
  2. 繼承 unittest.TestCase 類
  3. 做測試用例的方法捕发,方法以 test_ 開頭
    1. 附加 setUp(), tearDown(), 在每個 test_ 方法執(zhí)行前后 進行執(zhí)行
    1. 附加 setUpClass(), tearDownClass()
      需要在 類實例化的對象疏旨,運行的開頭和結(jié)尾進行執(zhí)行。
      加了星號(*)的步驟扎酷,可以不用充石。

上述代碼運行結(jié)果如下:

call setUpClass()
call setUp()
call test_01()
call tearDown()
call setUp()
call test_02()
call tearDown()
call setUp()
call test_06()
call tearDown()
call tearDownClass()
  • unittest 的斷言配置使用

    unittest 的斷言,屬于 TestCase類,只要繼承了該類骤铃,均可以通過 self調(diào)用斷言

    方法 Method 檢查條件
    assertEqual(a, b [, msg]) a == b拉岁,msg可選,用來解釋失敗的原因
    assertNotEqual(a, b [, msg] a != b惰爬,msg可選喊暖,用來解釋失敗的原因
    assertTrue(x [, msg]) x 是真,msg可選撕瞧,用來解釋失敗的原因
    assertFalse(x [, msg]) x 是假陵叽,msg可選,用來解釋失敗的原因
    assertIsNot(a, b [, msg]) a 不是 b丛版,msg可選巩掺,用來解釋失敗的原因

3.3 測試用例類的編寫

這里,我們需要結(jié)合 unittest 與 WebDriver 來一起編寫 測試用例的類页畦。

  • WebDriver 的實例化放到 setUp() 里面實現(xiàn)
  • WebDriver 實例化的對象的退出胖替,放到 tearDown() 里面實現(xiàn)
  • 測試的步驟與斷言,放到 test_ 開頭的方法里

參考一個例子豫缨。

from time import sleep
from selenium import webdriver
import unittest

class RanzhiTest(unittest.TestCase):
    """
    用例 [rzat01]  系統(tǒng)登錄模塊能接受不同的語言和不同類型的用戶在有效和無效范圍內(nèi)登錄独令。
    """

    base_url = None
    main_page = None

    def set_up(self):
        """
        測試前置條件
        :param **kwargs:
        :return:
        """
        self.base_driver = webdriver.Chrome()
        self.base_url = "http://localhost/ranzhi/www/"

    def tear_down(self):
        """
        測試清理條件
        :return:
        """
        self.base_driver.quit()

    def test_01(self):
        """
        測試有效和無效用戶登錄
        :return:
        """
        account = "admin"
        password = "123456"
        
        self.base_driver.get(self.base_url)
        sleep(2)
        
        we_account = self.base_driver.find_element_by_id("account")
        we_account.clear()
        we_account.send_keys(account)
        
        we_password = self.base_driver.find_element_by_id("password")
        we_account.clear()
        we_account.send_keys(password)
        
        self.base_driver.find_element_by_id("submit").click()
        sleep(2)
        
        expected_url = self.base_url + "sys/index.html"
        actual_url = self.base_driver.get_url()
        self.assertEqual(expected_url, actual_url, "有效登錄用戶[%s]登錄失敗或者登錄后跳轉(zhuǎn)錯誤!" % account)
六天入門軟件測試系列課程總綱
  • 相關學習

立師兄Linty:六天入門軟件測試①——測試執(zhí)行講義

立師兄Linty:六天入門軟件測試①——測試執(zhí)行筆記

立師兄Linty:六天入門軟件測試②——測試分析講義

立師兄Linty:六天入門軟件測試②——測試分析筆記

立師兄Linty:六天入門軟件測試③——測試設計講義

立師兄Linty:六天入門軟件測試③——測試設計筆記

立師兄Linty:六天入門軟件測試④——測試腳本講義

立師兄Linty:六天入門軟件測試④——測試腳本筆記

立師兄Linty:六天入門軟件測試⑤——測試編程講義

立師兄Linty:六天入門軟件測試⑤——測試編程筆記

立師兄Linty:六天入門軟件測試⑥——測試報告講義

立師兄Linty:六天入門軟件測試⑥——測試報告筆記

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末好芭,一起剝皮案震驚了整個濱河市燃箭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舍败,老刑警劉巖招狸,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異邻薯,居然都是意外死亡瓢颅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進店門弛说,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挽懦,“玉大人,你說我怎么就攤上這事木人⌒攀粒” “怎么了?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵醒第,是天一觀的道長渔嚷。 經(jīng)常有香客問我,道長稠曼,這世上最難降的妖魔是什么形病? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上漠吻,老公的妹妹穿的比我還像新娘量瓜。我一直安慰自己,他們只是感情好途乃,可當我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布绍傲。 她就那樣靜靜地躺著,像睡著了一般耍共。 火紅的嫁衣襯著肌膚如雪烫饼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天试读,我揣著相機與錄音杠纵,去河邊找鬼。 笑死钩骇,一個胖子當著我的面吹牛比藻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播伊履,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼韩容,長吁一口氣:“原來是場噩夢啊……” “哼款违!你這毒婦竟也來了唐瀑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤插爹,失蹤者是張志新(化名)和其女友劉穎哄辣,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赠尾,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡力穗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了气嫁。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片当窗。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖寸宵,靈堂內(nèi)的尸體忽然破棺而出崖面,到底是詐尸還是另有隱情,我是刑警寧澤梯影,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布巫员,位于F島的核電站,受9級特大地震影響甲棍,放射性物質(zhì)發(fā)生泄漏简识。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望七扰。 院中可真熱鬧奢赂,春花似錦、人聲如沸戳寸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疫鹊。三九已至袖瞻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拆吆,已是汗流浹背聋迎。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留枣耀,地道東北人霉晕。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像捞奕,于是被迫代替她去往敵國和親牺堰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容