我目前正在学习Python REST API(辅助项目)。我一直在阅读RealPython,Python Requests文档等中的许多教程。我发现了这篇关于如何在Python(Correct way to try/except using Python requests module?)中正确编写try / except的文章。令我困惑的是,如何为这样的函数创建单元测试,因为它不返回任何内容。有帮助吗?
def google_do_something(blahblah):
url='http://www.google.com/' + blahblah
try:
r = requests.get(url,timeout=3)
r.raise_for_status()
except requests.exceptions.HTTPError as errh:
print (errh)
except requests.exceptions.ConnectionError as errc:
print (errc)
except requests.exceptions.Timeout as errt:
print (errt)
except requests.exceptions.RequestException as err:
print (err)
我可以想到这一点,但是我不知道该怎么断定。
def test_google_do_something():
g = google_do_something('blahblah')
# assert??
答案 0 :(得分:2)
我不确定您的方法是不是一个好主意(只是在出现错误的情况下打印某些内容),但是您可以模拟print函数以查看它是否真的被调用(以及带有什么参数):
https://docs.python.org/3/library/unittest.mock.html?highlight=mock#module-unittest.mock
编辑:
据我所知,使用模拟程序有些棘手。您将不得不在当前模块中模拟打印功能。也许是这样的(未测试... ):
from unittest.mock import patch
from unittest import TestCase
class TestGoogleDoSomething(TestCase)
@patch("nameOfYourModule.print")
def test_google_do_something(self, print_mock): # the decorator will pass the mock object into the function
g = google_do_something('blahblah')
print_mock.assert_called_with("your error message here ...")
答案 1 :(得分:1)
Python提供了几种单元测试框架。 try / except块可以很好地处理错误,但是如果要对它进行单元测试,则仍然需要在调用周围进行单独的单元测试。
您确实有可以测试的东西,您可以将其返回并在单元测试中进行测试。
使用unittest的示例单元测试:
import unittest
import requests
class RestCalls():
def google_do_something(blahblah):
url= blahblah
try:
r = requests.get(url,timeout=1)
r.raise_for_status()
return r.status_code
except requests.exceptions.Timeout as errt:
print (errt)
raise
except requests.exceptions.HTTPError as errh:
print (errh)
raise
except requests.exceptions.ConnectionError as errc:
print (errc)
raise
except requests.exceptions.RequestException as err:
print (err)
raise
class TestRESTMethods(unittest.TestCase):
def test_valid_url(self):
self.assertEqual(200,RestCalls.google_do_something('http://www.google.com/search'))
def test_exception(self):
self.assertRaises(requests.exceptions.Timeout,RestCalls.google_do_something,'http://localhost:28989')
if __name__ == '__main__':
unittest.main()
执行应显示(对此帖子进行了一些编辑,更新后的输出包含在帖子底部):
> python .\Tests.py
.
----------------------------------------------------------------------
Ran 1 test in 0.192s
OK
如果您断言了与请求不同的响应代码,则它将失败(该请求仅返回http响应代码):
python .\Tests.py
F
======================================================================
FAIL: test_upper (__main__.TestStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
File ".\Tests.py", line 25, in test_upper
self.assertEqual(404,RestCalls.google_do_something('search'))
AssertionError: 404 != 200
----------------------------------------------------------------------
Ran 1 test in 0.245s
FAILED (failures=1)
希望。
编辑:包括的异常测试。您可以通过在except块中加入 raise 来进行测试,运行后将显示以下内容:
> python .\Tests.py
HTTPConnectionPool(host='localhost', port=28989): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x03688598>, 'Connection to localhost timed out. (connect timeout=1)'))
..
----------------------------------------------------------------------
Ran 2 tests in 2.216s
OK
参考:
答案 2 :(得分:0)
似乎您使用的是print而不是所有异常处理程序。我认为这不是一个好习惯。从我的角度来看,如果不确定现在如何处理这些异常,我希望再次提出这些异常。
话虽如此,当发生任何错误时,都会抛出异常;如果没有例外,则表示此功能运行良好。因此,您可以在此基础上设计单元测试用例。