【问题标题】:How to get coverage for a unittest inside a for-loop?如何在 for 循环中获取单元测试的覆盖率?
【发布时间】:2020-02-21 06:45:31
【问题描述】:

我正在尝试在修补 BeautifulSoup.select 时使用 assertRaises 测试异常。

从网页中获取 ID 的方法,采用 html resultsPage

def parseOutIds(resultsPage):

    soup = BeautifulSoup(resultsPage, "html.parser")

    records = soup.select('some-html-tags')
    parsed = []
    for record in records:
        try:
            ampData = json.loads(record["other-tags"])
            parsed.append(ampData)
        except json.decoder.JSONDecodeError from err # Missing coverage

    return parsed

上面的辅助方法和测试。我正在提高ValueError,因为json.decoder.JSONDecodeError 基于此answer 继承自它。

def loadHtml(self, fileName):
    with open('path/to/test'+filename) as f:
         self.html = file.read().strip()

def test_parseOutIds(self):
    self.loadHtml('test-html.html')

    #errorMock method just raises ValueError exception
    bsPatch = patch('bs4.BeautifulSoup.select', self.errorMock) 
    with bsPatch:
        with self.assertRaises(ValueError):
             parseOutIds(self.html)

我上面的当前测试缺少异常行的保险。

其他要点:

  1. 我也必须修补 json.load 吗?
  2. 根据我从其他答案中看到的情况,由于存在循环,我是否还模拟了另一种方法?

【问题讨论】:

    标签: python json unit-testing beautifulsoup mocking


    【解决方案1】:

    您的代码中有一些误解:

    • ValueError 不会被 except json.decoder.JSONDecodeError 子句捕获 - 您可以从派生自 json.decoder.JSONDecodeError 的类中捕获对象,但不能从 json.decoder.JSONDecodeError 中捕获父类。
    • soup.select 调用在 try 块之外 - 因此从 soup.select 抛出的异常无论如何都不会被捕获。

    现在,关于您的测试问题:我认为您可能不需要修补任何东西来测试parseOutIds。您只需为相应的测试用例提供适当的 html 输入。在您的情况下,您想编写一个测试来涵盖异常部分。这意味着,所需的 html 输入将具有包含无效 JSON 数据的记录之一。这将导致json.loads 抛出json.decoder.JSONDecodeError

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-24
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      相关资源
      最近更新 更多