我们要把应用各组件放在一起做集成 测试,这样才能保证模型和控制器之间能够良好契合。

在 RSpec 中,这种测试称为功能测试(feature spec),有时也称为验收测试(acceptance test)或集成测试(integration test)。这种测试的作用是确保 软件作为一个整体能按预期使用。

Capybara库 (8000star),用来定义功能测试的步骤,模拟真实用户的使用过程。 5.1已经自带这个库,因为系统测试依赖它。

Rails5.1 框架增加了系统测试。用的是MiniTest.

作者喜欢使用Rspec开发Rails应用。

在spec/rails_helper.rb中加入 require 'capybara/rspec'

6.3 一个简单的功能测试

bin/rails generate rspec:feature projects

feature test 和controller test 的区别:控制器测试绕过用户界面,直接把参数发给controller actions.

  it "user creates a new project" do
    user = FactoryGirl.create(:user)
    visit root_path
    click_link "Sign in"
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    click_button "Log in"
    expect {
      click_link "New Project"
      fill_in "Name", with: "Test Project"
      fill_in "Description", with: "Trying out Capybara"
      click_button "Create Project"
      expect(page).to have_content "Project was successfully created"
      expect(page).to have_content "Test Project"
      expect(page).to have_content "Owner: #{user.name}"
    }.to change(user.projects, :count).by(1)
  end

用到了expect{}.to , scenario作用等同于it。

6.2 Capybara DSL

除了 ,click_link, fill_in, with, click_button还有很多方法。

  scenario "works with all kinds of HTML elements" do
    visit "/fake/page"
    click_on "A link or button label"
    check "A checkbox label"
    uncheck "A checkbox label"
    choose "A radio button lable"
    select "An option", from: "A select menu"
    attach_file "A file upload label", "/some/file/in/my/test/suite.gif"\
    expect(page).to have_css "h2#subheading"
    expect(page).to have_selector "ul li"
    expect(page).to have_current_path "/projects/new"
  end

选择符还可以限定范围,让 Capybara 在页面的某一部分中(within)查找指定的元素。假设有如下的
HTML:

<div id="node">
<a href="http://nodejs.org">click here!</a>

</div>
<div id="rails">

<a href="http://rubyonrails.org">click here!</a>
</div>

我们可以像下面这样指明点击哪个“click here!”链接:

within "#rails" do

click_link "click here~!"

end

此外,还可以使用 Capybara 提供的多个 find 方法找出特定元素及其值。例如:

    language = find_field("Programming language").value
expect(language).to eq "Ruby"
    find("#fine_print").find("#disclaimer").click
find_button("Publish").click

以上是我最常使用的 Capybara 方法 ,完整方法见Capybara DSL 文档。

6.5调试feature test

save_and_open_page,保存并打开出错的页面。需要手动打开open tmp/...。

安装gem 'launchy'后可以自动打开保存的HTML文件。

测试完成后,应当在提交版本控制之前,把不需要的save_and_open_page删除。

  it "guest adds a project" do
    visit projects_path
    save_and_open_page
    click_link "New Project"
  end

6.6测试JavaScript交互

bin/rails g rspec:feature tasks

  scenario "user toggles a task", js:true do
    user = FactoryGirl.create(:user)
    project = FactoryGirl.create(:project,
      name: "RSpec tutorial",
      owner: user
    )
    task = project.tasks.create!(name: "Finish RSpec tutorial")
    visit root_path
    click_link "Sign in"
    fill_in "Email", with: user.email
    fill_in "Password", with: user.password
    click_button "Log in"
    click_link "RSpec tutorial"
    check "Finish RSpec tutorial"
    expect(page).to have_css "label#task_#{task.id}.completed"
    expect(task.reload).to be_completed
    uncheck "Finish RSpec tutorial"
    expect(page).to_not have_css "label#task_#{task.id}.completed"
    expect(task.reload).to_not be_completed
  end

be_completed 匹配器matcher :

js:true选项传给scenario,Capybara默认带JS驱动。

然后变更运行浏览器,换为Chrome运行测试

配置:

1. spec/rails_helper.rb中把下面一行注释去掉,

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

2. 创建文件 spec/support/capybara.rb,并写:

Capybara.javascript_driver = :selenium_chrome

3. 安装ChromeDriver.需要看

见 ChromeDriver 官方文档。

如果安装了brew,则敲击brew install chromedriver

出现提示:

Error: No available formula with the name "chromedriver"
It was migrated from homebrew/core to caskroom/cask.
You can access it again by running:
  brew tap caskroom/cask
And then you can install it by running:
  brew cask install chromedriver

安装提示安装,成功。

运行bin/rspec spec/features/tasks_spec.rb,弹出chrome窗口,我们的应用在这个窗口加载,自动点击连接填写表单自动,完成任务,测试成功。为了运行效率只在需要JavaScript的案例上面使用js:true

6.7headless driven

不在浏览器窗口 运行测试,只在命令行界面中运行。禁止打开新窗口。

让Selenium在Chrome的无界面模式下运行测试:

编辑spec/support/capybara.rb.

Capybara.javascript_driver = :selenium_chrome_headless

6.8 等待JavaScript执行完毕

默认情况下,Capybara等待2了,如果没有按钮出现,放弃,这个时间可以调整。

Capybara.default_max_wait_time = 15

这个设置在rspec/rails_helper.rb内加载的地方就行,可以放在capybara.rb文件中。

缺点:整体速度变慢,

可以使用using_wait_time针对特定案例修改时间。

scenario "runs a really slow process" do

using_wait_time(15) do

# 测试代码

end

end

6.9小结

功能测试,先在浏览器实操以下模拟需要的步骤,然后在使用Capybara一一实现。

站在客户角度,看有些操作是否可以简化,甚至删除,从而提升用户体验。


Rspec: feature spec 功能测试 测试JavaScript.的更多相关文章

  1. 通过Jasmine和Guard自动测试JavaScript

    原文标题:Autotesting JavaScript with Jasmine and Guard 原文地址:http://edspencer.net/2013/06/15/autotesting- ...

  2. 一个免费的自动化跨平台测试JavaScript的工具——BrowserSwarm

    BrowserSwarm是一个免费工具,能够自动化跨平台测试JavaScript.

  3. 使用Jest测试JavaScript (入门篇)

    1 什么是 Jest? Jest是 Facebook 的一套开源的 JavaScript 测试框架, 它自动集成了断言.JSDom.覆盖率报告等开发者所需要的所有测试工具,是一款几乎零配置的测试框架. ...

  4. Mozilla正在SpiderMonkey中测试JavaScript并行计算

    Mozilla正致力于实现JavaScript“并行(parallelism)计算”,以便充分利用硬件性能.Dave Herman是Mozilla Research的首席研究员和策略总监.近日,他在一 ...

  5. 运用PhantomJS测试JavaScript

    我认为我不需要说服你,测试你的JavaScript代码是一个好主意.但是,测试需要DOM操作的JavaScript代码有时候确是繁琐的.这意味着你需要在浏览器中测试代码而不能使用终端,对吗?错了,事实 ...

  6. 测试JavaScript数组Array

    <script> var numbers = [1, 2, 3, 4, 5]; function isLessThan3(value,index,array) { var returnVa ...

  7. [js测试]JavaScript Web Quiz By davidshariff

    Question1 var foo = function foo() { console.log(foo === foo); }; foo(); 输出是"true",因为foo就指 ...

  8. Rails 4.0 bundle exec rspec spec/requests/xxx 测试失败的解决

    rails项目没有使用默认的单元测试包,而是使用了rspec-rails来测试. 按照文档说明首先生成对应的测试文件: rails generate integration_test xxx invo ...

  9. 新书《编写可测试的JavaScript代码 》出版,感谢支持

    本书介绍 JavaScript专业开发人员必须具备的一个技能是能够编写可测试的代码.不管是创建新应用程序,还是重写遗留代码,本书都将向你展示如何为客户端和服务器编写和维护可测试的JavaScript代 ...

随机推荐

  1. office word 2010 怎么把左侧的标题大纲调出来?

    有时候打开Word很希望出现左边的大纲,可是有时候就不出来,对word一些操作都忘得差不多了,这个小问题确实还是让我迷糊了一下~~ 网上的解决方案是: 打开Word2010文档窗口,切换到“视图”功能 ...

  2. Python: os.listdir()

    os.listdir(): 返回一个列表,此列表包含参数路径下的的文件名或文件夹名.这个列表以字母为顺序. eg: >>>import os >>>dirs=os. ...

  3. python进程、多进程

    进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体:在当 ...

  4. java使用反射给对象属性赋值的两种方法

    java反射无所不能,辣么,怎么通过反射设置一个属性的值呢? 主程序: /** * @author tengqingya * @create 2017-03-05 15:54 */ public cl ...

  5. Python入门之python可变对象与不可变对象

    本文分为如下几个部分 概念 地址问题 作为函数参数 可变参数在类中使用 函数默认参数 类的实现上的差异 概念 可变对象与不可变对象的区别在于对象本身是否可变. python内置的一些类型中 可变对象: ...

  6. python no module named 'win32api'

    在cmd下执行 pip install pypiwin32api   即可

  7. 20145104张家明 《Java程序设计》第三次实验设计

    合作伙伴是20145103 下面是我们的git成果 首先下载他托管上去的代码 然后运行下载的代码 之后对下载的代码进行修改 然后推送上去 下载修改后的代码并运行 •软件工程是把系统的.有序的.可量化的 ...

  8. 微信小程序——3、逻辑js文件

    逻辑层js文件 微信小程序前端进行了层次划分,分为逻辑层和视图层.逻辑层实现对数据的加工和处理.与HTML页面相似,逻辑层使用JavaScript编写.逻辑层将数据处理后发送至视图层,同时接受视图层的 ...

  9. TensorFlow入门(四) name / variable_scope 的使

    name/variable_scope 的作用 欢迎转载,但请务必注明原文出处及作者信息. @author: huangyongye @creat_date: 2017-03-08 refer to: ...

  10. C++类的静态成员变量初始化 Win32 API 定时器使用

    1.类的静态成员变量 .h 类声明入下 class A { public: static int x; }; .cpp文件 这样初始化. ; 2.定时器使用 1.SetTimer(HWND,UINT, ...