Python 网络爬虫 - 使用爬虫进行测试



本章解释如何在 Python 中使用网络爬虫进行测试。

介绍

在大型 Web 项目中,会定期对网站的后端进行自动化测试,但前端测试往往会被忽略。其主要原因是网站的编程就像一个由各种标记语言和编程语言组成的网络。我们可以为一种语言编写单元测试,但是如果交互是在另一种语言中进行的,就会变得具有挑战性。这就是为什么我们必须有一套测试来确保我们的代码按照我们的预期执行。

使用 Python 进行测试

当我们谈论测试时,指的是单元测试。在深入探讨使用 Python 进行测试之前,我们必须了解单元测试。以下是单元测试的一些特征:

  • 每个单元测试都将测试组件功能的至少一个方面。

  • 每个单元测试都是独立的,也可以独立运行。

  • 单元测试不会干扰任何其他测试的成功或失败。

  • 单元测试可以以任何顺序运行,并且必须至少包含一个断言。

Unittest - Python 模块

名为 Unittest 的 Python 单元测试模块随所有标准 Python 安装一起提供。我们只需要导入它,其余的工作由 unittest.TestCase 类完成,它将执行以下操作:

  • unittest.TestCase 类提供 setUp 和 tearDown 函数。这些函数可以在每个单元测试之前和之后运行。

  • 它还提供 assert 语句,允许测试通过或失败。

  • 它运行所有以 test_ 开头的函数作为单元测试。

示例

在这个例子中,我们将把网络爬虫与unittest结合起来。我们将测试维基百科页面搜索字符串“Python”。它基本上会进行两个测试,第一个测试是标题页面是否与搜索字符串“Python”相同,第二个测试确保页面具有内容 div。

首先,我们将导入所需的 Python 模块。我们使用 BeautifulSoup 进行网络爬虫,当然也使用 unittest 进行测试。

from urllib.request import urlopen
from bs4 import BeautifulSoup
import unittest

现在我们需要定义一个类,该类将扩展 unittest.TestCase。全局对象 bs 将在所有测试之间共享。unittest 指定的函数 setUpClass 将实现它。在这里,我们将定义两个函数,一个用于测试标题页面,另一个用于测试页面内容。

class Test(unittest.TestCase):
   bs = None
   def setUpClass():
      url = '<a target="_blank" rel="nofollow" href="https://en.wikipedia.org/wiki/Python">https://en.wikipedia.org/wiki/Python'</a>
      Test.bs = BeautifulSoup(urlopen(url), 'html.parser')
   def test_titleText(self):
      pageTitle = Test.bs.find('h1').get_text()
      self.assertEqual('Python', pageTitle);
   def test_contentExists(self):
      content = Test.bs.find('div',{'id':'mw-content-text'})
      self.assertIsNotNone(content)
if __name__ == '__main__':
   unittest.main()

运行上述脚本后,我们将得到以下输出:

----------------------------------------------------------------------
Ran 2 tests in 2.773s

OK
An exception has occurred, use %tb to see the full traceback.

SystemExit: False

D:\ProgramData\lib\site-packages\IPython\core\interactiveshell.py:2870:
UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
 warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

使用 Selenium 进行测试

让我们讨论如何使用 Python Selenium 进行测试。它也称为 Selenium 测试。Python unittestSelenium 之间并没有太多共同之处。我们知道 Selenium 将标准 Python 命令发送到不同的浏览器,尽管它们的浏览器设计有所不同。回想一下,我们已经在前面的章节中安装并使用了 Selenium。在这里,我们将创建 Selenium 中的测试脚本并将其用于自动化。

示例

借助下一个 Python 脚本,我们正在创建 Facebook 登录页面的自动化测试脚本。您可以修改此示例以自动化您选择的其他表单和登录,但概念将相同。

首先,为了连接到 Web 浏览器,我们将从 selenium 模块导入 webdriver:

from selenium import webdriver

现在,我们需要从 selenium 模块导入 Keys。

from selenium.webdriver.common.keys import Keys

接下来,我们需要提供用户名和密码才能登录我们的 Facebook 帐户

user = "[email protected]"
pwd = ""

接下来,提供 Chrome 的 Web 驱动程序路径。

path = r'C:\\Users\\gaurav\\Desktop\\Chromedriver'
driver = webdriver.Chrome(executable_path=path)
driver.get("https://127.0.0.1")

现在,我们将使用 assert 关键字验证条件。

assert "Facebook" in driver.title

借助以下代码行,我们将值发送到电子邮件部分。在这里,我们通过其 ID 搜索它,但我们可以通过名称搜索它,如driver.find_element_by_name("email")

element = driver.find_element_by_id("email")
element.send_keys(user)

借助以下代码行,我们将值发送到密码部分。在这里,我们通过其 ID 搜索它,但我们可以通过名称搜索它,如driver.find_element_by_name("pass")

element = driver.find_element_by_id("pass")
element.send_keys(pwd)

下一行代码用于在电子邮件和密码字段中插入值后按 Enter/登录。

element.send_keys(Keys.RETURN)

现在我们将关闭浏览器。

driver.close()

运行上述脚本后,Chrome 浏览器将打开,您可以看到电子邮件和密码正在插入,并单击登录按钮。

Facebook Login

比较:unittest 或 Selenium

unittest 和 selenium 的比较很难,因为如果您想使用大型测试套件,则需要 unites 的语法严格性。另一方面,如果您要测试网站的灵活性,那么 Selenium 测试将是我们的首选。但是,如果我们可以将两者结合起来呢?我们可以将 selenium 导入到 Python unittest 中,并获得两者的优势。Selenium 可用于获取有关网站的信息,而 unittest 可以评估该信息是否符合通过测试的标准。

例如,我们正在重写上述用于 Facebook 登录自动化的 Python 脚本,方法是将两者结合起来,如下所示:

import unittest
from selenium import webdriver

class InputFormsCheck(unittest.TestCase):
   def setUp(self):
      self.driver = webdriver.Chrome(r'C:\Users\gaurav\Desktop\chromedriver')
      def test_singleInputField(self):
      user = "[email protected]"
      pwd = ""
      pageUrl = "https://127.0.0.1"
      driver=self.driver
      driver.maximize_window()
      driver.get(pageUrl)
      assert "Facebook" in driver.title
      elem = driver.find_element_by_id("email")
      elem.send_keys(user)
      elem = driver.find_element_by_id("pass")
      elem.send_keys(pwd)
      elem.send_keys(Keys.RETURN)
   def tearDown(self):
      self.driver.close()
if __name__ == "__main__":
   unittest.main()
广告