专栏首页用户7466307的专栏使用Selenium WebDriver,Python和Chrome编写您的第一个Web测试

使用Selenium WebDriver,Python和Chrome编写您的第一个Web测试

准备好WebDriver后,让我们编写第一个Web测试!测试将是一个简单的DuckDuckGo搜索。DuckDuckGo是一个不跟踪用户数据的搜索引擎。就像任何其他搜索引擎一样,用户可以输入搜索短语并获得指向匹配网站的链接。

在编写自动化代码之前,最好总是以简单的语言编写测试过程。编写程序迫使我们首先考虑被测行为。这是我们的测试过程:

  1. 导航到DuckDuckGo主页
  2. 输入搜索词组
  3. 验证:
    1. 结果显示在结果页面上
    2. 搜索词出现在搜索栏中
    3. 至少一个搜索结果包含搜索短语

这是相当基本的,但涵盖了端到端的典型搜索行为。

代码

将以下测试功能添加到:tests/test_web.py

def test_basic_duckduckgo_search(browser):
  URL = 'https://www.duckduckgo.com'
  PHRASE = 'panda'
  
  browser.get(URL)
  
  search_input = browser.find_element_by_id('search_form_input_homepage')
  search_input.send_keys(PHRASE + Keys.RETURN)
  
  link_divs = browser.find_elements_by_css_selector('#links > div')
  assert len(link_divs) > 0
  
  xpath = f"//div[@id='links']//*[contains(text(), '{PHRASE}')]"
  results = browser.find_elements_by_xpath(xpath)
  assert len(results) > 0
  
  search_input = browser.find_element_by_id('search_form_input')
  assert search_input.get_attribute('value') == PHRASE

test_basic_duckduckgo_search函数按照Arrange-Act-Assert模式执行我们的测试过程。请注意,测试函数声明了一个名为的参数browser,该参数 与我们用于ChromeDriver设置和清除的固定装置相同。每次运行此测试时,pytest都会自动调用固定装置并注入WebDriver参考。然后,测试函数使用该browser变量进行多个WebDriver调用。让我们看看这些调用是如何工作的。

URL = 'https://www.duckduckgo.com'

该测试将DuckDuckGo主页的URL声明为变量,以提高可读性和可维护性。

PHRASE = 'panda'

这是测试将使用的搜索短语。由于测试涵盖了“基本”搜索,因此该短语并不太重要。其他行使不同行为的测试应使用更复杂的短语。再次,测试将其声明在测试功能的顶部,以提高可读性和可维护性。

browser.get(URL)

测试的起点是DuckDuckGo主页。此调用将浏览器导航到给定的URL。被警告,虽然:此调用并 不会等待页面加载。它只是启动加载交互。

search_input = browser.find_element_by_id('search_form_input_homepage')

自动化Web交互的第一步是找到目标元素。元素可能会或可能不会出现在页面上。自动化必须使用 定位器 来查找元素(如果存在),然后构造一个代表该元素的对象。定位符的类型很多:ID,类名,CSS选择器,XPaths等。定位器将在页面上找到所有匹配的元素-可能不止一个。尝试使用最简单的定位器,该定位器将唯一地标识目标元素。

要编写定位器,您需要查看页面的HTML结构。Chrome DevTools可轻松检查任何实时页面的标记。只需右键单击页面,然后选择“检查”。您可以在“元素”选项卡上查看所有元素。对于我们的测试,我们想在DuckDuckGo主页上找到搜索输入字段。该元素的 id 属性值为“ search_form_input_homepage”,如下所示:

我们可以使用WebDriver的find_element_by_id 方法获取该元素。为search_input变量分配了代表页面上搜索输入元素的对象。请记住,由于WebDriver实例具有隐式等待,因此最多等待10秒钟,搜索输入元素才会出现在页面上。

search_input.send_keys(PHRASE + Keys.RETURN)

有了元素,我们就可以触发与它的交互。该send_keys方法将一系列击键发送到搜索输入元素,就像人类用户会在键盘上键入一样。上面的呼叫发送搜索词组。最后的RETURN键提交搜索。

断言(1)

link_divs = browser.find_elements_by_css_selector('#links > div')

结果页面应显示一个divID为“ links”的div元素,每个结果链接都有一个子元素。上面的CSS选择器可以找到所有这样的结果链接div。请注意,“元素”是复数–此调用将返回一个列表。

assert len(link_divs) > 0

测试必须验证搜索词是否确实出现了结果。此assert语句确保在页面上至少找到一个结果链接。

断言(2)

xpath = f"//div[@id='links']//*[contains(text(), '{PHRASE}')]"

验证是否出现了一些结果很好,但是我们还应该验证结果是否与我们的搜索词匹配。我们可以使用XPath来精确定位包含文本中搜索短语的结果链接。XPath比名称和CSS选择器复杂,但它们也更强大。上面的XPath搜索divID为“ links”的链接,然后查找包含搜索短语文本的后代。

phrase_results = browser.find_elements_by_xpath(xpath)

此调用使用先前串联的XPath查找所有元素。我们可以将这两行合并为一,但是将这些行拆分起来更具可读性和Python风格。

assert len(phrase_results) > 0

像先前的断言一样,此断言确保至少找到一个元素。这是一个简单的健全性检查。它可以变得更强大-就像验证页面上的每个结果都包含搜索词组文本一样-但这很难。并非每个结果都可以包含搜索短语的确切文本。例如,某些可能具有大写字符。对于高级验证,定位器和逻辑将需要更加复杂。由于这是 基本的搜索测试,因此简单的断言就足够了。

断言(3)

