Ste*_*art 3 python django unit-testing
背景:我正在研究一个网络抓取工具,以跟踪在线商店的价格。它使用Django。我为每个商店都有一个模块,每个模块都具有get_price()和get_product_name()编写的功能,因此主刮板模块可以互换使用这些模块。我有store_a.py,store_b.py,store_c.py等,每个都定义了这些功能。
为了防止重复代码,我制作了StoreTestCase,它继承自TestCase。对于每个商店,我都有一个StoreTestCase的子类,例如StoreATestCase和StoreBTestCase。
当我手动测试StoreATestCase 类时,测试运行器执行我想要的操作。它使用子类中的数据self.data进行测试,而不尝试自行建立和测试父类:
python manage.py test myproject.tests.test_store_a.StoreATest
Run Code Online (Sandbox Code Playgroud)
但是,当我手动测试模块时,例如:
python manage.py test myproject.tests.test_store_a
Run Code Online (Sandbox Code Playgroud)
它首先为子类运行测试并成功,但是随后为父类运行测试并返回以下错误:
for page in self.data:
TypeError: 'NoneType' object is not iterable
Run Code Online (Sandbox Code Playgroud)
store_test.py(父类)
from django.test import TestCase
class StoreTestCase(TestCase):
def setUp(self):
'''This should never execute but it does when I test test_store_a'''
self.data = None
def test_get_price(self):
for page in self.data:
self.assertEqual(store_a.get_price(page['url']), page['expected_price'])
Run Code Online (Sandbox Code Playgroud)
test_store_a.py(子类)
import store_a
from store_test import StoreTestCase
class StoreATestCase(StoreTestCase):
def setUp(self):
self.data = [{'url': 'http://www.foo.com/bar', 'expected_price': 7.99},
{'url': 'http://www.foo.com/baz', 'expected_price': 12.67}]
Run Code Online (Sandbox Code Playgroud)
如何确保Django测试运行器仅测试子类,而不测试父类?
解决此问题的一种方法是使用Mixins:
from django.test import TestCase
class StoreTestCase(object):
def setUp(self):
'''This should never execute but it does when I test test_store_a'''
self.data = None
def test_get_price(self):
for page in self.data:
self.assertEqual(store_a.get_price(page['url']), page['expected_price'])
class StoreATestCase(StoreTestCase, TestCase):
def setUp(self):
self.data = [{'url': 'http://www.foo.com/bar', 'expected_price': 7.99},
{'url': 'http://www.foo.com/baz', 'expected_price': 12.67}]
Run Code Online (Sandbox Code Playgroud)
由于StoreTestCase它将不是,因此将不会执行TestCase,但是您StoreATestCase仍将从继承中受益。
我认为您的问题之所以发生是因为它StoreTestCase是一个TestCase实例,因此在您运行测试时便会执行它。
编辑:
我也建议在中提出一个例外StoreTestCase.setUp,明确指出未实现。看看这些异常。您最终将得到如下结果:
import exceptions # At the top of the file
[...]
def setUp(object):
raise exceptions.NotImplementedError('Please override this method in your subclass')
Run Code Online (Sandbox Code Playgroud)
您可以将基类隐藏在另一个基类中:
store_test.py(父类)
from django.test import TestCase
class TestHelpers(object):
class StoreTestCase(TestCase):
...
Run Code Online (Sandbox Code Playgroud)
test_store_a.py(子类)
import store_a
from store_test import TestHelpers
class StoreATestCase(TestHelpers.StoreTestCase):
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
862 次 |
| 最近记录: |