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 = "gauravleekha@gmail.com"
pwd = ""

接下來,提供 Chrome 的 Web 驅動程式路徑。

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

現在,我們將使用 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 = "gauravleekha@gmail.com"
      pwd = ""
      pageUrl = "https://#"
      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()
廣告