在单元测试python中出现故障步骤时运行测试用例

时间:2018-01-03 06:45:03

标签: python python-unittest

我在Python中有一个testSuite,有几个使用单元测试框架的测试用例。我正在使用导入单元测试

如果测试用例中的测试步骤失败,则测试用例将进入拆解类。即使一个测试用例失败,我还想继续测试用例的其余部分。

单元测试的默认行为:如果任何测试步骤失败,它将拆除课程并结束测试用例。

测试步骤:我的意思是断言相等并且喜欢这个内置的proc,它定义了它是失败还是传递

3 个答案:

答案 0 :(得分:6)

考虑到你有这样的事情:

class TestFoo(unittest.TestCase):
    def test_case_1(self):
        self.assertEqual(1, 2)
        self.assertEqual(1, 3)
        self.assertEqual(1, 1)

第一个断言将失败,并且以下的断言将不会运行,但测试将结束,而将调用self.tearDown方法。

当你断言你的意思是条件是强有力的,或者继续没有意义。你的意思是:“如果一个人不等于二,那么生活就再也没有意义......”:)

大多数情况都是如此。如果结果代码不是预期的,例如,您不希望检查rest API的结果体。

你应该在一步中测试所有的平等,以确保它们都将被检查。您可以将它们分组为元组,例如:

class TestFoo(unittest.TestCase):
    def test_case_1(self):
        self.assertEqual((1, 1, 1), (2, 3, 1))

然后你会得到这样的输出:

AssertionError: Tuples differ: (1, 1, 1) != (2, 3, 1)

First differing element 0:
1
2

- (1, 1, 1)
?  ^  ^

+ (2, 3, 1)
?  ^  ^

来自python文档:

  

assertEqual(first,second,msg = None)   测试第一和第二是相等的。如果值不相等,    测试将失败

     

此外,如果第一个和第二个是完全相同的类型和一个   list,tuple,dict,set,frozenset或str或子类的任何类型   使用addTypeEqualityFunc() 注册特定于类型的相等性   将调用函数以生成更有用的默认值   错误消息 (另请参见特定于类型的方法列表)。

https://docs.python.org/2/library/unittest.html#unittest.TestCase.assertEqual https://docs.python.org/3.6/library/unittest.html#unittest.TestCase.assertEqual

[编辑] - 在对这个问题进行一些澄清之后发表评论,但还没有代码示例。

考虑到你有不同的东西,比如:

class TestBar(unittest.TestCase):
    def test_rest_api_foo(self):
        r = request("http://dummyurl")
        self.assertEqual(r.status_code, 200)
        self.assertEqual(r.text, "hello world")

你可以做许多(hacky)事情,比如计算失败,而不是在最后断言和断言计数器值:

class TestBar(unittest.TestCase):
    def test_rest_api_foo(self):
        r = request("http://dummyurl")
        errors = (r.status_code != 200)
        errors += (r.text != "hello world")
        self.assertEqual(errors, 0)

或创建一个辅助函数来断言,记录,计数和吞下异常,然后在结尾处断言计数器。有很多种可能性。

然而,总的来说,最好的(最简单,最清楚,最无聊的)方式将是评论中已经提出的方式:

class TestBar(unittest.TestCase):
    def test_rest_api_status_code_foo(self):
        r = request("http://dummyurl")
        self.assertEqual(r.status_code, 200)

    def test_rest_api_text_foo(self):
        r = request("http://dummyurl")
        self.assertEqual(r.text, "hello world")

请注意,在此特定示例中,单个测试用例会更好。

无论如何,这将为您提供单独的错误消息,同时保持代码简单易维护。

如果您的问题是因为在每个测试用例之后调用tearDown方法,那么您可以使用tearDownClass进行清理(python3或来自unittest2)。

我确信我没有在这里覆盖您实际问题的所有可能性,但也许这对于展示您的未解决问题有多少可能性非常有用。所以,请澄清你的问题。

答案 1 :(得分:1)

subTest怎么样?

import unittest


class TestFoo(unittest.TestCase):
    def test_bar(self):
        with self.subTest('Failed'):
            self.assertEqual(5, 2 + 2)

        with self.subTest('Passed'):
            self.assertEqual(1, 1)

olivecode的示例如下所示:

class TestBar(unittest.TestCase):
    def test_rest_api_foo(self):
        r = request("http://dummyurl")

        with self.subTest('Test status code'):
            self.assertEqual(r.status_code, 200)

        with self.subTest('Test text'):
            self.assertEqual(r.text, "hello world")

答案 2 :(得分:1)

好问题!当assert*帮助程序在unittest(或pytest,一个常见的Python测试框架)失败时,没有内置的方法可以继续。

实现相同效果的最惯用的方法是同时使用比较值的dict或元组。

class TestBar(unittest.TestCase):
    def test_rest_api_foo(self):
        r = request("http://dummyurl")

        # using a tuple
        # `assertEqual` works as well, `assertTupleEqual` specifically
        # highlights which elements that are different
        self.assertTupleEqual(
            (200, "hello world"),
            (r.status_code, r.text),
        )

        # using a dict
        # `assertEqual` works as well, `assertDictEqual` specifically
        # highlights which elements that are different
        self.assertDictEquals(
            {'status': 200, 'text': "hello world"},
            {'status': r.status_code, 'text': r.text},
        )

有一个正当的理由说明您所要求的内容是不允许的。如果您的测试可以在断言失败后继续进行,那么您很可能会在线路上遇到不太明确的错误,因为环境处于意外状态。考虑:

class TestContinuesOnAssert(unittest.TestCase):
    def test_rest_api_foo(self):
        """Imagine this continues on assert"""
        r = request("http://dummyurl")
        self.assertIsNotNone(r)
        self.assertEqual(r.status_code, 200)
        self.assertEqual(r.text, "hello world")

如果出于正常行为,如果由于某种原因rNone,您的代码会提前退出,并提供有用的消息:AssertionError: unexpectedly None。没有它,您的代码将获得以下更加不透明的异常:AttributeError: 'NoneType' object has no attribute 'status_code'