search_input = browser.find_element_by_id('search_form_input')

最终断言验证搜索短语仍出现在搜索输入中。上面的行与Arrange阶段中的find元素调用相同 。它将再次找到搜索输入元素。我们为什么不能search_input再次使用该对象?不幸的是,先前的元素已经 过时了。页面从搜索页面更改为结果页面。即使元素看起来相同,也有所不同,并且还需要一个新的定位器。因此,我们需要重新获取它。

assert search_input.get_attribute('value') == PHRASE

键入输入元素的文本可作为其“值”属性访问。该行断言“值”属性等于搜索词组。它验证该短语没有消失。

查看并运行Web测试

现在,其完整代码应如下所示(为清晰起见,附加了注释):tests/test_web.py

"""
This module contains web test cases for the tutorial.
Tests use Selenium WebDriver with Chrome and ChromeDriver.
The fixtures set up and clean up the ChromeDriver instance.
"""
import pytest
from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
@pytest.fixture
def browser():
  # Initialize ChromeDriver
  driver = Chrome()
  # Wait implicitly for elements to be ready before attempting interactions
  driver.implicitly_wait(10)
  
  # Return the driver object at the end of setup
  yield driver
  
  # For cleanup, quit the driver
  driver.quit()
def test_basic_duckduckgo_search(browser):
  # Set up some test case data
  URL = 'https://www.duckduckgo.com'
  PHRASE = 'panda'
  # Navigate to the DuckDuckGo home page
  browser.get(URL)
  # Find the search input element
  # In the DOM, it has an 'id' attribute of 'search_form_input_homepage'
  search_input = browser.find_element_by_id('search_form_input_homepage')
  # Send a search phrase to the input and hit the RETURN key
  search_input.send_keys(PHRASE + Keys.RETURN)
  # Verify that results appear on the results page
  link_divs = browser.find_elements_by_css_selector('#links > div')
  assert len(link_divs) > 0
  # Verify that at least one search result contains the search phrase
  xpath = f"//div[@id='links']//*[contains(text(), '{PHRASE}')]"
  phrase_results = browser.find_elements_by_xpath(xpath)
  assert len(phrase_results) > 0
  # Verify that the search phrase is the same
  search_input = browser.find_element_by_id('search_form_input')
  assert search_input.get_attribute('value') == PHRASE

现在,运行测试以确保它可以运行:

$ pipenv run python -m pytest
============================= test session starts ==============================
platform darwin -- Python 3.7.3, pytest-4.5.0, py-1.8.0, pluggy-0.12.0
rootdir: /Users/andylpk247/Programming/automation-panda/python-webui-testing
collected 9 items                                                              
tests/test_math.py ........                                              [ 88%]
tests/test_web.py .                                                      [100%]
=========================== 9 passed in 6.10 seconds ===========================

网络测试运行时,它将打开Google Chrome。您可以观看它自动输入搜索短语,等待结果页面,然后退出浏览器。整齐!

如果测试无法运行,请检查以下内容:

  • 测试计算机是否已安装Chrome?
  • ChromeDriver是否在系统路径上?
  • ChromeDriver版本与Chrome版本匹配吗?
  • 是否有文件系统权限问题?
  • 防火墙是否阻止了任何端口?
  • 测试代码正确吗?

本文分享自微信公众号 - 软件测试test(gh_d29759b02f67),作者:Coldrain

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • WebDriverIO教程:处理Selenium中的警报和覆盖

    在此有关Selenium中警报处理的WebDriverIO教程中,我将向您展示如何在WebDriverIO中处理警报和弹出窗口以及叠加模式。我还将介绍自动化期间...

    用户7466307
  • SoapUI中是如何断言的呢(一)

    将请求发送到Web服务器后,就会收到响应。我们需要验证响应是否包含我们期望的数据。为了验证响应,我们需要使用断言。

    用户7466307
  • 什么是渗透测试?

    渗透测试告诉系统上采用的现有防御措施是否足够强大,可以防止任何安全漏洞。渗透测试报告还建议了可以采取的对策,以减少系统被黑客入侵的风险。

    用户7466307
  • H5中input输入框如何实现原生键盘搜索功能

    在H5开发中,经常会开发搜索功能,商品列表、订单列表、客户列表等等,都需要搜索,所以程序猿(程序媛)们都会遇到这样的需求,点击搜索input时,弹出的键盘,有“...

    Javanx
  • iOS自定义键盘搜索键

    之前知道HTML5的input属性,新增了一种type=search。当系统焦点在input[type=search]元素上时,iOS会自动更改键盘的确认按键为...

    libo1106
  • 触类旁通Elasticsearch:管理

    (1)创建模板 当待创建的索引与之前的索引有相同的设置和映射时,非常适合使用索引模板。正如其名,索引模板将会用于和预定义名称模式相匹配的索引创...

    用户1148526
  • swoole安装时的问题

    waki
  • 闭包还可以这样写?谈谈少儿编程工具的实现思路

      看看这段代码,很明显,是列举出100以内所有的质数。类似这样的程序我们从学程序开始写过很多。

    窗户
  • 先验概率(Prior probability)

    先验概率(prior probability)是指根据以往经验和分析得到的概率,如全概率公式,它往往作为”由因求果”问题中的”因”出现的概率。

    easyAI
  • 索引是救星也是灾星

    最近读了一篇关于MYSQL的文章,主要是更深入化的讲解MYSQL的锁机制,写的真是好。但里面细细的读,发现一个问题,索引的问题,一般我们都人为索引是我们查询中的...

    AustinDatabases

扫码关注云+社区

领取腾讯云代金券