bcreate the data quickly and easily。考虑测试运行的速度。

fixtures and factories.以及下章讨论的test doubles,还有原生的create创建的,没有一个方案可以解决所有情景。


Fxitures

如果想使用固件。RSpec目录是spec/fixtures/projects.yml。 Mini test的目录是test/fixtures/

runway:
   name: Project Runway

due_date: 2016-12-18

projects(:runway)

名字可以描述用途,比如projects(:project_with_no_due_date)

Fixture接受ERB files.可以使用<%= %> ,不建议使用使用循环。

Loading Fixture Data

在测试开始时固件会一次性加载,使用事物transaction,因此在测试结束时会回滚。回归初始状态。

固件运行速度块。固件是全局性的数据 储存在database中。

固件是分散的,不适合管理connections,关联数据。

总之,固件不适合在复杂的程序使用。


Factories   factory_bot

gem 'factory_bot_rails'  目录spec/factories/

在spec的一个文件中配置:

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

每次用create方法无需加上FactoryBot前缀了。

详细用法:本博客: https://www.cnblogs.com/chentianwei/p/9047596.html

Factory_bot假定class的名字就是你定义的名字。如果要自定义类,需要指定类名。

FactoryBot.define do
  factory :project, class: Project do
    name "Project Runway"
    due_date {Date.today - rand(50)} #随机时间。50天内的。
  end
end

Basic Factory Creation

build(:project): 非关联对象可以使用。

create(:project):别用,除非对象之间有关联,必须存入数据库。因为会让测试减慢。

attributes_for(:project)   需要对hash属性进行验证时,使用,一般见于controller test。

build_stubbed(:project) Unlike build, it assigns a fake ActiveRecord
ID to the model and stubs out database-interaction methods (like save)
such that the test raises an exception if they are called.

Prescription: 尽量使用这个方法,有build的一切功能,还能生成一个假Rails id,有了这个就能建立belongs_to 关联,同时不会被存入数据库。

*_pair  and *_list 两个方法,没看。

Associations and Factories 

FactoryBot.define do
  factory :task do
    title "Thing to do"
    size 1
    completed_at nil
    project   

#这样调用task = create(:task)就会自动调用task.project = create(:project)

  end
end

也可以单独建立关联:

task
= FactoryBot.create(:task,  project: Project.new)

如果已经在factory definition中建立了关联,同时不想在测试中有value,设置nil

task = FactoryBot.create(:task,
project: nil).

如果关联名字不匹配factory name或者你想指定关联对象的默认的属性:

在factory definition 中使用association方法

association :doer,  factory: :user,  name: "Task Doer"

只有保存在数据库中,对象有了id才能关联。但可以使用build_stubbed来创建不保存的对象

或者使用create方法。

作者建议在定义中建立关联,但不设置属性。属性在测试中设置。

association :user

更直接的 user

Managing Duplication in Factories 

对于2个以上的factories, Factory_bot可以做到管理。文档里面有许多技巧,但以下3个最常用。

sequence方法 

对于需要unique values 的属性,如登陆,或电子邮件。可以使用sequence方法。

sequence(:title) { |n| "Task #{n}"}

起始n是1. 每被调用一次n加1。

inherited factories 继承的特性

FactoryBot.define do
  factory :task do
    sequence(:title){ |n| "Task #{n}"}  
#可以嵌套进来
    factory :big_task do
      size 5
    end
    factory :small_task do
      size 1
    end
  end
#或者加上parent: :task
  factory :middle_task, parent: :task do
    size 3
  end
end

trait方法

trait

优点:设置一个有意义的名字,方便理解

缺点:需要额外的输入和增加了复杂度。

用于指定一批的特定的属性,一个省事的方法。

这个方法放在factory :task的块中,就可以被task使用。

FactoryBot.define do
  factory :task do
    title "Thing to do"
    size 1
    completed_at nil
    trait :small do
      size 1
    end

#继承一个对象,并使用了trait

    factory :trivial do
      small
    end
  end
end

调用: let(:task){build(:task, :smal)}

Preventing Factory Abuse

创建最小数量的数据刚好够测试用就可以了。


Dates and Times

测试历法逻辑,让人头疼,但可以使用a couple of things 来简化时间逻辑这个野兽 .

Using Relative Dates

Date.today 和 1.day.ago, 2.months.ago, 2.weeks.ago结合使用。

如在

factory :project do

start_date {1.week.ago}

end

gutenberg:

start_date: <%= 1.day.ago %>

缺点就是如果某个时间是已知的,就没办法使用相对时间了。

Stubbing Time

把时间冻结!!!用a stub来明确指定时间。

需要用到Raisl helper方法。

ActiveSupport::Testing::TimeHelpers#travel

Changes current time to the time in the future or in the past by a given time difference by stubbing Time.nowDate.today, and DateTime.now. The stubs are automatically removed at the end of the test.

travel(duration, &block)

  1. Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
  2. travel 1.day do
  3. User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
  4. end
  5. Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00

如 travel 1.month, 接受一段时间作为参数。 一个整数。

ActiveSupport::Testing::TimeHelpers#travel_to

travel_to(date_or_time)

接受1个固定的时间/日记,作为参数。

pasting

  1. Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
  2. travel_to Time.zone.local(2004, 11, 24, 01, 04, 44) do
  3. Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
  4. end
  5. Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00

trave_back 重置时间回到初始状态。

可以在这两个参数的块内,进行断言,或者期望expect.

Comparing Time

Ruby有三个独立的时间类。Time, Date, DateTime.

