该文章同步发布於:我的部落格
测试有一个必要的条件就是要有资料来做测试,有三种方法可以 Rails 中产生测试资料。
这三种方法都是可行的解决方案,我们可以一个一个来探讨一下。
如果你测试的 Model 只有几个属性,而且没有关联的 Model,手动建立测试资料可以说是非常方便。
例如,假设我有一个 PaymentType Model,只有一个属性,名字。而且也可以很轻易的做出合法以及不合法的状态,很简单!
valid_payment_type = PaymentType.new(name: 'Visa')
invalid_payment_type = PaymentType.new(name: '')
接着,我们有一笔订单,它是由多的 LineItems 和 Payments 组成,每个都有一个 PaymentType。
order = Order.create!(
line_items: [
LineItem.create!(name: 'PS5', price: 15000)
],
payments: [
Payment.create!(
amount: 15000,
payment_method: PaymentType.create!(name: 'Visa')
)
]
)
这样写起来其实超级烦的,我们不得不浪费一堆脑力,想一些不一定相关的细节。
如果我们想要测试的是,amount
等於 line_items
的总额时,order.balance
回传 0,该怎麽做?
接这就是 Factory 派上用场的时候了!
Factory 其实不是一个针对测试的概念,Factory Method
是一种设计模式,可以在 Gang of Four
这本书中找到,而这个模式恰好对测试的目的很有用。
Factory 的概念基本上是,你有一个方法或是函数,可以为你产生新的类别。
在 Gang of Four
这本书中,他用了一个例子,一个叫做 Creator
的工厂会根据不同的条件回传 MyProduct
或是 YourProduct
的实体。可以直接说 Creator.create(相关资料)
,就会自然回传适当的实体!
你也许会想这样的 Factory 有什麽用处,在测试的情况下,我们想要的 Factory 类型可能会有一点不同。我们关心的不是抽象的类别实体化。我们希望抽象出没意义的细节和繁琐的 Model Association
下面是一个例子,说明如果我们用一个 Factory,特别是 Factory-Bot,刚刚 Order 的设置会是怎麽样呢?( 关於 Factory-Bot 在之前的文章有做过分享基本的用法 )
order = create(
:order,
line_items: [create(:line_item, price: 15000)],
payments: [create(:payment, amount: 15000)]
)
在这样的情况下,我们只需要专注在我们要测试的项目,不用像刚刚手动的那样关心一些奇怪的名目和支付方式,做好我们关心的 price
和 amount
,就是我们最关心的一切。
那我们要怎麽用 fixtures 来实现同样的事情呢?
首先我自己对於 fixtures
的经验和 Factory-Bot
相比,比较不熟。但可以看看这篇关於 fixtures 的文章!
说到这里,如果我们想用做出和上面 Factory-Bot 一样的测试资料,也可以使用 fixtures
来做,通常情况下,我看别人都是用 YAML 档的形式来表达!
# orders.yml
payments_equal_line_item_total:
# no attributes needed
# line_items.yml
ps5:
order: payments_equal_line_item_total
name: 'PS5'
price: 15000
# payment_methods.yml
visa:
name: 'Visa'
# payments.yml
first:
order: payments_equal_line_item_total
payment_method: visa
amount: 15000
一但确定好 fixtures 的资料後,用它就像在用 Hash 的 key 一样简单~
order = orders(:payments_equal_line_item_total)
所以,你觉得哪一种生产测试资料的方式好用呢?
我想前面已经证明,手动产生测试资料这件事情真的很容易就很麻烦,但是,也不是真的不好用,他其实在自己的 side project 里面就很好用,手动生产就不需要开档案,分那麽多的资料夹,而且可读性又提高,东西都在一个档案里面~
至於 fixtures 和 Factory-Bot,我自己是用 Factory 居多,主要原因是 Gem 的强大,还有 YAML 档,虽然很好读,但我自己还是不太习惯,可能这就是工具用久的依赖性吧~
至於之前看到有人提过关於 fixtures 的见解,他认为,一个专案会创造一个 资料世界
,然後用这个很大又很复杂的世界作为测试的基础,发文的人说他更倾向於在可行的情况下,从一个乾净的 Model 开始每一个测试,并为每个测试产生该测试所需要的最低限度资料,他发现,这让测试变得容易理解,而不是用 fixtures 制造出一个固定的资料!
当然也不是说只能挑一个做使用,但如果今天你想要有一个固定的回传资料或是什麽的可以( 可能是金流,那种从来不会改变的东西 ),你也可以做一个 fixtures 然後传到 Factory,在整个测试基础上产生动态资料!
我自己还是大推 Factory-Bot 啦,但可能我自己对於 fixtures 的理解也不够深,说不定一年过後就会推翻这些自己觉得是对的东西,那也没关系啦,继续变强才是重点嘛~
在Java程序设计中,有时一维阵列无法计算较多且较复杂的,这时我们需要二维阵列,例如要产生一个阵列A...
Http 使用 Http 通讯协定,发送网路请求存取网路上的资源在开发App是很基本的需求,今日我们...
这篇主要讲GetX在页面切换之间的路由(上下页的前後文关系) 初步先建立一个routes的资料夹 里...
Firebase 云端服务平台之一,提供资料库、机器学习、虚拟机、登入验证等服务 建立专案 要使用 ...
软件版本 PHPphp7.3 WebServicenginx FRAMEWORKLaravel8 ...