GVKun编程网logo

Python 单元测试 - 如何在 setUpClass 内部断言?(python assert断言)

2

在这里,我们将给大家分享关于Python单元测试-如何在setUpClass内部断言?的知识,让您更了解pythonassert断言的本质,同时也会涉及到如何更有效地pythonunittestset

在这里,我们将给大家分享关于Python 单元测试 - 如何在 setUpClass 内部断言?的知识,让您更了解python assert断言的本质,同时也会涉及到如何更有效地python unittest setUp 和 setUpClass 区别、Python unittest-setUpClass()给我带来麻烦-为什么我不能这样继承?、python – 单元测试(烧瓶 – 静止)GET API调用时获得500内部服务器错误、Python 一课一练(单元测试 nose 包使用)的内容。

本文目录一览:

Python 单元测试 - 如何在 setUpClass 内部断言?(python assert断言)

Python 单元测试 - 如何在 setUpClass 内部断言?(python assert断言)

如何解决Python 单元测试 - 如何在 setUpClass 内部断言?

在我的 setUpClass 中,我想一次在数据库中创建一个资源,然后将其用于类中的所有测试。

setUpClass 中创建资源后,我想立即对其执行断言。但是,我不确定如何在 setUpClass 中调用断言,因为所有断言函数都是实例方法,而不是类方法。

  1. import unittest
  2. class TestFoo(unittest.TestCase):
  3. @classmethod
  4. def setUpClass(cls):
  5. cls.foo = cls.make_foo(name=''bar'')
  6. # How would I assert that cls.foo[''name''] == ''bar''?
  7. # The following does not work,as the assertEquals function is not a class method
  8. # cls.assertEquals(cls.foo[''name''],''bar'')
  9. @classmethod
  10. def make_foo(cls,name):
  11. # Calls a POST API to create a resource in the database
  12. return {''name'': name}
  13. def test_foo_0(self):
  14. # Do something with cls.foo
  15. pass
  16. def test_foo_1(self):
  17. # do something else with cls.foo
  18. pass

我能想到的唯一替代方法是在 setUpClass 中引发异常:

  1. @classmethod
  2. def setUpClass(cls):
  3. cls.foo = cls.make_foo(name=''bar'')
  4. if cls.foo[''name''] != ''bar'':
  5. raise Exception("Failed to create resource,cannot do the tests")

当然,我不想从每个测试中调用断言,因为这只会重复代码。


编辑:我认为这个 workaround 不好,因为失败消息将指向 self.assertFalse(self.flag) 行,而不是 if cls.foo[''name''] ~= ''bar'' 行。此外,如果您创建了多个资源,则需要多个标志来消除歧义。

  1. flag=False
  2. @classmethod
  3. def setUpClass(cls):
  4. cls.foo = cls.make_foo(name=''bar'')
  5. if cls.foo[''name''] != ''bar'':
  6. cls.flag=True
  7. def setUp(self):
  8. self.assertFalse(self.flag)

python unittest setUp 和 setUpClass 区别

python unittest setUp 和 setUpClass 区别

import unittest


class Test(unittest.TestCase):
    def setUp(self):
        print("start!=======")

    def test01(self):
        print("执行测试用例01")

    def test03(self):
        print("执行测试用例03")

    def test02(self):
        print("执行测试用例02")

    def addtest(self):
        print("add方法")

    def tearDown(self):
        print("end-------------------!")


if __name__ == "__main__":
    unittest.main()

每次执行测试用例的时候都会去执行一次setUp 和tearDown,执行脚本结果如下

"D:\Program Files\Python\Python35\python.exe" "D:\Program Files\JetBrains\PyCharm 2017.2.3\helpers\pycharm\_jb_nosetest_runner.py" --target test.py::Test
Testing started at 21:35 ...
Launching Nosetest with arguments D:\Program Files\JetBrains\PyCharm 2017.2.3\helpers\pycharm\_jb_nosetest_runner.py test.py:Test in D:\workspace\90duAuto

