【发布时间】:2022-01-06 08:35:51
【问题描述】:
我的应用程序中有一个抓取模块,它使用 Beautiful Soup 和 Selenium 通过此功能获取网站信息:
def get_page(user: str) -> Optional[BeautifulSoup]:
"""Get a Beautiful Soup object that represents the user profile page in some website"""
try:
browser = webdriver.Chrome(options=options)
wait = WebDriverWait(browser, 10)
browser.get('https://somewebsite.com/' + user)
wait.until(EC.presence_of_element_located((By.TAG_NAME, 'article')))
except TimeoutException:
print("User hasn't been found. Try another user.")
return None
return BeautifulSoup(browser.page_source, 'lxml')
我需要通过两种方式来测试这个功能:
- 如果是获取页面(成功案例);
- 如果它正在打印警告并在没有获取任何页面时返回 None(失败情况)。
我试着这样测试:
class ScrapeTests(unittest.TestCase):
def test_get_page_success(self):
"""
Test if get_page is getting a page
"""
self.assertEqual(isinstance(sc.get_page('myusername'), BeautifulSoup), True)
def test_get_page_not_found(self):
"""
Test if get_page returns False when looking for a user
that doesn't exist
"""
self.assertEqual(sc.get_page('iwçl9239jaçklsdjf'), None)
if __name__ == '__main__':
unittest.main()
这样做会使测试变慢一些,因为get_page 本身在成功的情况下很慢,在失败的情况下,我在寻找不存在的用户时强制出现超时错误。我的印象是我测试这些功能的方法不是正确的。可能最好的测试方法是伪造响应,所以get_page 不需要连接到服务器并要求任何东西。
所以我有两个问题:
- 这种“虚假网络响应”的想法是测试此功能的正确方法吗?
- 如果是这样,我该如何实现该功能?我是否需要重写
get_page函数以使其“可测试”?
编辑:
我尝试像这样为get_page 创建一个测试:
class ScrapeTests(TestCase):
def setUp(self) -> None:
self.driver = mock.patch(
'scrape.webdriver.Chrome',
autospec=True
)
self.driver.page_source.return_value = "<html><head></head><body><article>Yes</article></body></html>"
self.driver.start()
def tearDown(self) -> None:
self.driver.stop()
def test_get_page_success(self):
"""
Test if get_page is getting a page
"""
self.assertEqual(isinstance(sc.get_page('whatever'), BeautifulSoup), True)
我面临的问题是driver.page_source 属性仅在wait.until 函数调用之后创建。我需要wait.until,因为我需要 Selenium 浏览器等待 javascript 在 HTML 中创建 article 标记,以便我抓取它们。
当我尝试在setUp 中定义页面源的返回值时,我收到错误:AttributeError: '_patch' object has no attribute 'page_source'
我尝试了很多方法来使用 mock. patch 模拟 webdriver 属性,但据我所知,这似乎很难。我认为实现我想要的(无需连接到服务器即可测试get_page 功能)的最佳方法可能是模拟整个Web 服务器连接。但这只是猜测。
【问题讨论】:
-
请参阅softwareengineering.stackexchange.com/questions/365346/… 了解有关此问题的讨论。
标签: python unit-testing testing beautifulsoup architecture