所以我知道在我的单元测试中我可以模拟上下文管理器 open(),即:
with open('file_path', 'r') as stats:
Run Code Online (Sandbox Code Playgroud)
嘲笑与
with mock.patch('builtins.open', mock.mock_open(read_data=mock_json)):
Run Code Online (Sandbox Code Playgroud)
但有没有办法让我只模拟特定的文件路径?或者也许有其他方法来确保在单元测试中使用正确的路径调用上下文管理器?
我有 2 个包含测试的目录:
project/
|
|-- test/
| |
| |-- __init__.py
| |-- test_1.py
|
|-- my_submodule/
|
|-- test/
|
|-- __init__.py
|-- test_2.py
Run Code Online (Sandbox Code Playgroud)
我怎样才能运行所有测试?
python -m unittest discover .
只运行test_1.py
显然
python -m unittest discover my_submodule
只运行test_2.py
我正在使用 pytest 修补 os.makedirs 方法以进行测试。在一个特定的测试中,我想添加异常的副作用。
因此,我导入os在测试脚本中导入的对象,对其进行修补,然后在测试中设置副作用:
from infrastructure.scripts.src.server_administrator import os
def mock_makedirs(self, mocker):
mock = MagicMock()
mocker.patch.object(os, "makedirs", return_value=mock)
return mock
def test_if_directory_exist_exception_is_not_raised(self, administrator, mock_makedirs):
mock_makedirs.side_effect = Exception("Directory already exists.")
with pytest.raises(Exception) as exception:
administrator.initialize_server()
assert exception.value == "Directory already exists."
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,当在我的测试脚本中调用模拟时,副作用不再存在。在进行故障排除时,我停止了调试器中的测试,以查看我创建的模拟的 ID 值以及补丁应设置为返回值的模拟,发现它们是不同的实例:
我对 python 中的一些测试工具还比较陌生,所以这可能是我在文档中遗漏了一些东西,但是这里修补的返回的模拟不应该是我创建的模拟吗?难道是我补丁错了?
我什至调整了导入样式以makedirs直接抓取来修补它:
def mock_makedirs(self, mocker):
mock = MagicMock()
mocker.patch("infrastructure.scripts.src.server_administrator.makedirs", return_value=mock)
return mock
Run Code Online (Sandbox Code Playgroud)
我仍然遇到同样的“不同的模拟”问题。
在一个文件中(比方说parser.py)我有:
import argparse
def parse_cmdline(cmdline=None):
parser = argparse.ArgumentParser()
parser.add_argument('--first-param',help="Does foo.")
parser.add_argument('--second-param',help="Does bar.")
if cmdline is not None:
args = parser.parse_args(cmdline)
else:
args = parser.parse_args()
return vars(args)
if __name__=='__main__':
print parse_cmdline()
Run Code Online (Sandbox Code Playgroud)
果然,当从命令行调用它时,它会起作用并给我很多我期望的东西:
$ ./parser.py --first-param 123 --second-param 456
{'first_param': '123', 'second_param': '456'}
Run Code Online (Sandbox Code Playgroud)
但后来我想要unittest它,因此我写了一个test_parser.py文件:
import unittest
from parser import parse_cmdline
class TestParser(unittest.TestCase):
def test_parse_cmdline(self):
parsed = parse_cmdline("--first-param 123 --second-param 456")
self.assertEqual(parsed['first_param'],'123')
self.assertEqual(parsed['second_param'],'456')
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
然后我收到以下错误:
usage: test_parser.py [-h] [--first-param FIRST_PARAM]
[--second-param SECOND_PARAM]
test_parser.py: …Run Code Online (Sandbox Code Playgroud) 我有一个python脚本,其中包含一个unittest.TestCase,一个setUp()函数和少量的test_foo_does_bar()-type函数。
脚本结束如下:
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
当我在Spyder中运行此脚本时(请参阅下面的配置详细信息),解释器将在以下行停止:
----------------------------------------------------------------------
Ran x tests in x.xxxs
FAILED (failures=x)
Run Code Online (Sandbox Code Playgroud)
Ctrl + C或Ctrl + D都无法解救解释器并使我返回提示。从命令提示符运行的相同脚本正常终止。
这是Spyder中的错误还是我遗漏了一些东西?
设置信息: Spyder 2.2.3 Python 2.7.5 64位。Windows上的Qt 4.8.4,PyQt4(API v2)4.9.6
在我正在运行的一系列测试中nosetests,assertEqual(a,b)失败,a并且b(相当长的字符串)被逐字打印填充屏幕,混淆了其他所有内容.您可以通过将其添加到您的一个测试用例来创建类似的情况:
def test_my_long_strings(self):
self.assertEqual('a'*5000, 'b'*5000)
Run Code Online (Sandbox Code Playgroud)
我试着设置--verbosity=0和--debug-log=File,但他们都没有任何影响,这两个字符串仍印在屏幕上.
无论如何都要关闭assertEqual详细程度或将其重定向到除stderr之外的单独文件(还报告测试失败/通过)?
我有以下目录
/root
/app
/api
my_api.py
/service
my_service.py
/tests
test_api.py
Run Code Online (Sandbox Code Playgroud)
my_api.py
import app
def run_service():
app.service.my_service.service_function()
Run Code Online (Sandbox Code Playgroud)
test_api.py
@patch('app.service.my_service.service_function')
test_run_service(self,mock_service):
mock_service.return_value = 'Mock'
response = self.client.get(url_for('api.run_service')
self.assertTrue(response == expected_responce)
Run Code Online (Sandbox Code Playgroud)
以上工作.我无法弄清楚,我需要修补哪个模块,以防我想service_function在my_apy.py中导入,如下所示:
from app.service.my_service import service_function
Run Code Online (Sandbox Code Playgroud)
如果我像上面那样进行导入,模拟停止工作.
我一直熟悉Python中的unittest库,我写了几个unitest.TestCase类似于这个的:
class TestOne(unittest.TestCase):
def setUp(self):
pass
def first_test(self):
self.assertEqual('a', 'b')
def second_test(self):
self.assertEqual('a', 'b')
def third_test(self):
self.assertEqual('a', 'b')
def tearDown(self):
pass
class TestTwo(unittest.TestCase):
def setUp(self):
pass
def first_test(self):
self.assertEqual('a', 'b')
def second_test(self):
self.assertEqual('a', 'b')
def third_test(self):
self.assertEqual('a', 'b')
def tearDown(self):
pass
class TestThree(unittest.TestCase):
def setUp(self):
pass
def first_test(self):
self.assertEqual('a', 'b')
def second_test(self):
self.assertEqual('a', 'b')
def third_test(self):
self.assertEqual('a', 'b')
def tearDown(self):
pass
Run Code Online (Sandbox Code Playgroud)
现在这不是我的代码完全如此,但这是遵循的基本结构.
我知道如果我想执行一个TestCase,我可以这样做:
suite = unittest.TestLoader().loadTestsFromTestCase(TestOne)
unittest.TextTestRunner(verbosity=2).run(suite)
Run Code Online (Sandbox Code Playgroud)
但是,我一直在努力让多个TestCases同时运行.
我试过这样做:
suite = unittest.TestSuite()
suite.addTest(TestOne())
unittest.TextTestRunner(verbosity=2).run(suite) …Run Code Online (Sandbox Code Playgroud) 我发现了有关该shortDescription功能的信息,并渴望尝试一下。
shortDescription()返回测试的描述,如果未提供描述,则返回None。此方法的默认实现返回测试方法的文档字符串的第一行(如果有),或者返回None。
奇怪的是,我无法正常工作。有人可以发现我在做什么吗?
我的课确实继承自unittest.TestCase它,甚至有一个文档字符串
def test_smth(self):
"""
TEST
"""
self.description = 'TEST!'
print(self.shortDescription())
Run Code Online (Sandbox Code Playgroud)
None在Python 3.6中打印出来
我正在使用Django作为我的Web开发框架.现在我正在编写单元测试.如何断言我的测试代码中没有执行某个函数?
例如,这是用例:我的测试代码是测试用户在登录时输入了错误的密码.我想确保在此用例中不执行重置密码功能.
嗯,这并没有真正反映真实情况,但我希望你明白我的观点.
python ×10
python-unittest ×10
unit-testing ×5
mocking ×3
argparse ×1
assert ×1
django ×1
nosetests ×1
pytest ×1
python-2.7 ×1
python-3.4 ×1
python-3.x ×1
spyder ×1