首页 > 解决方案 > 是否有充分的理由在单元测试事务中捕获异常?

问题描述

unittest 模块非常适合检测代码中的问题。我理解使用断言隔离和测试部分代码的想法:

self.assertEqual(web_page_view.func, web_page_url)

但除了这些断言之外,您之前可能还有一些逻辑,在相同的测试方法中,这可能会出现问题。

我想知道在 TestCase 子类的方法中是否需要考虑手动异常处理。

因为如果我在 try-catch 中包装一个块,如果失败,测试会返回 OK 并且不会失败:

    def test_simulate_requests(self):
        """
        Simulate requests to a url
        """
        try:
           response = self.client.get('/adress/of/page/')
           self.assertEqual(response.status_code, 200)
        except Exception as e:
            print("error: ", e)

在此类测试中是否应始终避免异常处理?

标签: pythondjangounit-testing

解决方案


答案的第一部分:

正如您所说的那样,在实际测试之前需要一些逻辑。属于单元测试的代码可以分为四个部分(我在下面使用 Meszaros 的术语):设置、练习、验证、拆卸。通常,测试用例的代码是这样构造的,即四个部分的代码被清晰地分开并以精确的顺​​序出现——这被称为四阶段测试模式。

练习阶段是测试的核心,在此执行应在测试中检查的功能。该设置确保这发生在明确定义的上下文中。因此,您在此术语中所描述的是在设置过程中出现故障的情况。这意味着,未满足有意义地执行要测试的功能所需的先决条件。

这是一种常见的情况,这意味着您实际上需要能够区分测试的三种结果:测试可以成功通过,可以失败,或者只是没有意义。

幸运的是,python 中有一个答案:您可以跳过测试,如果跳过测试,则会记录下来,但既不是失败也不是成功。跳过测试可能是处理示例中所示情况的更好方法。这是一个小代码片段,演示了一种跳过测试的方法:

import unittest
class TestException(unittest.TestCase):
   def test_skipTest_shallSkip(self):
      self.skipTest("Skipped because skipping shall be demonstrated.")

答案的第二部分:

您的测试似乎有一些不确定的元素。可以抛出异常(self.client.get但只是有时 - 有时不会)。这意味着您无法控制测试执行期间的上下文。在单元测试中,您应该尽量避免这种情况。您的测试应该具有确定性的行为。

实现此目的的一种典型方法是将代码与导致不确定性的组件隔离开来,并在测试期间用模拟替换这些组件。模拟的行为完全由测试代码控制。因此,如果您的代码使用某些组件进行网络访问,您将模拟该组件。然后,在某些测试用例中,您可以指示 mock 模拟成功的网络通信以查看组件如何处理此问题,而在其他测试中,您可以指示 mock 模拟网络故障以查看组件如何应对这种情况。


推荐阅读