使用Python学习selenium测试工具,pythonselenium,Selenium的组件S


 

快速入门

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。

 

快速入门

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

  • 文档
    • API文档
    • 官方文档
    • Selenium Wiki

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

  • 代码完成和智能提示的图形化代码编辑器
  • 函数和类的代码浏览器
  • 语法高亮
  • 项目管理
  • 代码模板
  • 单元测试和调试
  • 源代码控制支持

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

  • WingIDE
  • pycharm
  • Eclipse
  • PyDev安装教程
  • PyDev官网
  • PyScripter

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

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

Shell
#!/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()

执行结果和火狐的类似。

参考资料:

  • InternetExplorerDriver
  • DesiredCapabilities  

 

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

参考资料:

  • ChromeDriver
  • chromium chromedriver

 

 

 

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

 

参考资料

  • Dr .        Philip        Polstra         介绍 博客
  • Walt        Stoneburner: wls#wwco.com Walt.Stoneburner#gmail.com 博客
  • 维基百科Selenium英文介绍

评论关闭