使用Python学习selenium测试工具

快速入门

Selenium是一个简便的Web应用软件测试工具。Selenium的组件Selenium IDE支持录制/回放。它还支持Python,Java,C#,javascript等语言。支持Windows,Linux和Macintosh。它是 开源软件,根据Apache2.0许可证发布的,并可以下载并无偿使用。

历史

Selenium来源于由杰森·哈金斯 (Jason Huggins)在2004年在ThoughtWorks的开发内部工具,后面有ThoughtWorks的其他程序员和测试人员在 ThoughtWorks加入。后来Paul Hammant加入开发了'Selenium Remote Control' (RC)并开源。

2005年Dan Fabulich和Nelson Sproul在Pat Lightbody的帮助下给Selenium-RC做了一些补丁。同时ThoughtWorks在Huggins和Hammant代表的情况下组建了Selenium委员会。

2007 年哈金斯和Jennifer Bevan等加盟谷歌。他继续Selenium RC的开发和稳定。与此同时,西蒙·斯图尔特(Simon Stewart)在ThoughtWorks开发出了卓越的浏览器自动化工具webdriver。2009年在谷歌测试自动化大会上决定合并两个项目,新 项目叫Selenium WebDriver,即Selenium 2.0。

2008年,ThoughtWorks的Philippe Hanrigou开发了'Selenium Grid',支持同时在任意数量的本地或远程系统执行多个Selenium测试,从而减少测试执行时间。Selenium Grid提供类似谷歌内部Selenium RC云项目的功能,但是它是开源的。Pat Lightbody也开发了一个类似的私有云:'HostedQA',并卖给了Gomez公司。

当时有个类似的软件叫Mercury,及汞,哈金斯就取名为硒,可以通过服用硒补充剂治愈汞中毒。

组件

支持浏览器: Firefox、Internet Explorer、Google Chrome、Safari和Opera。

支持操作系统:Linux, Windows和Mac OS X。

  • Selenium IDE

Selenium IDE是Selenium测试完整的集成开发环境(IDE)。它是Firefox插件,并允许录制,编辑和调试。这是以前被称为Selenium Recorder,最初是由Shinya Kasatani开发并于2006年捐赠给Selenium。

脚本会自动录制,可以事后编辑,编辑时可以自动完成并快速移动命令。脚本记录在Selenese的(Selenium特殊的测试脚本语言)。Selenese可以在浏览器中执行操作命令(如点击链接,选择选项),并从网页中检索数据。

  • Selenium client API

目前支持Python, Java,C#,Ruby。

  • Selenium Remote Control(webdriver已经弃用)

Selenium Remote Control (RC)是Java编写的服务,通过HTTP接收浏览器的命令(类似代理服务器)。RC支持多种编程语言对Web应用进行测试,方便集成进语言的单元测试 框架。支持PHP,Python和Ruby,.NET,Perl和Java客户端驱动程序。java驱动通过Rhino engine支持JavaScript。一个端口只支持一个实例,但是Java/PHP中一个端口可以支持多个实例。RC来源于Paul Hammant和Jason。

Selenium Remote Control来源于Paul Hammant的Driven Selenium或Selenium B。最初的版本直接在编程语言中启动进程和浏览器交互,Selenese在各种语言中实现。Dan Fabulich和Nelson Sproul在Pat Lightbody的帮助下改进后,测试脚本和和浏览器之间增加了守护进程,这样就可以驱动远程浏览器,并只需要维护一套Selenese语言。2006 年RC完全替代Driven Selenium。RC和Driven Selenium浏览器模式是响应/请求,即Comet。

Selenium 2发布时,已经建议用webdriver替代RC。

  • Selenium WebDriver:

Selenium WebDriver是RC的替代。它接受命令(Selenese或者API),并发送给浏览器。调用特定浏览器的驱动,发送命令到浏览器,并获取结果。多 数浏览器驱动启动和访问浏览器应用程序(如Firefox或Internet Explorer);另外还有浏览器的HtmlUnit驱动程序,它用模拟使用浏览器。

Selenium WebDrive不需要特殊的服务器来执行测试。webdriver直接启动浏览器实例并控制它。Selenium Grid可以用于的webdriver执行远程测试。

2012 年初,Simon Stewart(webdriver的发明者,当时在google工作,现在在Facebook)和Mozilla的David Burns与W3C协商将WebDriver作为互联网标准。2013年初草案发布,Selenium-Webdriver为参考实现。目前 Selenium-WebDriver在Python和Ruby,Java和C#有完整的支持。

  • Selenium Grid(Selenium standalone server)

Selenium Grid是允许在远程机器上运行的Web浏览器实例的服务。Selenium Grid允许运行测试在多台计算机上并行,以及管理的不同版本的浏览器和浏览器配置。甚至支持移动操作系统:Android和Apple iOS。

参考资料

  • 讨论qq群144081101 591302926 567351477 钉钉免费群21745728

快速入门

Selenium WebDriver python client可以访问Selenium WebDriver和Selenium standalone server,开发人员:David Burns, Adam Goucher, Maik Röder,Jason Huggins, Luke Semerau, Miki Tebeka和Eric Allenin。支持python版本2.6, 2.7, 3.2和3.3。

安装:

pip install -U selenium

需要选择一个合适IDE,要求如下:

  • 代码完成和智能提示的图形化代码编辑器

  • 函数和类的代码浏览器

  • 语法高亮

  • 项目管理

  • 代码模板

  • 单元测试和调试

  • 源代码控制支持

推荐:WingIDE,PyCharm,PyDev Eclipse plugin,PyScripter。相关下载地址如下:

