Python 웹 스크래핑-스크레이퍼로 테스트
이 장에서는 Python에서 웹 스크레이퍼를 사용하여 테스트를 수행하는 방법을 설명합니다.
소개
대규모 웹 프로젝트에서는 웹 사이트 백엔드의 자동화 된 테스트가 정기적으로 수행되지만 프런트 엔드 테스트는 자주 생략됩니다. 이것의 주된 이유는 웹 사이트의 프로그래밍이 다양한 마크 업과 프로그래밍 언어의 그물과 같다는 것입니다. 한 언어에 대한 단위 테스트를 작성할 수 있지만 상호 작용이 다른 언어로 수행되면 어렵습니다. 그렇기 때문에 코드가 예상대로 작동하는지 확인하기 위해 일련의 테스트가 필요합니다.
Python을 사용한 테스트
테스트에 대해 이야기 할 때 단위 테스트를 의미합니다. Python을 사용한 테스트에 깊이 들어가기 전에 단위 테스트에 대해 알아야합니다. 다음은 단위 테스트의 몇 가지 특성입니다.
구성 요소의 기능 중 최소한 한 가지 측면이 각 단위 테스트에서 테스트됩니다.
각 단위 테스트는 독립적이며 독립적으로 실행할 수도 있습니다.
단위 테스트는 다른 테스트의 성공 또는 실패를 방해하지 않습니다.
단위 테스트는 임의의 순서로 실행할 수 있으며 하나 이상의 어설 션을 포함해야합니다.
Unittest-Python 모듈
단위 테스트를위한 Unittest라는 Python 모듈은 모든 표준 Python 설치와 함께 제공됩니다. 우리는 가져 오기만하면되고 나머지는 다음을 수행 할 unittest.TestCase 클래스의 작업입니다.
SetUp 및 tearDown 함수는 unittest.TestCase 클래스에서 제공합니다. 이러한 기능은 각 단위 테스트 전후에 실행할 수 있습니다.
또한 테스트를 통과하거나 실패 할 수 있도록 assert 문을 제공합니다.
단위 테스트로 test_로 시작하는 모든 함수를 실행합니다.
예
이 예에서는 웹 스크래핑을 unittest. Wikipedia 페이지에서 'Python'문자열 검색을 테스트합니다. 기본적으로 두 가지 테스트를 수행합니다. 첫 번째는 제목 페이지가 검색 문자열 인 'Python'과 동일하거나 그렇지 않은지 확인하고 두 번째 테스트는 페이지에 콘텐츠 div가 있는지 확인합니다.
먼저 필요한 Python 모듈을 가져옵니다. 웹 스크래핑에는 BeautifulSoup을 사용하고 테스트에는 물론 단위 테스트를 사용하고 있습니다.
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)
셀레늄으로 테스트
테스트를 위해 Python Selenium을 사용하는 방법에 대해 논의하겠습니다. 셀레늄 테스트라고도합니다. 두 파이썬unittest 과 Selenium공통점이 많지 않습니다. 우리는 Selenium이 브라우저 디자인의 변화에도 불구하고 표준 Python 명령을 다른 브라우저로 전송한다는 것을 알고 있습니다. 이전 장에서 이미 Selenium을 설치하고 작업했음을 기억하십시오. 여기서는 Selenium에서 테스트 스크립트를 만들고 자동화에 사용합니다.
예
다음 Python 스크립트의 도움으로 Facebook 로그인 페이지 자동화를위한 테스트 스크립트를 만들고 있습니다. 선택한 다른 양식 및 로그인을 자동화하는 예제를 수정할 수 있지만 개념은 동일합니다.
먼저 웹 브라우저에 연결하기 위해 셀레늄 모듈에서 웹 드라이버를 가져옵니다.
from selenium import webdriver
이제 셀레늄 모듈에서 키를 가져와야합니다.
from selenium.webdriver.common.keys import Keys
다음으로 페이스 북 계정에 로그인하기위한 사용자 이름과 비밀번호를 제공해야합니다.
user = "[email protected]"
pwd = ""
다음으로 Chrome 용 웹 드라이버의 경로를 제공합니다.
path = r'C:\\Users\\gaurav\\Desktop\\Chromedriver'
driver = webdriver.Chrome(executable_path=path)
driver.get("http://www.facebook.com")
이제 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 웹 브라우저가 열리고 이메일과 비밀번호가 삽입되고 로그인 버튼을 클릭하는 것을 볼 수 있습니다.
비교 : unittest 또는 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 = "http://www.facebook.com"
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()