..start!=======
执行测试用例01
end-------------------!
start!=======
执行测试用例02
end-------------------!
start!=======
执行测试用例03
end-------------------!
.
----------------------------------------------------------------------
Ran 3 tests in 0.016s

OK

Process finished with exit code 0

下面我们在看下setUpClass和tearDownClass,而这个只有在开始和结束的时候执行一次

import unittest


class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("start===============!")

    def test01(self):
        print("执行测试用例01")

    def test03(self):
        print("执行测试用例03")

    def test02(self):
        print("执行测试用例02")

    def addtest(self):
        print("add方法")

    @classmethod
    def tearDownClass(cls):
        print("end!===================")


if __name__ == "__main__":
    unittest.main()

 

Python unittest-setUpClass()给我带来麻烦-为什么我不能这样继承?

Python unittest-setUpClass()给我带来麻烦-为什么我不能这样继承?

我有如下的单元测试代码:

import unittestclass MyUnitTest(unittest.TestCase):    def setUpClass(self):        do_something_expensive_for_all_sets_of_tests()class MyFirstSetOfTests(MyUnitTest):    def setUpClass(self):        super(MyFirstSetOfTests, self).setUpClass()        do_something_expensive_for_just_these_first_tests()    def test_one(self):        ...    def test_two(self):        ...class MySecondSetOfTests(MyUnitTest):    def setUpClass(self):        super(MySecondSetOfTests, self).setUpClass()        do_something_expensive_for_just_these_second_tests()    def test_one(self):        ...    def test_two(self):        ...if __name__ == ''__main__'':    unittest.main()

当我尝试运行此代码时,出现如下错误:

======================================================================ERROR: setUpClass (__main__.MyFirstSetOfTests)----------------------------------------------------------------------TypeError: unbound method setUpClass() must be called with MyFirstSetOfTests instance as first argument (got nothing instead)----------------------------------------------------------------------

答案1

小编典典

setUpClass 必须
是一个类方法。从文档中:

在运行单个类中的测试之前调用的类方法。setUpClass以类作为唯一参数调用,并且必须修饰为classmethod()

@classmethoddef setUpClass(cls):    ...

有关更多详细信息,请参见类和模块装置。

您的版本缺少@classmethod装饰器:

class MyUnitTest(unittest.TestCase):    @classmethod    def setUpClass(cls):        do_something_expensive_for_all_sets_of_tests()class MyFirstSetOfTests(MyUnitTest):    @classmethod    def setUpClass(cls):        super(MyFirstSetOfTests, cls).setUpClass()        do_something_expensive_for_just_these_first_tests()

引发错误是因为MyFirstSetOfTests.setUpClass() 上而不是在实例上调用了该错误,但是您没有将方法标记为a
classmethod,因此未在自动self参数中传递该错误。在上面的更新代码中,我cls改为使用该名称来反映名称引用了类对象。

python – 单元测试(烧瓶 – 静止)GET API调用时获得500内部服务器错误

python – 单元测试(烧瓶 – 静止)GET API调用时获得500内部服务器错误

我已经从我的烧瓶式API模块中单独测试了所有方法.现在我想通过实际进行API调用来测试get方法.我期待这个测试的错误400.

我的资源类

class Response(Resource):

    @marshal_with(response_params_get_responses_on_job)
    def get(self,filter_name=None):
        try:
            response = self.process_get_request(filter_name)
            if not response['users']:
                raise MyValidationError("No data found")
            return response
        except MyValidationError as err:
            abort(404,message=err)
        except ValueError as mistake:
            abort(400,message=mistake)

我的单位测试

# Todo - Failing!
@mock.patch('application.resources.response.Response.process_get_request',autospec=True)
def test_get_400(self,process_get_request_mock):
    process_get_request_mock.side_effect = ValueError("some error")
    app = Flask(__name__)
    app.debug = True
    api = Api(app,prefix='/api/v2')
    api.add_resource(Response,'/user/responses',endpoint='job_responses')
    api.init_app(app)
    with app.test_client() as client:
        resp = client.get('/api/v2/user/responses',environ_base={'HTTP_USER_AGENT': 'Chrome'},headers={'Content-type': 'application/json'})
        self.assertEqual(resp.status_code,400)

