我想确保我正在单独测试模型/对象,而不是作为一个庞大的系统。
如果我有一个订单对象,并且它具有客户、付款、订单项等的外键,并且我想测试订单功能,则需要为所有相关数据创建固定装置,或在代码中创建它。我认为我真正需要做的是模拟其他项目,但如果我对这些外键进行查询,我没有看到一个简单(或可能)的解决方案。
常见的解决方案(夹具)并不能真正让我一次测试一个对象。我确信这部分是由于我的应用程序造成的way过度耦合。
我正在尽最大努力采用 TDD 作为我的主要工作方法,但是从 Django 的工作方式来看,您似乎可以运行非常简单的单元测试,也可以运行这些大规模的集成测试。
[Edit]更好的明确的例子和更多的谦虚
我的意思是I seem能够只运行简单的单元测试。我见过有人拥有经过充分测试和细化的模块。我确信其中一些可以追溯到糟糕的设计。
Example:
我有一个名为 Upsell 的模型,它链接到产品模型。然后我有一个 Choices 模型,它是 Upsell 的子模型(你想要#1、#2、#3 门后面的东西)。
追加销售模型有多种方法,可以从他们的选择中派生出渲染模板所需的项目。最重要的是它为每个选择创建一个 URL。它通过一些字符串修改等来实现这一点。如果我想测试 Upsell.get_urls() 方法,我希望它不依赖于装置中选择的值,并且我不希望它依赖于固定装置中的产品。
现在,我在 setUp 方法中填充数据库以进行测试,这与 Django 每次撤回事务的方式配合得很好,但仅限于 setUp 和 TeaDown 之外。除了某些模型的设置相当复杂之外,这种方法效果相当好,而我实际上只需要为其获取一个属性。
我无法给你一个例子,因为我无法完成它,但这就是我现在正在做的事情。基本上我输入一个完整的订单,创建它所附加的 A/B 实验等。这还不包括由固定装置设置的产品、类别等。这不是我担心的额外工作,因为我什至无法一次测试一个基于数据库的对象。下面的测试很重要,但它们是集成测试。我想通过单独测试每个项目来构建类似的东西。正如您所指出的,也许我不应该选择与数据库密切相关的框架。是否存在任何类型的依赖注入? (超出了我的测试,但也超出了代码本身)
class TestMultiSinglePaySwap(TestCase):
fixtures = ['/srv/asm/fixtures/alchemysites.json','/srv/asm/fixtures/catalog.json','/srv/asm/fixtures/checkout_smallset.json','/srv/asm/fixtures/order-test-fixture.json','/srv/asm/fixtures/offers.json']
def setUp(self):
self.o = Order()
self.sp = SiteProfile.objects.get(pk=1)
self.c = Customer.objects.get(pk=1)
signals.post_save.disconnect(order_email_first, sender=Order)
self.o.customer = self.c
p = Payment()
p.cc_number = '4444000011110000'
p.cc_exp_month = '12'
p.cc_type = 'V'
p.cc_exp_year = '2020'
p.cvv2 = '123'
p.save()
self.o.payment = p
self.o.site_profile = self.sp
self.o.save()
self.initial_items = []
self.main_kit = Product.objects.get(pk='MOA1000D6')
self.initial_items.append(self.main_kit)
self.o.add_item('MOA1000D6', 1, False)
self.item1 = Product.objects.get(pk='MOA1041A-6')
self.initial_items.append(self.item1)
self.o.add_item('MOA1041A-6', 1, False)
self.item2 = Product.objects.get(pk='MOA1015-6B')
self.initial_items.append(self.item2)
self.o.add_item('MOA1015-6B', 1, False)
self.item3 = Product.objects.get(pk='STP1001-6E')
self.initial_items.append(self.item3)
self.o.add_item('STP1001-6E', 1, False)
self.swap_item1 = Product.objects.get(pk='MOA1041A-1')
def test_single_pay_swap_wholeorder(self):
o = self.o
swap_all_skus(o)
post_swap_order = Order.objects.get(pk = o.id)
swapped_skus = ['MOA1000D','MOA1041A-1','MOA1015-1B','STP1001-1E']
order_items = post_swap_order.get_all_line_items()
self.assertEqual(order_items.count(), 4)
pr1 = Product()
pr1.sku = 'MOA1000D'
item = OrderItem.objects.get(order = o, sku = 'MOA1000D')
self.assertTrue(item.sku.sku == 'MOA1000D')
pr2 = Product()
pr2.sku = 'MOA1015-1B'
item = OrderItem.objects.get(order = o, sku = 'MOA1015-1B')
self.assertTrue(item.sku.sku == 'MOA1015-1B')
pr1 = Product()
pr1.sku = 'MOA1041A-1'
item = OrderItem.objects.get(order = o, sku = 'MOA1041A-1')
self.assertTrue(item.sku.sku == 'MOA1041A-1')
pr1 = Product()
pr1.sku = 'STP1001-1E'
item = OrderItem.objects.get(order = o, sku = 'STP1001-1E')
self.assertTrue(item.sku.sku == 'STP1001-1E')
请注意,尽管我尝试过,但我从未真正使用过 Mock 框架。所以我也可能从根本上错过了一些东西。