实例1:在网站python自动化测试上面寻找webdriver相关的页面,并输出相关的网址:

注意:本实例因为http://automationtesting.vipsinaapp.comhttp://automationtesting.sinaapp.com已经因为新浪收费原因关闭匿名用户查询,已经不能执行。

#!/usr/bin/env python
# encoding: utf-8
import time

from selenium import webdriver

# create a new Firefox session
driver = webdriver.Firefox()
driver.implicitly_wait(30)
driver.maximize_window()

# navigate to the application home page
driver.get("http://automationtesting.sinaapp.com/")

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

# enter search keyword and submit
search_field.send_keys("webdriver")
search_field.submit()



time.sleep(6)
products = driver.find_elements_by_xpath("//a[@class='searchable']")
# get the number of anchor elements found
print "Found " + str(len(products)) + " pages:"

# iterate through each anchor element and
# print the text that is name of the product
for product in products:
    print product.get_attribute('href')

# close the browser window
driver.quit()

selenium.webdriver实现了浏览器驱动类,涉及 Firefox, Chrome, Internet Explorer, Safari等浏览器及用于测试远程机器的类RemoteWebDriver。

driver.implicitly_wait(30)表示最多等待页面打开的时间为30秒。

执行结果:

Found 2 pages:
http://automationtesting.sinaapp.com/blog/python_selenium1
http://automationtesting.sinaapp.com/blog/appium

实例2打开网址,搜索产品,并列出产品名。实例的网站为:magentocommerce,代码下载地址:learnsewithpython

注意:上面演示的网址可能需要翻墙

from selenium import webdriver

# create a new Firefox session
driver = webdriver.Firefox()
driver.implicitly_wait(30)
driver.maximize_window()

# navigate to the application home page
driver.get("http://demo.magentocommerce.com/")

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

# enter search keyword and submit
search_field.send_keys("phones")
search_field.submit()

# get all the anchor elements which have product names displayed
# currently on result page using find_elements_by_xpath method
products = driver.find_elements_by_xpath("//h2[@class='product-name']/a")

# get the number of anchor elements found
print "Found " + str(len(products)) + " products:"

# iterate through each anchor element and
# print the text that is name of the product
for product in products:
    print product.text

# close the browser window
driver.quit()

执行结果:

Found 2 products:
MADISON EARBUDS
MADISON OVEREAR HEADPHONES

跨浏览器支持

IE

selenium下载页面地址。为了在Internet Explorer上面执行,需要下载配置InternetExplorerDriver服务,它是测试脚本和Internet Explorer之间的胶水。

在上述下载页面搜索InternetExplorerDriver,下载32位或者64位版本,并解压到合适的目录。在IE7以上的版本,选择Tools 菜单下面的Internet Options,在弹出窗口选择Security标签,把每个zone的Protected Mode设置为关或者开启的情况都设置为中。另外要特别注意IE的缩放要选择为100%才正确地进行坐标对应。

实例1:

#!/usr/bin/env python
# encoding: utf-8
import time

from selenium import webdriver

ie_driver_path = "e:\IEDriverServer.exe"

# create a new Firefox session
driver = webdriver.Ie(ie_driver_path)
driver.implicitly_wait(30)
driver.maximize_window()

# navigate to the application home page
driver.get("http://automationtesting.sinaapp.com/")

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

# enter search keyword and submit
search_field.send_keys("webdriver")
search_field.submit()



time.sleep(6)
products = driver.find_elements_by_xpath("//a[@class='searchable']")
# get the number of anchor elements found
print "Found " + str(len(products)) + " pages:"

# iterate through each anchor element and
# print the text that is name of the product
for product in products:
    print product.get_attribute('href')

# close the browser window
driver.quit()

实例2:

import os
from selenium import webdriver

# get the path of IEDriverServer
# dir = os.getcwd()
ie_driver_path = "e:\IEDriverServer.exe"

# create a new Internet Explorer session

driver = webdriver.Ie(ie_driver_path)
driver.implicitly_wait(30)
driver.maximize_window()

# navigate to the application home page
driver.get("http://demo.magentocommerce.com/")

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

# enter search keyword and submit
search_field.send_keys("phones")
search_field.submit()

# get all the anchor elements which have product names displayed
# currently on result page using find_elements_by_xpath method
products = driver.find_elements_by_xpath("//h2[@class='product-name']/a")

# get the number of anchor elements found
print "Found " + str(len(products)) + " products:"

# iterate through each anchor element and
# print the text that is name of the product
for product in products:
    print product.text

# close the browser window
driver.quit()

执行结果和火狐的类似。

参考资料:

Chrome

ChromeDriver由Chromium开发,安装方法和IE的类似,但是不需要设置Protected Mode。 实例1:

#!/usr/bin/env python
# encoding: utf-8
import time

from selenium import webdriver

# get the path of chromedriver
chrome_driver_path = r"e:\chromedriver.exe"
#remove the .exe extension on linux or mac platform

# create a new Chrome session
driver = webdriver.Chrome(chrome_driver_path)
driver.implicitly_wait(30)
driver.maximize_window()

# navigate to the application home page
driver.get("http://automationtesting.sinaapp.com/")

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

# enter search keyword and submit
search_field.send_keys("webdriver")
search_field.submit()



time.sleep(6)
products = driver.find_elements_by_xpath("//a[@class='searchable']")
# get the number of anchor elements found
print "Found " + str(len(products)) + " pages:"

# iterate through each anchor element and
# print the text that is name of the product
for product in products:
    print product.get_attribute('href')

# close the browser window
driver.quit()

实例2:

import os
from selenium import webdriver