我的测试失败,因为我得到的响应是错误500

AssertionError: 500 != 400

堆栈跟踪

Failure
Traceback (most recent call last):
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/mock.py",line 1201,in patched
return func(*args,**keywargs)
File "/home/hussain/workspace/my-app/tests/unittests/test_Response.py",line 38,in test_get_400
headers={'Content-type': 'application/json'})
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/werkzeug/test.py",line 774,in get
return self.open(*args,**kw)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/testing.py",line 108,in open
follow_redirects=follow_redirects)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/werkzeug/test.py",line 742,in open
response = self.run_wsgi_app(environ,buffered=buffered)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/werkzeug/test.py",line 659,in run_wsgi_app
rv = run_wsgi_app(self.application,environ,line 867,in run_wsgi_app
app_rv = app(environ,start_response)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py",line 1836,in __call__
return self.wsgi_app(environ,line 1820,in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_cors/extension.py",line 110,in wrapped_function
return cors_after_request(app.make_response(f(*args,**kwargs)))
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py",line 270,in error_router
return original_handler(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py",in error_router
return original_handler(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py",line 1403,in handle_exception
reraise(exc_type,exc_value,tb)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py",line 267,in error_router
return self.handle_error(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_restful/__init__.py",in error_router
return self.handle_error(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py",line 1817,in wsgi_app
response = self.full_dispatch_request()
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask/app.py",line 1477,in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/hussain/workspace/venv/local/lib/python2.7/site-packages/flask_cors/extension.py",line 1363,in handle_user_exception
assert exc_value is e
AssertionError

通过在get方法中放置一个调试点,我看到执行一直持续到中止(400,消息=错误).

然后发生了什么?为什么我的测试失败了?

最佳答案
我一直认为问题出在我的单元测试中.我错了!

问题出在我的代码中.正如米歇尔所说,我的测试已经找到了.

中止方法中的消息kwarg应该是一个字符串,而是我将它传递给异常对象.所以我在中止线上得到了一个例外.

所以我纠正了它

abort(400,message=mistake.message)

或者我也可以写

abort(400,message=str(mistake))

现在我的考试正在通过.

Python 一课一练(单元测试 nose 包使用)

Python 一课一练(单元测试 nose 包使用)

还记得我们的 Python 工程结构吗? 上图一张: 我们把编写的测试脚本放到 “tests” 文件夹下,而工程源文件则放到 “lexcion” 文件夹下。

  1. 在 lexicon 目录下新建文件 ltest.py:
# -*- coding: utf-8 -*-
# 自定义一个异常类
class LTestError(Exception):
    pass

class ltest(object):

    items = [''a'', ''b'', 4]

    def item(self, a, b):
        if a != None and b != None:
            return a + b
        else:
            raise LTestError("您输入的内容为空")

2. 在‘tests’目录下新建文件‘ltest_tests.py’文件,此处文件命名格式非常重要,必须按照测试目标文件(‘ltest.py’)来确定,否则执行测试脚本会失败,命名格式是:“目标文件_tests.py”。

# -*- coding:utf-8 -*-
# 测试脚本的文件命名非常严格,nose包就是按照名字来寻找相应的测试目标文件
# 测试脚本命名规则:目标文件名_tests.py
# nose包导入格式
from nose.tools import *
# 笔者已知导入对类的测试文件格式分两种:
# 1.from 目录名.文件名 import 对象(对象可以直接在测试文件中使用)
# 2.from 目录名.文件名 import *(对象需要先实例化才能使用)
from lexicon.ltest import *

def item_test():
    lt = ltest()
    item = lt.item(3, 6)
    assert_equal(item, 9)

关于Python 单元测试 - 如何在 setUpClass 内部断言?python assert断言的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于python unittest setUp 和 setUpClass 区别、Python unittest-setUpClass()给我带来麻烦-为什么我不能这样继承?、python – 单元测试(烧瓶 – 静止)GET API调用时获得500内部服务器错误、Python 一课一练(单元测试 nose 包使用)等相关内容,可以在本站寻找。

本文标签: