🦄 2024 独立开发者训练营,一起创业!查看介绍 / 立即报名 →

Day 18:Rails 应用的测试

准备一个全新的 Rails 应用,今天我们了解一下 Rails 应用的测试。

创建测试

先为我们要创建的控制器创建一个测试,比如我要创建一个名字是 Pages 的控制器,对这个控制器的测试可以放在 test/controllers 目录的下面,创建一个测试文件,文件名里可以包含控制器的名字,再加上一个 test 后缀:

test/controllers/pages_controller_test.rb

在这个测试文件里,先 require 测试需要的一个助手,名字是 test_helper。每个测试都是一个类,让它继承 ActionDispatch::IntegrationTest。在这个测试文件里添加:

require 'test_helper'

class PagesControllerTest <  ActionDispatch::IntegrationTest
end

在这个测试类里面,每个测试的形式像这样:

  test "说明一下要测试的是什么" do
    # 具体要做的测试
  end

比如我要在 Pages 里面添加一个 about 动作,它处理的是对 /about 这个静态页面的请求。对这个方法的测试可以使用 get 方法请求一下这个静态页面地址,然后断言它会返回 http 的成功状态码,也就是 200。这个测试会像这样:

class PagesControllerTest <  ActionDispatch::IntegrationTest
  test "should get about" do
    get about_url
    assert_response :success
  end
end

先 get 一下 about 页面的地址,这个地址我们用了一个路由的助手方法。断言用了 assert_response,断言的是响应,:success 对应的是一个 http 的状态码,也就是 200 ,表示成功的得到了响应。这个测试的意思就是请求 /about 这个地址,断言得到的响应是 200。

运行测试

再去运行一下这个测试:

rails test

会看到一个错误:

undefined local variable or method `about_url'

提示不认识 about_url,这是一个助手方法,创建了对应的路由以后才会得到这个方法。我们再为应用添加一些东西。先创建 Pages 控制器,然后给它添加 about 方法,再去添加一条路由。

控制器:app/controllers/pages_controller.rb

class PagesController < ApplicationController
  def about
  end
end

路由:config/routes.rb

Rails.application.routes.draw do
  get '/about', to: 'pages#about'
end

再次运行测试:

rails test

会提示:

ActionController::UnknownFormat: PagesController#about is missing a template for this request format and variant.

意思是 about 方法用的视图还不存在,再去为它创建一个对应的视图。

视图:app/views/pages/about.html.erb

<h1>about</h1>

再次运行测试:

rails test

这次就不会再提示错误了,看一下测试的运行的状态,现在会是:

1 runs, 1 assertions, 0 failures, 0 errors, 0 skips

测试报告

使用 minitest-reporters 这个 gem,可以去定制一下运行测试返回的报告,你可以使用不同风格的测试报告。https://github.com/kern/minitest-reporters

首先去为 test 环境添加一个 gem,打开 Gemfile,添加:

group :test do
  gem 'minitest-reporters', '1.1.9'
end

再打开测试的助手:test/test_helper.rb。

添加两行代码:

require "minitest/reporters"
Minitest::Reporters.use!

执行:

bundle install

再次运行测试,现在的测试报告看起来是这样的:

06500708-684d-478e-819b-e8cd1a79f562

默认的 minitest-reporters  的测试报告会带一个进度条。我们可以使用其它风格的报告,比如配置一下使用 Spec 风格的报告:

test/test_helper.rb

把:

Minitest::Reporters.use!

换成:

Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new

现在的测试报告看起来是这样的:

74882856-bae9-480a-8a1e-943ef32c2d57

测试页面标签内容

我想测试请求回来的一个页面上的某个元素里的值,比如页面的标题必须等于什么,这种断言可以使用 assert_select。

test/controllers/pages_controller_test.rb

class PagesControllerTest <  ActionDispatch::IntegrationTest
  test "should get about" do
    get about_url
    assert_response :success
    assert_select "title", "about | App"
  end
end

在 should get about 这个测试里,添加了一条新的断言:

assert_select "title", "about | App"

意思就是请求 /about ,响应回来的内容里面,它的 title 标签的值要是 “about | App”。

运行一下测试,会报错:

b87b9270-ee56-4945-ad93-3b18be70f945

再去编辑一下视图的默认的布局:app/views/layouts/application.html.erb,修改一下它的 title 标签的值:

<title><%= yield :title %> | App</title>

上面定义了一个 :title 区域,这个区域的内容可以在视图里提供给它。

编辑视图:app/views/pages/about.html.erb,添加一行:

<% provide(:title, 'about') %>

意思是,为布局的 :title 区域提供的内容是 about 。这样使用这个视图的页面的 title 元素里的值就会是 about | App。

运行测试,这次就会成功了:

d549ea76-1aa7-49fd-8744-e24745175969

setup

在运行每个测试之前,可以使用 setup 方法去配置一些东西:

class PagesControllerTest <  ActionDispatch::IntegrationTest
  def setup
    @app_name = "App"
  end

  test "should get about" do
    get about_url
    assert_response :success
    assert_select "title", "about | #{@app_name}"
  end
end
Ruby

评论

做测试一般是要测试哪些方面的内容?测最终结果的类型?

我觉得测试就是测试的你想要的结果。做出一些断言,如果断言不成立,你的应用就会出问题。

皓哥,可否讲解下如何在生产环境下,利用docker迁移和部署 rails网站,感觉docker的课程就剩这一个环节了,谢谢!

微信好友

用微信扫描二维码,
加我好友。

微信公众号

用微信扫描二维码,
订阅宁皓网公众号。

240746680

用 QQ 扫描二维码,
加入宁皓网 QQ 群。

统计

14696
分钟
0
你学会了
0%
完成

社会化网络

关于

微信订阅号

扫描微信二维码关注宁皓网,每天进步一点