我有一个使用unittest测试模块的脚本.当我使用python控制台运行脚本时,我得到输出:
test_equal (__main__.TestOutcome) ... ok
test_win_amount (__main__.TestOutcome) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Run Code Online (Sandbox Code Playgroud)
但是,在使用IPython控制台运行相同的脚本时,我没有得到任何输出.
我使用以下命令来运行我的脚本,
suite = unittest.TestLoader().loadTestsFromTestCase(TestOutcome)
unittest.TextTestRunner(verbosity=2).run(suite)
Run Code Online (Sandbox Code Playgroud)
任何想法,如果这可能是由于IPython设置?
我正在尝试用Django/unittest学习单元测试.
这些是我的模型的简单版本:
class Device(models.Model):
name = models.CharField(max_length=100)
def get_ips(self):
return DeviceIP.objects.filter(device=self.id)
class DeviceIP(models.Model):
ip = models.GenericIPAddressField()
device = models.ForeignKey(Device)
Run Code Online (Sandbox Code Playgroud)
这是我提出的测试代码:
from django.test import TestCase
class DeviceTest(TestCase):
def test_get_ips(self):
device = Device()
device.name = 'My Device'
ip1 = DeviceIP()
ip1.ip = '127.0.0.1'
ip1.device = device
ip1.save()
ip2 = DeviceIP()
ip2.ip = '127.0.0.2'
ip2.device = device
ip2.save()
ip3 = DeviceIP()
ip3.ip = '127.0.0.3'
ip3.device = device
ip3.save()
self.assertEqual(device.get_ips(), [ip1, ip2, ip3])
Run Code Online (Sandbox Code Playgroud)
测试结果失败,因为AssertionError即使字符串表示device.get_ips()和[ip1, ip2, ip3]相同.
如果我尝试使用self.assertListEqual …
我有一个基于类的视图
class HomePage(View):
def get(self, request):
return HttpResponse('<p>This is content.</p>')
Run Code Online (Sandbox Code Playgroud)
和url-pattern定义如下:
urlpatterns = patterns('',
url(r'^$', HomePage.as_view()),
)
Run Code Online (Sandbox Code Playgroud)
为了这个模式解析为当前的视图函数,我写了一个这样的测试:
class HomePageTest(TestCase):
def test_root_url_resolves_to_home_page_view(self):
found = resolve('/')
self.assertIsInstance(found.func, HomePage)
Run Code Online (Sandbox Code Playgroud)
通过运行此单元测试,我收到以下错误:
self.assertIsInstance(found.func, HomePage)
AssertionError: <function HomePage at 0x7f85dd2c7840> is not an instance of <class 'web.views.HomePage'>
Run Code Online (Sandbox Code Playgroud)
任何想法如何测试这种情况?
我正在尝试理解使用context-manager(带语句)对代码进行单元测试的正确方法.
这是我的示例代码:
class resources():
def __init__(self):
self.data = 'at-init'
def __enter__(self):
self.data = 'at-enter'
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.data = 'at-exit'
Run Code Online (Sandbox Code Playgroud)
这是我的unittest代码:
import unittest
import ctxmgr
class TestResources(unittest.TestCase):
def setUp(self):
pass
def test_ctxmgr(self):
with ctxmgr.resources as r:
self.assertEqual(r.data, 'at-enter')
Run Code Online (Sandbox Code Playgroud)
示例代码运行正常,但上面的unittest代码失败,
======================================================================
ERROR: test_ctxmgr (__main__.TestResources)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_ctxmgr.py", line 12, in test_ctxmgr
with ctxmgr.resources as r:
AttributeError: __exit__
----------------------------------------------------------------------
Ran 1 test in 0.003s
FAILED (errors=1)
Run Code Online (Sandbox Code Playgroud)
导致此错误的原因是什么?我错过了什么?
Python unittest模块似乎假设一个项目的目录结构,其中有一个项目根级目录,其中包含源代码和该目录下的测试.
但是,我想在我的~/bin目录中编写Python脚本并在另一个目录中测试它(比方说~/dev/tests).有没有办法让我使用命令行界面运行单元测试,而无需设置我的PYTHONPATH环境变量和创建__init__.py文件等等?
这是一个展示我想要的简单例子:
~/bin/candy:
#!/usr/bin/env python
def candy():
return "candy"
if __name__ == '__main__':
print candy()
Run Code Online (Sandbox Code Playgroud)
~/dev/tests/test_candy.py:
#!/usr/bin/env python
import unittest
import candy
class CandyTestCase(unittest.TestCase):
def testCandy(self):
candyOutput = candy.candy()
assert candyOutput == "candy"
Run Code Online (Sandbox Code Playgroud)
我注意到如果出现以下情况,可以很方便
candy.py和test_candy.py)我可以使用unittest模块运行python 来执行以下操作,而无需在我的环境中明确设置任何内容:
~/candy).test_candy有py作为扩展名.candy和test_candy.py不共享一个共同的根(我的主目录除外).如果通过简单的调用python -m unittest无法做到这一点,那么实现这一目标的最简单方法是什么?
我知道如何断言已生成日志消息,但我似乎无法弄清楚如何断言未生成日志消息。这是我现在的单元测试(已清理)。请注意,XYZ 类将记录器作为参数,并且test_check_unexpected_keys_found按预期通过。
import unittest
import logging
class TestXYZ(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.test_logger = logging.getLogger('test_logger')
cls.test_logger.addHandler(logging.NullHandler())
def test_check_unexpected_keys_found(self):
test_dict = {
'unexpected': 0,
'expected1': 1,
'expected2': 2,
}
xyz = XYZ(self.test_logger)
with self.assertLogs('test_logger', level='WARNING'):
xyz._check_unexpected_keys(test_dict)
def test_check_unexpected_keys_none(self):
test_dict = {
'expected1': 1,
'expected2': 2,
}
xyz = XYZ(self.test_logger)
xyz._check_unexpected_keys(test_dict)
# assert that 'test_logger' was not called ??
Run Code Online (Sandbox Code Playgroud)
我尝试使用 unittest.patch 像这样:
with patch('TestXYZ.test_logger.warning') as mock_logwarn:
xyz._check_unexpected_keys(test_dict)
self.assertFalse(mock_logwarn.called)
Run Code Online (Sandbox Code Playgroud)
但我得到
导入错误:没有名为“TestXYZ”的模块我也尝试了一些变体,但一无所获。
有谁知道如何处理这个?
我正在按照python unittest进行一些测试,并使用发现功能将测试打包到套件中。但是,当我尝试使用unittest运行测试时,出现此错误:
Traceback (most recent call last):
File "D:/Project/run_tests.py", line 12, in <module>
suite2 = unittest.defaultTestLoader.discover(dir2, pattern='test*.py')
File "C:\Python\Python36-32\lib\unittest\loader.py", line 338, in discover
raise ImportError('Start directory is not importable: %r' % start_dir)
ImportError: Start directory is not importable: 'D:\\Project\\dir2'
Run Code Online (Sandbox Code Playgroud)
这是run_tests.py的样子:
import unittest
if __name__ == "__main__":
dir1 = "./test1"
suite1 = unittest.defaultTestLoader.discover(dir1, pattern='test*.py')
runner1 = unittest.TextTestRunner()
runner1.run(suite1)
dir2 = "./tes2"
suite2 = unittest.defaultTestLoader.discover(dir2, pattern='test*.py')
runner2 = unittest.TextTestRunner()
runner2.run(suite2)
Run Code Online (Sandbox Code Playgroud) 我对打破单元测试的功能进行了一些更改.以前我有一个包含函数request_url的common.py:
import requests
def request_url(method, url):
return _request_url(method, url)
def _request_url(method, url):
return requests.request(method, url)
Run Code Online (Sandbox Code Playgroud)
这是测试:
@mock.patch("requests.request", autospec=True)
def test_request_url_200(self, mock_request):
response = mock.MagicMock()
response.status_code = 200
method = mock.sentinel.method
path = "url"
result = common.request_url(
method,
path
)
self.assertListEqual([
mock.call(
mock.sentinel.method,
"url"
),
], list(mock_request.mock_calls))
self.assertListEqual([mock.call.raise_for_status()], list(response.mock_calls))
self.assertEqual(mock_request.return_value, result)
Run Code Online (Sandbox Code Playgroud)
在功能发生变化之后,我首先发起了一个会话,安装了一个TLS适配器,然后调用会话的请求函数,而不是简单地调用requests.request:
def _request_url(method, url):
session = requests.session()
adapter = TlsAdapter(ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
session.mount("https://", adapter)
return response = session.request(method, url)
Run Code Online (Sandbox Code Playgroud)
在这里,我不确定如何完全模拟session.request,因为这可以通过session变量获得.我尝试修补requests.session.request,但这在这里不起作用.
有谁知道如何嘲笑这个功能?
谢谢!
这是我进行链式数据库查询调用的一种方法。
import math
def get_all_keys():
db_session = DBSession()
keys = db_session.query(SomeClass).all()
Run Code Online (Sandbox Code Playgroud)
我应该嘲笑DBSession().query(SomeClass).all()。我尝试了一些,但没有任何效果。这是我的试验。
@patch('app.modules.somemodule.DBSession')
def test_asd(self, DBSession):
DBSession.execute.query.execute.all.return_value = [1, 2, 3]
self.assertListEqual(DBSession.query('qwe').all(), [1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
在这次尝试中,如果我尝试打印,DBSession()我会得到一个MagicMock看起来不错的对象。但是当我运行时pytest出现以下错误。
self = <test_some_module.SomeModuleTests testMethod=test_asd>, DBSession = <MagicMock name='DBSession' id='140028663111976'>
@patch('app.modules.somemodule.DBSession')
def test_asd(self, DBSession):
DBSession.execute.query.execute.all.return_value = [1, 2, 3]
print(DBSession().query('qwe').all())
> self.assertListEqual(DBSession.query('qwe').all(), [1, 2, 3])
E AssertionError: First sequence is not a list: <MagicMock name='DBSession.query().all()' id='140028662649184'>
tests/test_some_module.py:21: AssertionError
Run Code Online (Sandbox Code Playgroud)
好像我在嘲笑时做错了什么。我的错误是什么?我检查了文档。
python unit-testing sqlalchemy python-unittest python-unittest.mock
我目前正在运行一个单元测试脚本,它在控制台中成功传递了各种指定的测试,并带有一个唠叨的ImportWarning消息:
...../lib/python3.6/importlib/_bootstrap.py:219: ImportWarning: can't resolve package from __spec__ or __package__, falling back on __name__ and __path__
return f(*args, **kwds)
....
----------------------------------------------------------------------
Ran 7 tests in 1.950s
OK
Run Code Online (Sandbox Code Playgroud)
该脚本使用以下主函数运行:
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
我已经读过,当脚本被调用时,警告会被压抑:
python -W ignore:ImportWarning -m unittest testscript.py
Run Code Online (Sandbox Code Playgroud)
但是,有没有办法在脚本本身中指定此忽略警告,以便-W ignore:ImportWarning每次运行testscript时都不必调用?
提前致谢.
python-unittest ×10
python ×7
unit-testing ×4
python-3.x ×3
django ×2
django-views ×1
ipython ×1
logging ×1
mocking ×1
sqlalchemy ×1