5-13 Rspec实际; validates处理Errors, TDD, 单元测试和验收测试,capybara
validates处理验证错误:详见ActiveModel::Errors文档
一,errors
ActiveModel::Errors的实例包含所有的❌。每个错误:key是每个属性的name, value是一个数组,包含错误消息string.
例子:
person = Person.new
person.errors.messages #=> {:name => ["can't be blank", "is too short"], ...}
二 ,errors[]
通过key获取value ,如person.errors[:name] #=> ["can't be blank", "is too short"]
三, errors.add(atr, msg) 或者 errors.message[atr] << "msg"
手动添加某属性的错误message
errors.full_messages: 友好显示所有错误message, 用嵌套的hash显示。
add(attribute, message=:invalid, options={})
添加message给errors, 同时可以使用validator type 来在attribute上显示details
同一个attributes可以同时添加多个error。
如果没有自定义message ,默认使用:invalid。
分析: :not_implemente是自定义的验证类型,对应其message。使用p.errors.details,得到的是属性和属性指向的错误类型,
四, errors.details,
在add()方法内增加限制参数,not_allowed: "xxx"
五, errors[:base] << "string"
如果error不是直接管理到具体一个attribute上,可以使用:base .
把错误message添加到整个对象上。不是针对属性。不管什么错误,只像把对象标记为无效,就使用这个方法。
六,errors.clear 和 errors.empty?
清除errors 集合中所有message, errors.empty?查看是否错误集合是空的,配合clear使用。
七,errors.size,返回错误消息总数。 等同errors.count
八,视图上显示错误消息。
可以使用scarfold,在_form.html.erbzhong 自动加入ERB代码。或者自己写。
validate(*args, &block) #用于 自定义的验证方法
validates(*attributes) #用于验证表格的属性。这里有s
Rspec的方法:
to_not , be_valid
Rails程序开发,时间区默认是UTC,需要改为"Beijing"
在config/application.rb中,类Application中,加config.time_zone = "Beijing"
1.2.ceil #=> 2
2.0.ceil #=> 2
(-1.2).ceil #=> -1
(-2.0).ceil #=> -2
1.234567.ceil(3) #=> 1.235
TDD(Test-Driven Development)
测试驱动开发:
- 刚开始写测试的时候,关键要素,是测什么,要测试哪些案例example才算程序正确,可以列表一个清单。
- 先看到测试失败,才表示测试有作用。因此,可以先写测试代码,再写实做代码。
- 不要一次性把全部测试example写完,而是新写一段测试代码,让测试失败,再改正实做让实做通过,最后改进这个代码refactor重构。反复这个步骤,完成全部测试example。
测试代码比实做代码多是正常的,但很简单
- 建立测试资料
- 执行程序
- 检查结构-> TDD
如何在测试中除错
1利用puts输出信息
2关注需要除错的example
- 方法1: 把其他案例注释掉
- 方法2:编辑
spec/rails_helper.rb
,加上两行设定
RSpec.configure do |config|
# (略) + config.filter_run :focus => true
+ config.run_all_when_everything_filtered = true
然后修改 spec/models/parking_spec.rb
针对你想要单独测试的案例it/或者一组案例context,加上 :focus => true
,例子:
it "30 mins should be ¥2", :focus => true do...end
3.使用内置gem 'byebug'。 平时开发除错也可以使用。
def calculate_amount
+ byebug # (略)
执行测试会在中途停顿,并告知上下文环境。输入最后输入 continue
就会继续执行下去
Float@truncate: 返回要求的位数,默认只返回整数。
%:整除。
Feature Spec 验收测试
需要用到gem 'capybara' 水豚的意思。
Key benefits:
- works out of the box for Rails。开箱即用
- Intuitive API: mimics the language an actual user would use. 直观直觉API
Setup:
gem 'capybara'
Using Capybara with RSpec
在spec/rails_helper.rb添加(或者其他test helper file):
require 'capybara/rails'
require 'capybara/rspec'
⚠️: rails_helper已经require了文件spec_helper。所以require 'capybara/rspec'可以放到这两个文件任意一个中。
问题 :type => :feature 到底加不加,有啥用?
文档:
如果用Rails,并且Capybara specs文件在其他目录(非spec/features,or spec/system), 需给example groups加上tag, type: :feature or type: :system
问题:如果测试JavaScript。
使用js:true 来打开Capybara.javascript_dirver(默认:selenium)(具体看文档说明,有点复杂)
describe 'some stuff which requires js', js: true do
it 'will use the default js driver'
# it 'will switch to one specific driver', driver: :webkit
end
执行 mkdir spec/features
建立验收测试的目录
新增 spec/features/guest_spec.rb
save_and_open_page
解释:
feature
是别名:describe
,scenario
(a written outline of what happens in a film/movie or play 剧情概要。)等同于it
- 其他别名:background: before, given: let
- 这里
have_content
来检查指定文字有没有出现在 HTML 里面。Web 应用的测试,没办法去完整比对 HTML 字串,因为字串比对差一个空白就不一样。如果说设计师稍微多加一个<br>
就要改测试,这样就太累了,测试会太敏感。所以我们只能检查说 HTML 里面有出现我们希望要有的关键字。 - 注意到我们不需要再重复测试金额对不对了。Feature Spec 的重点在于检查东西(Model + Controller + View)接起来有没有正常运作。
- 被注解掉的
save_and_open_page
会存下测试当时的 HTML 页面(snapshot网页块照),除错的时候可以使用。如果打开的话,跑测试会出现:
within("#new_user") do # 填表单,模拟用户填写表单送出的情况。
fill_in "Email", with: "foobar@example.com"
fill_in "Password", with: "12345678"
fill_in "Password confirmation", with: "12345678"
end
click_button "Sign up"expect(page).to have_content("Welcome! You have signed up successfully")
这里我们模拟用户填写表单送出的情况,用fill_in
可以填入值
测试短期费率流出
Devise 提供测试用的 sign_in
方法,请改 spec/rails_helper.rb
:
RSpec.configure do |config|
+ + config.include Devise::Test::ControllerHelpers, type: :controller
+ config.include Devise::Test::ControllerHelpers, type: :view
+ config.include Devise::Test::IntegrationHelpers, type: :feature
这里用了 choose
来对 Radio 按钮做选择,在 capybara 中还有提供其他方法针对不同表单元件做操作,例如:
- check "核选方块名称"
- uncheck "核选方块名称"
- select "选项名称", :from => "下拉选单名称"
- attach_file 上传档案
The DSL
A complete reference is available at rubydoc.info.
⚠️:默认的Capybara只会定位可见的元素,因为真实用户不会和不可见的元素互动。
pasting
- Navigating
- Clicking links and buttons
- Interacting with forms
- Querying
- Finding
- Scoping
- Working with windows
- Scripting
- Modals
- Debugging
Navigating
vist方法,例子:
visit "/projects"
vist (post_comments_path(@post))
have_current_path方法:当前页面又这个路径
expect(page).to have_current_path(post_comments_path(post))
Clicking links and buttons
Full reference:Capybara::Node::Actions
Capybara自动跟随redirect, submits forms 相关的buttons
click_link('Link Text')
click_button('Save')
click_on('Link Text') # clicks on either links or buttons
Interacting with forms
Full reference:Capybara::Node::Actions
fill_in('First Name', with: 'John')
fill_in('Password', with: 'Seekrit')
fill_in('Description', with: 'Really Long Text...')
choose('A Radio Button')
check('A Checkbox')
uncheck('A Checkbox')
attach_file('Image', '/path/to/image.jpg')
select('Option', from: 'Select Box')
#fill_in([locator], options = {}) ⇒ Capybara::Node::Element
参数:
locator(String)-- Which field to fill in
options(Hash) (默认{})
选项:
:with(String):所要填入的值。
:id(String) -- 定位的选项。
:name(String)-- 定位的选项。
:class(String,Array<String>) -- 定位的选项。
Querying
Full reference: Capybara::Node::Matchers
一系列选项用来查询页面是否存在某个元素,操作这个元素。
You can use these with RSpec's magic matchers:
expect(page).to have_selector('table tr')
expect(page).to have_selector(:xpath, './/table/tr')
expect(page).to have_xpath('.//table/tr')
expect(page).to have_css('table tr.foo')
expect(page).to have_content('foo')
Finding
Full reference: Capybara::Node::Finders
指定寻找元素,并操作。
find_field('First Name').value
find_field(id: 'my_field').value
find_link('Hello', :visible => :all).visible?
find_link(class: ['some_class', 'some_other_class'], :visible => :all).visible? find_button('Send').click
find_button(value: '1234').click find(:xpath, ".//table/tr").click
find("#overlay").find("h1").click
all('a').each { |a| a[:href] }
find('#navigation').click_link('Home')
expect(find('#navigation')).to have_button('Sign out')
Scoping
Restrict certain actions, such as interacting with forms or clicking links and buttons, to within a specific area of the page. within method.
within("li#employee") do
fill_in 'Name', with: 'Jimmy'
end
Restrict: ~ sth: to limit the size, amount or range of sth.
within_fieldset(), within_table()也一样。
Scripting
在支持的drivers中,可以执行JavaScript, page.execute_script("$('body').empty()")
Modals
In drivers which support it, you can accept, dismiss and respond to alerts, confirms and prompts.
accept_alert do
click_link('Show Alert')
end
Debugging
网页快照snapshot存储当前页面在tmp/capybara/capybara-XXXxxx.html
save_and_open_page
You can also retrieve the current state of the DOM as a string using page.html.
print page.html #在命令窗口显示html代码。
Asynchronous JavaScript (Ajax and friends)
当想要操作一个异步的JS, Capybara自动等待元素在这个页面出现。
可以调整时间,默认2秒。在时间内等待,超出则放弃或throw an error
Capybara.default_max_wait_time = 5
Capybara's waiting behaviour is quite advanced, and can deal with situations such as the following line of code:
expect(find('#sidebar').find('h1')).to have_content('Something')
5-13 Rspec实际; validates处理Errors, TDD, 单元测试和验收测试,capybara的更多相关文章
- 使用IdleTest进行TDD单元测试驱动开发演练(2)
[前言] 1. 有关上篇请参见<使用IdleTest进行TDD单元测试驱动开发演练(1)>,有关本篇用到Entity Framework Code First请参见<使用NuGet助 ...
- TDD单元测试驱动
使用IdleTest进行TDD单元测试驱动开发演练(2) [前言] 1. 有关上篇请参见<使用IdleTest进行TDD单元测试驱动开发演练(1)>,有关本篇用到Entity Fram ...
- 使用IdleTest进行TDD单元测试驱动开发演练(3) 之 ASP.NET MVC
一.[前言] (1)本文将用到IOC框架Unity,可参照<Unity V3 初步使用 —— 为我的.NET项目从简单三层架构转到IOC做准备>(2)本文的解决方案是基于前述<使用I ...
- 使用IdleTest进行TDD单元测试驱动开发演练(1)
[前言] 开发工具:Visual Studio 2012 测试库:Visual Studio 2012自带的MSTest DI框架:Unity 数据持久层:Entity Framework 前端UI: ...
- C C++ TDD单元测试非常好的书
http://product.china-pub.com/199003 测试驱动的嵌入式C语言开发 Test Driven Development for Embedded C <测试驱动的嵌入 ...
- 测试驱动开发(Test-Driven Development,简称TDD)--单元测试-->提高代码质量
!!! 1.估算和做项目计划时要算上单元测试时间 2.开发之前写单元测试代码 盖房子的时候,工人师傅砌墙,会先用桩子拉上线,以使砖能够垒的笔直,因为垒砖的时候都是以这根线为基准的.TDD就像这样,先写 ...
- Rails 5 Test Prescriptions(everday Rspectest作者推荐) 目录 1-3章
总文档连接: RSpec.info/documentation/ 如何使用TDD 和 自动化测试来建立一个Rails app. TDD让你用测试来探索代码的设计.你将学习可利用的工具,并学习用什么工具 ...
- rspec测试(使用guard自动测试和spork加速测试)配置
Gemfile文件添加rspec.guard和spork,之后执行bundle install命令 gem 'rb-readline' group :development, :test do # C ...
- Oracle shutdown immediate无法关闭数据库解决方法
在测试服务器上使用shutdown immediate命令关闭数据库时,长时间无法关闭数据库,如下所示 1: [oracle@DB-Server admin]$ sqlplus / as sysdba ...
随机推荐
- Linux服务器配置---ssh配置
Ssh配置 通过配置文件,我们可以有效的管理ssh 1.空闲时间关闭连接 1)修改配置文件“/etc/ssh/sshd_config”,设置clientAliveInterval和client ...
- linux查看文件夹大小,备份文件夹zip压缩解压
linux查看文件夹大小,备份文件夹zip压缩解压 du -sh : 查看当前目录总共占的容量.而不单独列出各子项占用的容量 du -lh --max-depth=1 : 查看当前目录下一级子文件和子 ...
- C++中公有继承、保护继承、私有继承的区别
公有继承时基类中各成员属性保持不变,基类中private成员被隐藏.派生类的成员只能访问基类中的public/protected成员,而不能访问private成员:派生类的对象只能访问基类中的publ ...
- Observer模式实践
Observer 模式在实践中的应用场景: 为 Point 类设计一个数据绑定机制,当其坐标 x 或 y 被更改时,可以通知外界其更改的过程.将更改过程打印在控制台上.考虑使用松耦合设计. 代码: # ...
- 20145331魏澍琛《网络对抗》Exp2 后门原理与实践
20145331魏澍琛<网络对抗>Exp2 后门原理与实践 基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? 上网时候弹出一个广告说你中奖了,或者你可以贷款10万元之类 ...
- 关于cp命令的编写
关于cp命令的编写 娄老师在课上详细的讲了命令who的编写过程~对此,我很有启发!于是想亲自动手试试~ 有什么不足的地方请大家提出来! Learning by doing ~ 做中学,真的只有自己动手 ...
- BZOJ 1063 道路设计(树形DP)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1063 题意:给出一个无环图( 也就是树,但是也有可能是森林),代表一个国家的城市.1是首 ...
- 六角填数|2014年蓝桥杯B组题解析第七题-fishers
六角填数 如图所示六角形中,填入1~12的数字. 使得每条直线上的数字之和都相同. 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少? 请通过浏览器提交答案,不要填写多余的内容. 思路 ...
- 【Map】Echarts之iphone销量地图的使用以及详细配置
1.引入echarts库文件 <script charset="utf-8" type="text/javascript" language=" ...
- BZOJ1307: 玩具 单调队列
Description 小球球是个可爱的孩子,他喜欢玩具,另外小球球有个大大的柜子,里面放满了玩具,由于柜子太高了,每天小球球都会让妈妈从柜子上拿一些玩具放在地板上让小球球玩. 这天,小球球把所有的N ...