# get the path of chromedriver
chrome_driver_path = r"e:\chromedriver.exe"
#remove the .exe extension on linux or mac platform

# create a new Chrome session
driver = webdriver.Chrome(chrome_driver_path)
driver.implicitly_wait(30)
driver.maximize_window()

# navigate to the application home page
driver.get("http://demo.magentocommerce.com/")

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

# enter search keyword and submit
search_field.send_keys("phones")
search_field.submit()

# get all the anchor elements which have product names displayed
# currently on result page using find_elements_by_xpath method
products = driver.find_elements_by_xpath("//h2[@class='product-name']/a")

# get the number of anchor elements found
print "Found " + str(len(products)) + " products:"

# iterate through each anchor element and
# print the text that is name of the product
for product in products:
    print product.text

# close the browser window
driver.quit()

参考资料:

在unittest中使用

unittest可以为webdriver增加setup、teardown、检查应用状态、报告测试结果、数据驱动等功能。主要内容如下:

  • 什么是unittest?

  • 使用unittest来编写webDriver测试

  • 基于TestCase类实现测试

  • 理解各种类型的assert方法

  • 创建一组测试为TestSuite

  • 使用unittest扩展生成HTML格式的测试报告

unittest库

主要组成如下:

  • Test Fixture:准备及清理工作。

  • Test Case: 通常是使用assert方法检查动作和输入的响应,一般是基于TestCase类扩充。

  • Test Suite:多个测试的集合。

  • Test Runner:测试执行。

  • Test Report:测试报告。

测试通常由3A组成:

  • Arrange:预置条件、相关配置和依赖等。

  • Act:实际功能。

  • Assert:断言。

其他框架有Pytest和Nose等。

TestCase类

测试方法以test_开头

import unittest
from selenium import webdriver

class SearchTests(unittest.TestCase):
    def setUp(self):
        # create a new Firefox session
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.driver.maximize_window()

        # navigate to the application home page
        self.driver.get("http://demo.magentocommerce.com/")

    def test_search_by_category(self):
        # get the search textbox
        self.search_field = self.driver.find_element_by_name("q")
        self.search_field.clear()

        # enter search keyword and submit
        self.search_field.send_keys("phones")
        self.search_field.submit()

        # get all the anchor elements which have product names displayed
        # currently on result page using find_elements_by_xpath method
        products = self.driver\            .find_elements_by_xpath("//h2[@class='product-name']/a")
        self.assertEqual(2, len(products))

    def test_search_by_name(self):
        # get the search textbox
        self.search_field = self.driver.find_element_by_name("q")
        self.search_field.clear()

        # enter search keyword and submit
        self.search_field.send_keys("salt shaker")
        self.search_field.submit()

        # get all the anchor elements which have product names displayed
        # currently on result page using find_elements_by_xpath method
        products = self.driver.\
            find_elements_by_xpath("//h2[@class='product-name']/a")
        self.assertEqual(1, len(products))

    def tearDown(self):
        # close the browser window
        self.driver.quit()
        
if __name__ == '__main__':
    unittest.main(verbosity=2)

执行结果:

# python searchtests.py
test_search_by_category (__main__.SearchTests) ... ok
test_search_by_name (__main__.SearchTests) ... ok
----------------------------------------------------------------------
Ran 2 tests in 138.375s

OK

基于类的setUp()和tearDown()方法

上面每个用例都会初始化和清理一次,有时这不一定是必要的。@classmethod支持在一个类中只进行一次初始化和清理。

import unittest
from selenium import webdriverclass 

SearchTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # create a new Firefox session
        cls.driver = webdriver.Firefox()
        cls.driver.implicitly_wait(30)
        cls.driver.maximize_window()

        # navigate to the application home page
        cls.driver.get("http://demo.magentocommerce.com/")
        cls.driver.title    
        
    def test_search_by_category(self):
        # get the search textbox
        self.search_field = self.driver.find_element_by_name("q")
        self.search_field.clear()

        # enter search keyword and submit
        self.search_field.send_keys("phones")
        self.search_field.submit()

        # get all the anchor elements which have product names displayed
        # currently on result page using find_elements_by_xpath method
        products = self.driver.\
            find_elements_by_xpath("//h2[@class='product-name']/a")
        self.assertEqual(2, len(products))

    def test_search_by_name(self):
        # get the search textbox
        self.search_field = self.driver.find_element_by_name("q")
        self.search_field.clear()

        # enter search keyword and submit
        self.search_field.send_keys("salt shaker")
        self.search_field.submit()

        # get all the anchor elements which have product names displayed
        # currently on result page using find_elements_by_xpath method
        products = self.driver.\
            find_elements_by_xpath("//h2[@class='product-name']/a")
        self.assertEqual(1, len(products))

    @classmethod
    def tearDownClass(cls):
        # close the browser window
        cls.driver.quit()
        
if __name__ == '__main__':
    unittest.main(verbosity=2)

断言

断言有3种类型:相等、逻辑比较、异常。如果断言不通过,当前测试用例会停止,并报错。详细的断言参见unittest

另外fail()可以无条件让用例失败。

测试用例集(Test suites)

通过TestSuite, TestLoader和TestRunner可以有效地组织测试用例集。

先添加文件homepagetests.py,演示上面部分断言。

import unittest
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from __builtin__ import classmethod


