Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在单元测试python中的失败步骤中运行测试用例_Python_Python Unittest - Fatal编程技术网

在单元测试python中的失败步骤中运行测试用例

在单元测试python中的失败步骤中运行测试用例,python,python-unittest,Python,Python Unittest,我有一个Python测试套件,其中有几个使用单元测试框架的测试用例。我使用的是导入单元测试 若测试用例中的一个测试步骤失败,测试用例将转到teardown类。即使有一个测试用例失败,我也希望继续测试用例的其余部分 单元测试的默认行为:如果任何测试步骤失败,它将分解类并结束测试用例 测试步骤:我的意思是断言相等,就像这个内置过程,它定义了是失败还是通过 class TestFoo(unittest.TestCase): def test_case_1(self): self

我有一个Python测试套件,其中有几个使用单元测试框架的测试用例。我使用的是导入单元测试

若测试用例中的一个测试步骤失败,测试用例将转到teardown类。即使有一个测试用例失败,我也希望继续测试用例的其余部分

单元测试的默认行为:如果任何测试步骤失败,它将分解类并结束测试用例


测试步骤:我的意思是断言相等,就像这个内置过程,它定义了是失败还是通过

class TestFoo(unittest.TestCase):
    def test_case_1(self):
        self.assertEqual(1, 2)
        self.assertEqual(1, 3)
        self.assertEqual(1, 1)
AssertionError: Tuples differ: (1, 1, 1) != (2, 3, 1)

First differing element 0:
1
2

- (1, 1, 1)
?  ^  ^

+ (2, 3, 1)
?  ^  ^
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")
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")
第一个断言将失败,下面的断言将不运行,但测试将结束,并将调用self.tearDown方法

当你断言的时候,你的意思是这个条件是绝对正确的,或者继续下去没有意义。你的意思是:“如果一个不等于两个,那么生活就没有意义了……”

大多数时候都是这样。例如,如果结果代码不是预期的,则不希望检查RESTAPI的结果体

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

class TestFoo(unittest.TestCase):
    def test_case_1(self):
        self.assertEqual((1, 1, 1), (2, 3, 1))
然后您将得到如下输出:

class TestFoo(unittest.TestCase):
    def test_case_1(self):
        self.assertEqual(1, 2)
        self.assertEqual(1, 3)
        self.assertEqual(1, 1)
AssertionError: Tuples differ: (1, 1, 1) != (2, 3, 1)

First differing element 0:
1
2

- (1, 1, 1)
?  ^  ^

+ (2, 3, 1)
?  ^  ^
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")
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")
从python文档中:

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

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

[编辑]——在对这个问题进行了一些澄清之后,对其本身进行了评论,但还没有一个代码示例


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

class TestFoo(unittest.TestCase):
    def test_case_1(self):
        self.assertEqual(1, 2)
        self.assertEqual(1, 3)
        self.assertEqual(1, 1)
AssertionError: Tuples differ: (1, 1, 1) != (2, 3, 1)

First differing element 0:
1
2

- (1, 1, 1)
?  ^  ^

+ (2, 3, 1)
?  ^  ^
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")
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")
你可以做很多(骇客的)事情,比如计算失败次数,而不是在最后断言和断言计数器值:

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)
或者创建一个helper函数来断言、记录、计数和吞咽异常,然后在最后断言计数器。有很多可能性

然而,一般来说,最好的(最简单、清晰、枯燥的)方式是评论中已经提出的方式:

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)


我肯定我没有涵盖你实际问题的所有可能性,但这可能有助于说明你的开放式问题有多少可能性。所以,请澄清您的问题。

子测试如何

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 TestFoo(unittest.TestCase):
    def test_case_1(self):
        self.assertEqual(1, 2)
        self.assertEqual(1, 3)
        self.assertEqual(1, 1)
AssertionError: Tuples differ: (1, 1, 1) != (2, 3, 1)

First differing element 0:
1
2

- (1, 1, 1)
?  ^  ^

+ (2, 3, 1)
?  ^  ^
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")
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")

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

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

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")

对于正常行为,如果出于某种原因
r
None
您的代码会提前退出,并显示一条有用的消息:
AssertionError:意外无
。如果没有它,您的代码将得到以下更不透明的异常:
AttributeError:'NoneType'对象没有属性“status\u code”

它总是在其他测试中继续。我不知道你为什么会有不同的体验。你能提供你的测试代码吗?这会让你的问题更容易回答。我不确定我是否完全理解你的问题,因为我总是让我的测试继续进行,即使测试失败。我从来没有遇到过这样的问题。考虑到已经有几个答案了,也许我遗漏了一个我不理解的关键部分?除非您在一个测试方法中引用多个断言?我明白您的意思,但是在编写测试用例时,有很多测试步骤。有时我们不希望在失败的步骤停止,而是希望测试继续并打印失败的消息。这意味着您在一个测试中测试多个内容。不要这样做。在一个测试中,测试到第一个故障点,以确保其正常工作。在另一个测试中,运行相同的设置,但不要检查该故障(另一个测试正在处理该故障),而是检查下一个故障。等等这也可能是您正在测试的函数太大的证据。如果是这种情况,Nitesh就好像Adam已经回答过:只需将测试用例分成多个步骤。此外,如果我没有理解你的观点,那么请澄清你的问题,并添加已经询问过的示例。看来亚当·巴恩斯应该被接受。看起来亚当·巴恩斯的评论应该是公认的答案,现在尼特什在这些评论中对问题做了一些澄清。尽管它没有做到问题所要求的(这一点无论如何都不清楚),亚当·巴恩斯的评论是最好的方法,这就是最佳实践应该做的事情,这取决于你的案例,是非常有趣的。具体来说,对于url请求测试,我会在一个测试用例中保持简单,如果代码错误,就不检查文本。当然,这是一个有效的例子。