我想在不同条件下运行一组测试,因此在两个不同的TestCase
派生类之间共享这些测试。
一个创建自己的独立会话,另一个连接到现有会话并在那里执行相同的测试。
我想我在使用它测试API时会滥用unittest
框架,但它并不觉得它离原来的目的太远了。到目前为止我好吗?
我一起砍了几件东西,让它运行起来。但它的做法,感觉不对,我害怕迟早会引起问题。
这些是我的解决方案存在的问题:
当简单地使用PyCharm运行事物而不限制测试时,它不仅会尝试运行预期的StandaloneSessionTests
和ExistingSessionTests
,还会尝试GroupOfTests
这只是集合和没有会话,即执行上下文。
我可以通过GroupOfTests
不从<{1}}中导出{em>而不是来运行TestCase
,但PyCharm抱怨说它不知道assert...()
{1}}功能。这是正确的,因为当GroupOfTest
派生类也继承自TestCase
时,GroupOfTests
只能在运行时间接访问这些函数。来自C ++背景,这感觉就像黑魔法,我不认为我应该这样做。
我尝试将会话创建类传递给__init__(self, session_class)
的构造函数,如下所示:unittest
。但是当__init__
框架试图实例化测试时,这会导致问题:它不知道如何处理额外的@classmethod
参数。
我了解了suite = unittest.TestSuite()
suite.addTest(GroupOfTests(UseExistingSession))
suite.addTest(GroupOfTests(CreateStandaloneSession))
...
,这似乎是绕过&#34;只有一个构造函数&#34; Python的局限性,但我无法找到让它运行的方法。
我正在寻找一种解决方案,让我可以说明一些简单明了的事情:
#!/usr/bin/python3
import unittest
def existing_session():
return "existingsession"
def create_session():
return "123"
def close_session(session_id):
print("close session %s" % session_id)
return True
def do_thing(session_id):
return len(session_id)
class GroupOfTests(unittest.TestCase): # GroupOfTests gets executed, which makes no sense.
#class GroupOfTests: # use of assertGreaterThan() causes pycharm warning
session_id = None
def test_stuff(self):
the_thing = do_thing(self.session_id)
self.assertGreater(the_thing, 2)
# Original code contains many other tests, which must not be duplicated
class UseExistingSession(unittest.TestCase):
session_id = None
def setUp(self):
self.session_id = existing_session()
def tearDown(self):
pass # Nothing to do
class CreateStandaloneSession(unittest.TestCase):
session_id = None
def setUp(self):
self.session_id = create_session()
def tearDown(self):
close_session(self.session_id)
# unittest framework runs inherited test_stuff()
class StandaloneSessionTests(CreateStandaloneSession, GroupOfTests):
pass
# unittest framework runs inherited test_stuff()
class ExistingSessionTests(UseExistingSession, GroupOfTests):
pass
def main():
suite = unittest.TestSuite()
suite.addTest(StandaloneSessionTests)
suite.addTest(ExistingSessionTests)
runner = unittest.TextTestRunner()
runner.run(suite())
if __name__ == '__main__':
main()
这是我到目前为止所得到的:
{{1}}
答案 0 :(得分:1)
我不确定使用pytest
是否适合你,但如果是这样,这里有一个例子可能会做你想要的。
import pytest
class Session:
def __init__(self, session_id=None):
self.id = session_id
existing_session = Session(999)
new_session = Session(111)
@pytest.fixture(params=[existing_session, new_session])
def session_fixture(request):
return request.param
class TestGroup:
def test_stuff(self, session_fixture):
print('(1) Test with session: {}'.format(session_fixture.id))
assert True
def test_more_stuff(self, session_fixture):
print('(2) Test with session: {}'.format(session_fixture.id))
assert True
输出:
$ pytest -v -s hmm.py
======================================================= test session starts ========================================================
platform linux -- Python 3.6.4, pytest-3.4.1, py-1.5.2, pluggy-0.6.0 -- /home/lettuce/Dropbox/Python/Python_3/venv/bin/python
cachedir: .pytest_cache
rootdir: /home/lettuce/Dropbox/Python/Python_3, inifile:
collected 4 items
hmm.py::TestGroup::test_stuff[session_fixture0] (1) Test with session: 999
PASSED
hmm.py::TestGroup::test_stuff[session_fixture1] (1) Test with session: 111
PASSED
hmm.py::TestGroup::test_more_stuff[session_fixture0] (2) Test with session: 999
PASSED
hmm.py::TestGroup::test_more_stuff[session_fixture1] (2) Test with session: 111
PASSED
===================================================== 4 passed in 0.01 seconds =====================================================
如果您确实要使用pytest
,您可能需要关注conventions for Python test discovery,而不是使用hmm.py
作为文件名!
答案 1 :(得分:1)
您可以通过使用raise NotImplementetError
创建抽象方法来让pycharm忽略这些不存在的函数:
class GroupOfTests:
session_id = None
def test_stuff(self):
the_thing = do_thing(self.session_id)
self.assertGreater(the_thing, 2)
def assertGreater(self, a, b): # Pycharm treats these like abstract methods from the ABC module
raise NotImplementetError
这将让python相信这是一个抽象类,如果子类没有定义这些函数,它将使pycharm引发错误。