如何通过Mock或Pickle测试接收BeautifulSoup对象的函数?
测试接收BeautifulSoup对象的函数的方案
方案一:用静态HTML片段生成真实BeautifulSoup对象(最推荐)
无需Mock,直接提取目标页面关键HTML片段创建真实BS对象,既贴近实际解析场景,又避免Mock的复杂配置,测试准确性更高。
步骤:
- 从目标页面复制包含待解析元素(如
<option>标签)的HTML代码,保存为测试用静态字符串。 - 用这段HTML生成BeautifulSoup对象,传入待测试函数即可。
示例代码:
from bs4 import BeautifulSoup import pytest def scrape_full_team_names(soup_object): full_team_names = [] teams_location = soup_object.find_all("option", limit=32) for team in teams_location: for string in team.stripped_strings: full_team_names.append(string) return full_team_names def test_scrape_full_team_names(): # 模拟目标页面的<option>区域HTML test_html = """ <select> <option>Arizona Cardinals</option> <option>Atlanta Falcons</option> <option>Baltimore Ravens</option> <option>Buffalo Bills</option> <option>Carolina Panthers</option> <option>Chicago Bears</option> <!-- 可补充其他团队选项 --> </select> """ # 生成真实的BeautifulSoup对象 test_soup = BeautifulSoup(test_html, "html.parser") # 执行测试 result = scrape_full_team_names(test_soup) # 断言结果匹配预期 assert result == [ "Arizona Cardinals", "Atlanta Falcons", "Baltimore Ravens", "Buffalo Bills", "Carolina Panthers", "Chicago Bears" # 对应补充的预期值 ]
方案二:Mock BeautifulSoup对象及其方法(使用pytest-mock)
如果坚持使用Mock,可以模拟BeautifulSoup对象的find_all方法,以及返回Tag对象的stripped_strings属性。
示例代码:
from unittest.mock import MagicMock import pytest def scrape_full_team_names(soup_object): full_team_names = [] teams_location = soup_object.find_all("option", limit=32) for team in teams_location: for string in team.stripped_strings: full_team_names.append(string) return full_team_names def test_scrape_full_team_names(mocker): # 模拟单个<option>标签对象 mock_tag1 = MagicMock() mock_tag1.stripped_strings = ["Arizona Cardinals"] mock_tag2 = MagicMock() mock_tag2.stripped_strings = ["Atlanta Falcons"] mock_tag3 = MagicMock() mock_tag3.stripped_strings = ["Baltimore Ravens"] # 可继续模拟更多标签 # 模拟BeautifulSoup对象的find_all方法返回结果 mock_soup = MagicMock() mock_soup.find_all.return_value = [mock_tag1, mock_tag2, mock_tag3] # 执行测试并断言 result = scrape_full_team_names(mock_soup) assert result == [ "Arizona Cardinals", "Atlanta Falcons", "Baltimore Ravens" # 对应预期值 ] # 验证find_all的调用参数是否符合预期 mock_soup.find_all.assert_called_once_with("option", limit=32)
关于Pickle的说明
你提到的Pickle方案确实存在安全风险,Pickle反序列化不可信数据可能触发恶意代码执行,因此不建议用于这类测试场景。静态HTML片段的方式更安全可控,也更易维护。
内容的提问来源于stack exchange,提问作者DAK
相关产品推荐
相关产品推荐