因此Date的实例和DateTime的实例是无法比较和加减的

使用to_s(:db)进行转化。

 1.day.ago.to_date.to_s(:db)  => "2018-05-25"

 1.day.ago.to_date   => Fri, 25 May 2018

Setting Rails Timestamps

可以使用created_at 在预制件,或者固件中。

Rails 5 Test Prescriptions 第6章Adding Data to Tests的更多相关文章

  1. Rails 5 Test Prescriptions 第8章 Integration Testing with Capybara and Cucumber

    Capybara:  A complete reference is available atrubydoc.info. 集成测试就是把局部的程序组合起来测试. 端到端测试是一个特殊的集成测试,覆盖了 ...

  2. Rails 5 Test Prescriptions 第3章Test-Driven Rails

    本章,你将扩大你的模型测试,测试整个Rails栈的逻辑(从请求到回复,使用端到端测试). 使用Capybara来帮助写end-to-end 测试. 好的测试风格,包括端到端测试,大量目标明确的单元测试 ...

  3. Rails 5 Test Prescriptions 第10章 Testing for Security

    Web 安全是一个可怕的主题.所有的你的程序都依靠密码学,代码超出了你的控制. 尽管如此,你还是可以控制部分网页安全 --所有的logins和access checks和injection error ...

  4. Rails 5 Test Prescriptions 第11章其他部分的测试。

    Routes✅ Helper Methods✅ Controllers and Requests✅ Simulating Requests⚠️,看之前的博客 What to Expect in a R ...

  5. Rails 5 Test Prescriptions 第9章 Testing-JavaScript: Integration Testing,❌挂一个问题webpacker::helper

    使用Capybara进行JS的集成测试 谈论驱动 让测试通过 Webpack in Development Mode Js设计 是用户在网页上有好的体验的重要因素. 尽管如此,许多网页不测试JS. 部 ...

  6. Rails 5 Test Prescriptions 第5章 Testing Models

    Rails,model层包含业务逻辑和储存逻辑.其中储存逻辑被ActiveRecord处理. 在model中,不是每件事都必须是ActiveRecord对象.model layer可以包含各种服务,对 ...

  7. Rails 5 Test Prescriptions 第4章 什么制造了伟大的测试

    伴随着程序成长,测试变长,复杂性增加,如何更高效的写测试,对以后开发不会造成麻烦. 测试本身没发被测试,所以一定要清楚,可控.不要加循环,不要过于复杂的自动编程. Cost and Value 成本和 ...

  8. Rails 5 Test Prescriptions 第10章 Unit_Testing JavaScript(新工具,learn曲线太陡峭,pass)

    对Js的单元测试是一个大的题目.作者认为Ruby的相关测试工具比Js的测试工具更灵活 大多数Js代码最终是关于响应用户的行为和改变DOM中的元素 没有什么javascript的知识点.前两节用了几个新 ...

  9. Rails 5 Test Prescriptions 第7章 double stub mock

    https://relishapp.com/rspec/rspec-mocks/v/3-7/docs/basics/test-doubles 你有一个问题,如果想为程序添加一个信用卡程序用于自己挣钱. ...

随机推荐

  1. PL/SQL编程基础(一):PL/SQL语法简介(匿名PL/SQL块)

    PL/SQL PL/SQL是Oracle在关系数据库结构化查询语言SQL基础上扩展得到的一种过程化查询语言. SQL与编程语言之间的不同在于,SQL没有变量,SQL没有流程控制(分支,循环).而PL/ ...

  2. Object类中常见的方法,为什么wait notify会放在Object里边

    toString():输出一个对象的地址字符串(哈希code码):可以通过重写toString方法,获取对象的属性! equals():比较的是对象的引用是否指向同一块内存地址, 重写equals() ...

  3. Python开发【Django】:日志记录、API认证

    日志记录: 调用同一个对象,分别记录错误日志和运行日志 自定义日志类: class Logger(object): __instance = None def __init__(self): self ...

  4. django-session和cookie

    在Django里面,使用Cookie和Session看起来好像是一样的,使用的方式都是request.COOKIES[XXX]和request.session[XXX],其中XXX是您想要取得的东西的 ...

  5. iOS定位原理和使用建议(转)

    原文:http://ibbs.91.com/thread-1548870-1-1.html 看到很多网友讨论iOS设备定位的问题,这里将我们所了解的关于iPhone.iPad.iPod等的定位原理做详 ...

  6. [WorldWind学习]20.修改ShapeFileLayer类及托管D3D文字绘制方法

    PluginSDK\ShapeFileLayer.cs Line:1027char[] fieldDataChars = dbfReader.ReadChars(fieldHeaders[j].Fie ...

  7. mac终端显示日历信息命令

    cal 命令: 用法: usage: cal [-jy] [[month] year] cal [-j] [-m month] [year] ncal [-Jjpwy] [-s country_cod ...

  8. WebKit.net最简单使用方法

    WebKit.net是对WebKit的.Net封装,使用它.net程序可以非常方便的集成和使用webkit作为加载网页的容器.这里介绍一下怎么用它来显示一个网页这样的一个最简单的功能. 第一步: 下载 ...

  9. Python numpy有什么用?

    NumPy is the fundamental package for scientific computing with Python.就是科学计算包. a powerful N-dimensio ...

  10. JDBC 连接Oracle 数据库,JDBC 连接Mysql 数据库

    首先是JDBC 连接Oracle  数据库 package com.util; import com.pojo.UserInfo; import java.sql.*; public class DB ...