首页 文章

单元测试python时有多个异常和代码覆盖

提问于
浏览
9

The Problem:

以下是受测试代码的仿制示例:

from datetime import datetime

def f(s):
    try:
        date = s.split(":")[1]
        return datetime.strptime(date, "%Y%m%d")
    except (ValueError, IndexError) as e:
        # some code here
        raise

这是我目前拥有的一组测试:

from datetime import datetime
import unittest

from test_module import f

class MyTestCase(unittest.TestCase):
    def test_valid_date(self):
        self.assertEqual(f("1:20130101"), datetime(2013, 1, 1))

    def test_invalid_date(self):
        self.assertRaises(ValueError, f, "1:invalid")

测试通过,如果我使用 --branch 标志运行覆盖,我将得到100%的线和分支覆盖:

$ coverage run --branch -m unittest test
..
----------------------------------------------------------------------
Ran 2 tests in 0.003s

OK
$ coverage report
Name            Stmts   Miss Branch BrPart  Cover
--------------------------------------------
test_module.py      7      0      0      0   100%
--------------------------------------------
TOTAL               7      0      0      0   100%

但请注意,测试目前仅检查两种情况 - 当没有抛出异常时,并且引发了一个 ValueError 异常 .

The question:

是否有一种方法 coverage 报告我在 IndexError 被引发时没有测试过案例?

2 回答

  • 8

    Coverage.py只能测量运行哪些执行路径(语句或分支) . 它无法跟踪使用的值,包括引发的异常类型 .

    在我看来,你的选择是:

    • 分离异常从句 . 在您展示的代码中,无论如何都可以通过单独的行引发两个异常,尽管可能在您的实际代码中它们不是那么可分离的 .

    • 不要担心这两个例外 . 您对此代码的测试可能会考虑许多不同的输入,旨在执行不同的边缘情况 . Coverage.py无法帮助您区分所有这些,或确保您已编写足够的案例 . 使用其他标准来确定您已编写足够的测试用例 .

  • 1

    我认为你可以尝试两个例外的两个例外 . 在这种情况下,线路覆盖显示您尚未测试一个条件 .

    from datetime import datetime
    
    def f(s):
        try:
            date = s.split(":")[1]
            return datetime.strptime(date, "%Y%m%d")
        except ValueError as e:
            # some code here
            raise
        except IndexError as e:
            # some code
            raise
    

    如果您不想重复某些代码,则可以使用该功能 .

相关问题