class HomePageTest(unittest.TestCase):
    @classmethod
    def setUp(cls):
        # create a new Firefox session """
        cls.driver = webdriver.Firefox()
        cls.driver.implicitly_wait(30)
        cls.driver.maximize_window()

        # navigate to the application home page """
        cls.driver.get('http://demo-store.seleniumacademy.com/')

    def test_search_field(self):
        # check search field exists on Home page
        self.assertTrue(self.is_element_present(By.NAME, 'q'))

    def test_language_option(self):
        # check language options dropdown on Home page
        self.assertTrue(self.is_element_present(By.ID, 'select-language'))

    def test_shopping_cart_empty_message(self):
        # check content of My Shopping Cart block on Home page
        shopping_cart_icon = self.driver.\
            find_element_by_css_selector('div.header-minicart span.icon')
        shopping_cart_icon.click()

        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_button = self.driver.\
            find_element_by_css_selector('div.minicart-wrapper a.close')
        close_button.click()

    @classmethod
    def tearDown(cls):
        # close the browser window
        cls.driver.quit()

    def is_element_present(self, how, what):
        """
        Utility method to check presence of an element on page
        :params how: By locator type
        :params what: locator value
        """
        try:
            self.driver.find_element(by=how, value=what)
        except NoSuchElementException, e:
            return False
        return True

if __name__ == '__main__':
    unittest.main(verbosity=2)

再组合起来,见smoketests.py:

import unittest
from searchtests import SearchTests
from homepagetests import HomePageTest

# get all tests from SearchProductTest and HomePageTest class
search_tests = unittest.TestLoader().loadTestsFromTestCase(SearchTests)
home_page_tests = unittest.TestLoader().loadTestsFromTestCase(HomePageTest)

# create a test suite combining search_test and home_page_test
smoke_tests = unittest.TestSuite([home_page_tests, search_tests])

# run the suite
unittest.TextTestRunner(verbosity=2).run(smoke_tests)

执行结果:

# python smoketests.py
test_language_option (homepagetests.HomePageTest) ... ok
test_search_field (homepagetests.HomePageTest) ... ok
test_shopping_cart_empty_message (homepagetests.HomePageTest) ... ok
test_search_by_category (searchtests.SearchTests) ... ok
test_search_by_name (searchtests.SearchTests) ... ok
----------------------------------------------------------------------
Ran 5 tests in 223.231s

OK

生成HTML测试报告

插件 HTMLTestRunner可以帮助生成HTML报告。见 smoketests_with_html_report.py:

import unittest
import HTMLTestRunner
import os
from searchtests import SearchTests
from homepagetests import HomePageTest

# get the directory path to output report file
result_dir = os.getcwd()

# get all tests from SearchProductTest and HomePageTest class
search_tests = unittest.TestLoader().loadTestsFromTestCase(SearchTests)
home_page_tests = unittest.TestLoader().loadTestsFromTestCase(HomePageTest)

# create a test suite combining search_test and home_page_test
smoke_tests = unittest.TestSuite([home_page_tests, search_tests])

# open the report file
outfile = open(result_dir + '\SmokeTestReport.html', 'w')

# configure HTMLTestRunner options
runner = HTMLTestRunner.HTMLTestRunner(stream=outfile,
                                       title='Test Report',
                                       description='Smoke Tests')

# run the suite using HTMLTestRunner
runner.run(smoke_tests)

web通常包含了Hyper Text Markup Language (HTML)、Cascading Style Sheets (CSS)和JavaScript。本节主要内容如下:

  • 了解更多Selenium webDriver查找元素的知识

  • 使用各种浏览器提供的开发工具找到和定位元素

  • 多种发现元素的方法:ID、Name、类属性值、XPath、CSS选择器

  • Selenium webDriver中的各种find_element_by方法。

一般的浏览器都有查看源码的功能。

元素查找

使用开发工具发现定位器

Firefox的插件Firebug是个好帮手,可以F12或者右键点击元素选择“Inspect Element with Firebug”打开。Firefox的搜素框还可以对XPath或CSS进行查找。

Chrome中可以F12或者右键点击元素选择“Inspect Element”的方式查看代码。查找功能也和Firefox类似。Internet Explorer也有类似功能,不再赘述。

元素查找

find_element_by系列方法在找到元素的时候返回WebElement实例,否则产生NoSuchElementException异常。另外find_elements_by系列方法可以一次返回多个元素。

driver.find_element_by_css_selector(‘#search’)

Method Description Argument Example
find_element_by_id(id) This method finds an element by the ID attribute value id: The ID of the element to be found driver.find_element_by_id(‘search’)
find_element_by_name(name) This method finds an element by the name attribute value name: The name of the element to be found driver.find_element_by_name(‘q’)
find_element_by_class_name(name) This method finds an element by the class attribute value name: The class name of the element to be found driver.find_element_by_class_name(‘input-text’)
find_element_by_tag_name(name) This method finds an element by its tag name name: The tag name of the element to be found driver.find_element_by_tag_name(‘input’)
find_element_by_xpath(xpath) This method finds an element using XPath xpath: The xpath of the element to be found driver.find_element_by_xpath(‘form[0]/div[0]/input[0]’)
find_element_by_css_selector(css_selector) This method finds an element by the CSS selector css_selector: The CSS selector of the element to be found
find_element_by_link_text(link_text) This method finds an element by the link text link_text: The text of the element to be found driver.find_element_by_link_text(‘Log In’)
find_element_by_partial_link_text(link_text) This method finds an element by a partial match of its link text link_text: The text to match part of the text of the element driver.find_element_by_partial_link_text(‘Log’)

通过id、name、类属性是最建议,也是最快速的查找方法,尤其是id和name。其次使用tag和链接文本,万不得已才使用xpath和css。

XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。参考:XPath维基百科介绍 以及 w3schools的Xpath介绍zvon的XPath 1.0介绍。参考书籍:Selenium Testing Tools Cookbook。注意XPath的速度会比CSS还慢,不过支持向前向后定义和相对路径。

层叠样式表(英语:Cascading Style Sheets,简写CSS),又称串样式列表、层次结构式样式表文件,一种用来为结构化文档(如HTML文档或XML应用)添加样式(字体、间距和颜色等)的计算机语言。参考CSS维基百科介绍w3schools之CSS介绍

实例

import unittest
from selenium import webdriver

class HomePageTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # create a new Firefox session
        cls.driver = webdriver.Firefox()
        cls.driver.implicitly_wait(30)
        cls.driver.maximize_window()

        # navigate to the application home page
        cls.driver.get('http://demo-store.seleniumacademy.com/')

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

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

    def test_my_account_link_is_displayed(self):
        # get the Account link
        account_link = self.driver.find_element_by_link_text('ACCOUNT')

        # check My Account link is displayed/visible in the Home page footer
        self.assertTrue(account_link.is_displayed())

    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(len(account_links), 2)

    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 3 banners displayed on the page
        self.assertEqual(3, len(banners))

    def test_vip_promo(self):
        # get vip promo image
        vip_promo = self.driver.\
            find_element_by_xpath("//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)

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

    @classmethod
    def tearDownClass(cls):
        # close the browser window
        cls.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

执行结果:

# python        homepagetest.py
test_account_links (__main__.HomePageTest) ... ok
test_count_of_promo_banners_images (__main__.HomePageTest) ... ok
test_my_account_link_is_displayed (__main__.HomePageTest) ... ok
test_search_button_enabled (__main__.HomePageTest) ... ok
test_search_text_field_max_length (__main__.HomePageTest) ... ok
test_shopping_cart_status (__main__.HomePageTest) ... ok
test_vip_promo (__main__.HomePageTest) ... ok
----------------------------------------------------------------------
Ran 7 tests in 77.086s

OK

元素交互

本节主要内容如下:

  • 了解更多关于WebDriver和WebElement类的知识

  • 使用webdriver和WebElement类方法和属性实现测试与应用交互

  • 使用Select类自动化下拉菜单和列表的操作

  • 自动化的JavaScript弹窗和浏览器操作。

HTML表单的元素

HTML
--HEAD TITLE
--BODY
----FORM
----INPUT: Text,Password, Submit, Checkbox, Radio, FileEA
----TEXTAREA
----SELECT OPTION
----TABLE: THEAD,TBODY,TR(Rows),TD(columns/cells)
----DIV
----P(Paragraph)
----Headings(H1,H2...)
----A(Anchor)

webDriver类

webDriver类主要用于和浏览器交互,完整的属性和方法参见:selenium.webdriver.remote.webelement

属性列表:

| Property/attribute | Description | Example |
| current_url | This gets the URL of the current page displayed in the browser | driver.current_url |
| current_window_handle | This gets the handle of the current window | driver.current_window_handle |
| name | This gets the name of the underlying browser for this instance | driver.name |
| orientation | This gets the current orientation of the device | driver.orientation |
| page_source | This gets the source of the current page | driver.page_source |
| title | This gets the title of the current page | driver.title |
| window_handles | This gets the handles of all windows within the current session | driver.window_handles |

方法列表:

Method Description Argument Example
back() This goes one step backward in the browser history in the current session. driver.back()
close() This closes the current browser window. driver.close()
forward() This goes one step forward in the browser history in the current session. driver.forward()
get(url) This navigates and loads a web page in the current browser session. url is the address of the website or web page to navigate driver.get(“http://www.google.com”)
maximize_window() This maximizes the current browser window. driver.maximize_window()
quit() This quits the driver and closes all the associated windows. driver.quit()
refresh() This refreshes the current page displayed in the browser. driver.refresh()
switch_to.active_element() This returns the element with focus or the body if nothing else has focus. driver.switch_to_active_element()
Switch.to_alert() This switches the focus to an alert on the page. driver.switch_to_alert()
switch_to.default_content() This switches the focus to the default frame. driver.switch_to_default_content()
switch_to.frame(frame_reference) This switches the focus to the specified frame, by index, name, or web element. This method also works on IFRAMES. frame_reference: This is the name of the window to switch to, an integer representing the index, or a web element that is a frame to switch to driver.switch_to_frame(‘frame_name’)
switch_to.window(window_name) This switches focus to the specified window. window_name is the name or window handle of the window to switch to. driver.switch_to_window(‘main’)
implicitly_wait(time_to_wait) This sets a sticky timeout to implicitly wait for an element to be found, or a command to complete. This method only needs to be called one time per session. To set the timeout for calls to execute_async_script, see set_script_timeout. time_to_wait is the amount of time to wait(in seconds).
set_page_load_timeout(time_to_wait) This sets the amount of time to wait for a page load to complete. time_to_wait is the amount of time to wait(in seconds) driver.set_page_load_timeout(30)
set_script_timeout(time_to_wait) This sets the amount of time that the script should wait during an execute_async_script call before throwing an error. time_to_wait is the amount of time to wait(in seconds) driver.set_script_timeout(30)

WebElement类

WebElement类主要用于和元素交互,完整的属性和方法参见:elenium.webdriver.remote.webelement

属性列表:

| Property/attribute | Description | Example |
| size | This gets the size of the element | element.size |
| tag_name | This gets this element’ s HTML tag name | element.tag_name |
| text | This gets the text of the element | element.text |

方法列表:

Method Description Argument Example
clear() This clears the content of the textbox or text area element. element.clear()
click() This clicks the element. element.click()
get_attribute(name) This gets the attribute value from the element. name is the name of the attribute. element.get_attribute(“value”) Or element.get_attribute(“maxlength”)
is_displayed() This checks whether the element is visible to the user. element.is_displayed()
is_enabled() This checks whether the element is enabled. element.is_enabled()
is_selected() This checks whether the element is selected. This method is used to check the selection of a radio button or checkbox. element.is_selected()
send_keys(*value) This simulates typing into the element. Value is a string for typing or setting form fields. element.send_keys(“foo”)
submit() This submits a form. If you call this method on an element, it will submit the parent form. element.submit()
value_of_css_property(property_name) This gets the value of a CSS property. property_name is the name of the CSS property. element.value_of_css_property(“backgroundcolor”)

处理form、textbox、checkbox和radio

下面的homepagetests创建一个用户,演示了form、textbox、checkbox和radio等操作。

register_new_user.py

from selenium import webdriver
from time import gmtime, strftime
import unittest


class RegisterNewUser(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.driver.maximize_window()

        # navigate to the application home page
        self.driver.get('http://demo-store.seleniumacademy.com/')

    def test_register_new_user(self):
        driver = self.driver

        # click on Log In link to open Login page
        driver.find_element_by_link_text('ACCOUNT').click()
        driver.find_element_by_link_text('My Account').click()

        # get the Create Account button
        create_account_button = \
            driver.find_element_by_link_text('CREATE AN ACCOUNT')

        # check Create Account button is displayed and enabled
        self.assertTrue(create_account_button.is_displayed() and
                        create_account_button.is_enabled())

        # click on Create Account button. This will displayed new account
        create_account_button.click()

        # check title
        self.assertEquals('Create New Customer Account', driver.title)

        # get all the fields from Create an Account form
        first_name = driver.find_element_by_id('firstname')
        last_name = driver.find_element_by_id('lastname')
        email_address = driver.find_element_by_id('email_address')
        password = driver.find_element_by_id('password')
        confirm_password = driver.find_element_by_id('confirmation')
        news_letter_subscription = driver.find_element_by_id('is_subscribed')
        submit_button = driver.\
            find_element_by_xpath("//button[@title='Register']")

        # check maxlength of first name and last name textbox
        self.assertEqual('255', first_name.get_attribute('maxlength'))
        self.assertEqual('255', last_name.get_attribute('maxlength'))

        # check all fields are enabled
        self.assertTrue(first_name.is_enabled() and last_name.is_enabled() and
                        email_address.is_enabled() and
                        news_letter_subscription.is_enabled() and
                        password.is_enabled() and confirm_password.is_enabled()
                        and submit_button.is_enabled())

        # check Sign Up for Newsletter is unchecked
        self.assertFalse(news_letter_subscription.is_selected())

        user_name = 'user_' + strftime('%Y%m%d%H%M%S', gmtime())

        # fill out all the fields
        first_name.send_keys('Test')
        last_name.send_keys(user_name)
        news_letter_subscription.click()
        email_address.send_keys(user_name + '@example.com')
        password.send_keys('tester')
        confirm_password.send_keys('tester')

        # click Submit button to submit the form
        submit_button.click()

        # check new user is registered
        self.assertEqual('Hello, Test ' + user_name + '!',
                         driver.find_element_by_css_selector('p.hello > strong').text)
        driver.find_element_by_link_text('ACCOUNT').click()
        self.assertTrue(driver.find_element_by_link_text('Log Out').is_displayed())

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

执行结果:

test_register_new_user (__main__.RegisterNewUser) ... ok
----------------------------------------------------------------------
Ran 1 test in 133.117s

OK

处理dropdown和list

属性列表:

Property/attribute Description Example
all_selected_options This gets a list of all the selected options belonging to the dropdown or list select_element.all_selected_options
first_selected_option This gets the first selected/currently selected option from the dropdown or list select_element.first_selected_option
options This gets a list of all options from the dropdown or list select_element.options

方法列表:

Method Description Argument Example
deselect_() This clears all the selected entries from a multiselect dropdown or list select_element.deselect_()
deselect_by_index(index) This deselects the option at the given index from the dropdown or list index is the index of the option to be deselected deselect_element.deselect_by_index(1)
deselect_by_value(value) This deselects all options that have a value matching the argument from the dropdown or list value is the value attribute of the option to be deselected select_element.deselect_by_value(“foo”)
deselect_by_visible_text(text) This deselects all the options that display text matching the argument from the dropdown or list text is the text value of the option to be deselected select_element.deselect_by_visible_text(“bar”)
select_by_index(index) This selects an option at the given index from the dropdown or list index is the index of the option to be selected select_element.select_by_index(1)
select_by_value(value) This selects all the options that have a value matching the argument from the dropdown or list value is the value attribute of the option to be selected select_element.select_by_value(“foo”)
select_by_visible_text(text) This selects all the options that display the text matching the argument from the dropdown or list text is the text value of the option to be selected select_element.select_by_visible_text(“bar”)

代码文件:homepagetests.py。

from Tkinter import image_names
import unittest
from selenium import webdriver
from selenium.webdriver.support.ui import Select


class HomePageTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # create a new Firefox session
        cls.driver = webdriver.Firefox()
        cls.driver.implicitly_wait(30)
        cls.driver.maximize_window()

        # navigate to the application home page
        cls.driver.get('http://demo-store.seleniumacademy.com/')

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

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

    def test_my_account_link_is_displayed(self):
        # get the Account link
        account_link = self.driver.find_element_by_link_text('ACCOUNT')

        # check My Account link is displayed/visible in the Home page footer
        self.assertTrue(account_link.is_displayed())

    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.assertEqual(2, len(account_links))

    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 3 banners displayed on the page
        self.assertEqual(3, len(banners), 3)

    def test_vip_promo(self):
        # get vip promo image
        vip_promo = self.driver.\
            find_element_by_xpath("//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)
        self.driver.back()

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

    def test_language_options(self):
        # list of expected values in Language dropdown
        exp_options = ["ENGLISH", "FRENCH", "GERMAN"]

        # empty list for capturing actual options displayed in the dropdown
        act_options = []

        # get the Your language dropdown as instance of Select class
        select_language = \
            Select(self.driver.find_element_by_id("select-language"))

        # check number of options in dropdown
        self.assertEqual(3, len(select_language.options))

        # get options in a list
        for option in select_language.options:
            act_options.append(option.text)

        # check expected options list with actual options list
        self.assertListEqual(exp_options, act_options)

        # check default selected option is English
        self.assertEqual("ENGLISH",
                          select_language.first_selected_option.text)

        # select an option using select_by_visible text
        select_language.select_by_visible_text("German")

        # check store is now German
        self.assertTrue("store=german" in self.driver.current_url)

        # changing language will refresh the page,
        # we need to get find language dropdown once again
        select_language = \
            Select(self.driver.find_element_by_id("select-language"))
        select_language.select_by_index(0)

    def test_store_cookie(self):
        select_language = \
            Select(self.driver.find_element_by_id("select-language"))
        select_language.select_by_visible_text("French")
        self.assertEqual("french", self.driver.get_cookie("store")["value"])

        # changing language will refresh the page,
        # we need to get find language dropdown once again
        select_language = \
            Select(self.driver.find_element_by_id("select-language"))
        select_language.select_by_index(0)

    def test_css_for_home_page(self):
        self.assertTrue("demo-logo.png" in
                        self.driver.find_element_by_css_selector("div.notice-inner")
                        .value_of_css_property("background-image"))

    @classmethod
    def tearDownClass(cls):
        # close the browser window
        cls.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

处理告警和弹出窗口

完整的参考地址:selenium.webdriver.common.alert

属性列表:

Property/attribute Description Example
text This gets text from the alert window alert.text

方法列表:

Method Description Argument Example
accept() This will accept the JavaScript? alert.box that is click on the OK button alert.accept()
dismiss() This will dismiss the JavaScript? alert.box that is click on the Cancel button alert.dismiss()
send_keys(*value) This simulates typing into the element value is a string for typing or setting form fields alert.send_keys(“foo”)

实例中先加入商品,然后清空商品,此时会有弹出告警。注意此处的代码在网速较慢时,弹出窗口可能无法识别,解决方法参见下一章。

from selenium import webdriver
import unittest


class CompareProducts(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.driver.get('http://demo-store.seleniumacademy.com/')

    def test_compare_products_removal_alert(self):
        # get the search textbox
        search_field = self.driver.find_element_by_name('q')
        search_field.clear()

        # enter search keyword and submit
        search_field.send_keys('phones')
        search_field.submit()

        # click the Add to compare link
        self.driver.\
            find_element_by_link_text('Add to Compare').click()


        # click on Remove this item link,
        # this will display an alert to the user
        self.driver.find_element_by_link_text('Clear All').click()

        # switch to the alert
        alert = self.driver.switch_to.alert

        # get the text from alert
        alert_text = alert.text

        # check alert text
        self.assertEqual('Are you sure you would like to remove all products from your comparison?',
                          alert_text)

        # click on Ok button
        alert.accept()

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

自动化浏览器浏览

Method Description Argument Example
back() This goes one step backward in the browser history in the current session. None driver.back()
forward() This goes one step forward in the browser history in the current session. None driver.forward()
refresh() This refreshes the current page displayed in the browser. None driver.refresh()

实例: navigation_test.py

import unittest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions


class NavigationTest(unittest.TestCase):
    def setUp(self):
        # create a new Firefox session
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(30)
        self.driver.maximize_window()

        # navigate to the application home page
        self.driver.get('http://www.google.com')

    def test_browser_navigation(self):
        driver = self.driver
        # get the search textbox
        search_field = driver.find_element_by_name('q')
        search_field.clear()

        # enter search keyword and submit
        search_field.send_keys('selenium webdriver')
        search_field.submit()

        se_wd_link = driver.\
            find_element_by_link_text('Selenium WebDriver')
        se_wd_link.click()
        self.assertEqual('Selenium WebDriver', driver.title)

        driver.back()
        self.assertTrue(WebDriverWait(self.driver, 10)
            .until(expected_conditions.title_is('selenium webdriver - Google Search')))

        driver.forward()
        self.assertTrue(WebDriverWait(self.driver, 10)
            .until(expected_conditions.title_is('Selenium WebDriver')))

        driver.refresh()
        self.assertTrue(WebDriverWait(self.driver, 10)
            .until(expected_conditions.title_is('Selenium WebDriver')))

    def tearDown(self):
        # close the browser window
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

上面用例,因为google被和谐,通常无法执行,仅供参考。

同步

webdriver支持显式和隐式的同步。本节主要内容如下:

  • 显式和隐式等待

  • 何时使用显式和隐式的等待

  • 使用预期条件

  • 创建自定义的等待状态

使用隐式等待

隐式等待提供了通用的方法同步测试和步骤。适用于网络响应时间不一致或者使用Ajax调用渲染元素的时候。

隐式等待的默认超时时间是0,对整个webdriver生效。这个功能我们在第2章就有使用,现在我们把当时实例的隐式等待时间从30秒改成10秒。

import unittest
from selenium import webdriver


class SearchProductTest(unittest.TestCase):
    def setUp(self):
        # create a new Firefox session
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()

        # navigate to the application home page
        self.driver.get('http://demo-store.seleniumacademy.com/')

    def test_search_by_category(self):

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

        # enter search keyword and submit
        self.search_field.send_keys('phones')
        self.search_field.submit()

        # get all the anchor elements which have product names displayed
        # currently on result page using find_elements_by_xpath method
        products = self.driver\
            .find_elements_by_xpath("//h2[@class='product-name']/a")

        # check count of products shown in results
        self.assertEqual(3, len(products))

    def tearDown(self):
        # close the browser window
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

针对具体案例,显式案例通常隐式案例要好。

explicit_wait_tests.py

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
import unittest


class ExplicitWaitTests(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.get('http://demo-store.seleniumacademy.com/')

    def test_account_link(self):
        WebDriverWait(self.driver, 10)\
            .until(lambda s: s.find_element_by_id('select-language').get_attribute('length') == '3')

        account = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.visibility_of_element_located((By.LINK_TEXT, 'ACCOUNT')))
        account.click()

    def test_create_new_customer(self):
        # click on Log In link to open Login page
        self.driver.find_element_by_link_text('ACCOUNT').click()

        # wait for My Account link in Menu
        my_account = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.visibility_of_element_located((By.LINK_TEXT, 'My Account')))
        my_account.click()

        # get the Create Account button
        create_account_button = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.element_to_be_clickable((By.LINK_TEXT, 'CREATE AN ACCOUNT')))

        # click on Create Account button. This will displayed new account
        create_account_button.click()
        WebDriverWait(self.driver, 10)\
            .until(expected_conditions.title_contains('Create New Customer Account'))

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)

expected_conditions类

完整的属性和方法参见:selenium.webdriver.support.expected_conditions

该类的常见方法如下:

Method Description Argument Example
element_to_be_clickable(locator) This will wait for an element to be located and be visible and enabled so that it can be clicked. This method returns the element that is located back to the test. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver, 10).until(expected_conditions.element_to_be_clickable((By.NAME,“is_subscribed”)))
element_to_be_selected(element) This will wait until a specified element is selected. element: This is the WebElement?. subscription = self.driver.find_element_by_name(“is_subscribed”) WebDriverWait?(self.driver, 10).until(expected_conditions.element_to_be_selected(subscription))
invisibility_of_element_located(locator) This will wait for an element that is either invisible or is not present on the DOM. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver, 10).until(expected_conditions.invisibility_of_element_located((By.ID,“loading_banner”)))
presence_of_all_elements_located(locator) This will wait until at least one element for the matching locator is present on the web page. This method returns the list of WebElements? once they are located. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver,10).until(expected_conditions.presence_of_all_elements_located((By.CLASS_NAME,“input-text”)))
presence_of_element_located(locator) This will wait until an element for the matching locator is present on a web page or available on the DOM. This method returns an element once it is located. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver, 10).until(expected_conditions.presence_of_element_located((By.ID,“search”)))
text_to_be_present_in_element(locator, text_) This will wait until an element is located and has the given text. locator: This is a tuple of (by, locator). text: This is the text to be checked. WebDriverWait?(self.driver,10).until(expected_conditions.text_to_be_present_in_element((By.ID,“sele language”),“English”))
title_contains(title) This will wait for the page tile to contain a casesensitive substring.This method returns true if the tile matches, false otherwise。 title: This is the substring of the title to check. WebDriverWait?(self.driver, 10).until(expected_conditions.title_contains(“Create New Customer Account”))
title_is(title) This will wait for the page tile to be equal to the expected title. This method returns true if the tile matches, false otherwise. title: This is the title of the page. WebDriverWait?(self.driver, 10).until(expected_conditions.title_is(“Create New Customer Account -Magento Commerce Demo Store”))
visibility_of(element) This will wait until an element is present in DOM, is visible, and its width and height are greater than zero. This method returns the (same) WebElement? once it becomes visible. element: This is the WebElement?. first_name = self.driver.find_element_by_id(“firstname”) WebDriverWait?(self.driver,10).until(expected_conditions.visibility_of(first_name))
visibility_of_element_located(locator) This will wait until an element to be located is present in DOM, is visible, and its width and height are greater than zero. This method returns the WebElement? once it becomes visible. locator: This is a tuple of (by, locator). WebDriverWait?(self.driver,10).until(expected_conditions.visibility_of_element_located((By.ID,“firstname”)))

前一章的弹出窗口处理得不够好,现在我们修改下:comparetests.py

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
import unittest


class CompareProducts(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.get('http://demo-store.seleniumacademy.com/')

    def test_compare_products_removal_alert(self):
        # get the search textbox
        search_field = self.driver.find_element_by_name('q')
        search_field.clear()

        # enter search keyword and submit
        search_field.send_keys('phones')
        search_field.submit()

        # click the Add to compare link
        self.driver.\
            find_element_by_link_text('Add to Compare').click()

        # wait for Clear All link to be visible
        clear_all_link = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.visibility_of_element_located((By.LINK_TEXT, 'Clear All')))

        # click on Clear All link,
        # this will display an alert to the user
        clear_all_link.click()

        # wait for the alert to present
        alert = WebDriverWait(self.driver, 10)\
            .until(expected_conditions.alert_is_present())

        # get the text from alert
        alert_text = alert.text

        # check alert text
        self.assertEqual('Are you sure you would like to remove all products from your comparison?',
                          alert_text)
        # click on Ok button
        alert.accept()

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main(verbosity=2)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容