总文档连接:

RSpec.info/documentation/

如何使用TDD 和 自动化测试来建立一个Rails app。

TDD让你用测试来探索代码的设计。你将学习可利用的工具,并学习用什么工具最好使。Tools comes and tools go, 工具是不断进化的,所以作者希望读者用最少的步骤写出更好的代码。

to help you write great app that do cool things and still catch the train home!

What's in this book?

开始介绍TDD,它为什么起作用,何时用TDD。

然后2章将使用RSpec来为新的Rails app 创建test.

之后几章节将单元测试基础,关于models, 多种方法生成测试数据,使用test doubles(替身) to simulate objects and specify hard-to-reach states.

然后end-to-end tests 集成测试和Capybara.

讨论JavaScript 先学习有JS 代码的end-to-end tests,然后学习JS单元测试。

然后,旅行到其他Rails部分,展示系统支持的工具。

12章还会了解使用Minitest来代替RSpec.

13-14章关于指定的场景测试,包括安全测试,测试第三方services.

15章 Debugging and Troubleshooting failing test.⚠️陌生

16章 关键写快速的代码和快速的写代码

17章 Legacy code 遗产代码,从他人那里继承的代码,等同于bad code.

What You'll Need

最新的Ruby2.5和Rails5.2,RSpec 3.7.1, Minitest 5.11.3

作者说RSpec学习曲线稍微陡峭,但这是业界使用最多的工具。Minitest 学习起来比较容易。

也就是经常说的: sometimes the best practice for learning isn't the best practice for experts.

本书版本的更新:

  • 控制器测试被抛弃,集成测试会被结合RSpe讲解
  • JS内容是新增的,包括集成和单元测试。Rails Webpacker来开发JS代码
  • Capybara 集成现在使用headless Chrome作为Javascript driver。
  • 代码样本从写。 factory_bot作为数据创建方法使用在最新的测试中。

下载代码案例 


第一章 一个预言故事

不写测试的问题是,重构的时候还要手动测试,而写自动化测试几行不花费额外的时间。

写自动化测试可以防止你忘记测试的步骤。

if you do testing well, your work will go faster。

TDD可以减少bug并且容易改正bug。

TDD步骤:

  1. 创建测试。每个测试都应当简单,做一件事情。
  2. 确保测试失败。
  3. 写最简单的代码来通过当前测试。不要担心完整的代码,不要过于向前,步子要小。
  4. 测试通过后,重构改进代码。 去除重复。然后再运行测试。
  5. 重复以上步子
TDD的部分缺点:

当你不知道程序需要做什么的时候,TDD没有什么用。因为如果你不指定用什么断言/期望,就没法写测试。 比如view-testing:这时需要先写一部分代码然后马上测试,灵活一点,作者称为:test-next mode。

在写测试前,先列出一个测试清单,注明你要测试的内容,以防忘记。

在rails 社区,仍有讨论TDD 破坏代码的问题。

作者认为TDD开发不能取代好的设计天赋,TDD仍可能创造bad code。


第2章Test-driven development Basics

Prescription3:(药方->决策)

Initializing objects is a good starting
place for a TDD process. Another good
approach is to use the test to design
what you want a successful interaction of
the feature to look like.

下面跟着案例章节走。只记录重点。

Install RSpec

git init, #建立版本控制系统。

mkdir gatherer  -> cd gatherer

rails new .    -> bundle install

rake db:create:all   -> rake db:migrate

然后,安装gem 'rspec-rails'  ->再次bundle install

rails generate rspec:install #生成初始化文件

⚠️在.rspec, 加上--format documentation

rails spec  #测试是否安装成功。

Where to Start?

初始化对象是 TDD驱动测试开发的好的开始。另一个好方法是使用test来设计一个看起来成功的交互的功能。

建立spec/models/project_spec.rb,然后建立一个project的初始状态:

require 'rails_helper'
Rspec.describe Project do
  it "considers a project with no tasks to be done" do
    project = Project.new
    expect(project.done?).to be_truthy
  end
end

注解:

done?是自定义的方法, be_truthy是内建匹配器,判断actual_value是否是真,不是nil或false。

这是结构:expect(actual_value).to matcher

expect是RSpec定义的方法,接收任意object作为参数并return一个特殊的RSpec对象,这个对象被称为 ExpectationTarget.

然后这ExpectationTarget将作为matcher方法的参数,最后返回结果。

Running the test

使用rspec, 所有目录的文件都会被加载。

每个RSpec文件需要rails_helper文件加载Rails环境,和spec_helper.rb,这里包含非Rails的步骤。

rails_helper.rb会建立固件或预置件。

每个顶级call to RSpec.describe创建一个内部RSpec对象叫做 example group.

example group使用块参数让describe方法被执行。describe方法里面也可以内嵌example groups。

每个descirbe方法内可能包含it方法,每个it方法创造一个独立测试,这个测试叫做example。

在每个example group中先运行before(:all) 在所有案例运行结束后,运行after(:all)

每个案例也有before(:example), after(:example) 钩子方法。

Making the Test Pass

运行rspec会报错, uninitialized constant Project,当然了我没建立这个类。

然后有3个不同的解决办法:

  • 最purist way: 写最少的代码让当前错误通过,不考虑更大范围的事情。
  • Practical way: 写你需要最终写的代码,忽略太小的没有价值的步骤(不用测试了)
  • The teaching way: 介于前两者之间。让TDD既不要陷于细节之中,也不会忽略过多步骤。

作者的态度,偏重purer。作者的经历,有时候因为过于实际了,导致问题没有理解和忽略了本该测试的步骤。

app/models/project.rb

class Project

end

然后再$rspec , ->undefined method `done?' for <Project:0x00007ff65db9b9b8>

定义done?方法,再测试->expected: truthy value      got: nil

class Project
  def done?
    true
  end
end

测试通过!


The Second Test(只记录重点。)

建立了Task.Project and Task都没有继承ActiveRecord。作者的目的是一步步来。


let

使用let重构。 let(:project) {Project.new}

let方法是一个语法糖。定义一个方法,调用这个方法会缓存这个结果。类似:

def me
  @me ||= User.new( name:   "Noel" )
end 

不调用就不存在。

let!  则是在定义let方法后,就始终存在:project变量


be_comlete匹配器,是自定义的。

class Task
  def initialize
    @completed = false
  end
  def mark_completed
    @complete = true
  end
  def complete? #一定带问号,才能成为匹配器be_complete
    @completed
  end
end
RSpec.describe Task, type: :model do
  let(:task) {Task.new}
  it "does not have a new task as complete" do
    expect(task).not_to be_complete
  end

如果没有定义方法 complete?,测试会报错:

expected #<Task:0x00007fe3ac637da0 @completed=false> to respond to `complete?` 


知识点:

  def done?
    tasks.all? {|task| task.complete? }
    # task.all?(&:complete?)
    #这是单块方法,块参数的变形,具体需看<Ruby元编程>。 
  end

# Enumerable#all?  传递每个元素到块如果每次块返回的是true,则all?方法返回true,否则返回false


Adding Some Math

作者在写测试前会想这个测试需要什么,典型的测试结构

Rails 5 Test Prescriptions(everday Rspectest作者推荐) 目录 1-3章的更多相关文章

  1. Rails 5 Test Prescriptions 最后一章,如何测试继承下来的代码,legacy code

    Set expectations 你不可能把一个老旧的代码野兽只用一晚就转变成优雅的奇迹marvel.你需要如下做法: 让自己有好的状态,用15分钟挥舞拳头诅咒之前的程序员 开始工作,这个codeba ...

  2. 老李推荐: 第1章1节《MonkeyRunner源码剖析》概述:前言

    老李推荐: 第1章1节<MonkeyRunner源码剖析>概述:前言   前言 相信大家做过安卓移动平台UI自动化开发的必然会用过,至少听过MonkeyRunner这个名字.MonkeyR ...

  3. 老李推荐:第14章9节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-遍历控件树查找控件

    老李推荐:第14章9节<MonkeyRunner源码剖析> HierarchyViewer实现原理-遍历控件树查找控件   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员 ...

  4. 老李推荐:第14章5节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态

    老李推荐:第14章5节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态   poptest是国内唯一 ...

  5. 老李推荐:第14章6节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-启动ViewServer

    老李推荐:第14章6节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-启动ViewServer   poptest是国内唯一一家培养 ...

  6. 老李推荐:第14章3节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-HierarchyViewer实例化

    老李推荐:第14章3节<MonkeyRunner源码剖析> HierarchyViewer实现原理-HierarchyViewer实例化 poptest是国内唯一一家培养测试开发工程师的培 ...

  7. 老李推荐: 第14章2节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-HierarchyViewer架构概述

    老李推荐: 第14章2节<MonkeyRunner源码剖析> HierarchyViewer实现原理-HierarchyViewer架构概述   HierarchyViewer库的引入让M ...

  8. 老李推荐:第14章1节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-面向控件编程VS面向坐标编程

    老李推荐:第14章1节<MonkeyRunner源码剖析> HierarchyViewer实现原理-面向控件编程VS面向坐标编程   poptest是国内唯一一家培养测试开发工程师的培训机 ...

  9. 老李推荐:第8章7节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-小结

    老李推荐:第8章7节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-小结   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性 ...

随机推荐

  1. HDU 1104 Remainder(BFS 同余定理)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1104 在做这道题目一定要对同余定理有足够的了解,所以对这道题目对同余定理进行总结 首先要明白计算机里的 ...

  2. 理论实践:循序渐进理解AWR细致入微分析性能报告

    1. AWR 概述 Automatic Workload Repository(AWR) 是10g引入的一个重要组件.在里面存贮着近期一段时间内(默认是7天)数据库活动状态的详细信息. AWR 报告是 ...

  3. Python开发【模块】:Urllib(二)

    Urllib实战 1.爬取糗事百科中段子和用户名: 代码实例: # 爬取网站页面内容 import re import urllib.request url = 'https://www.qiushi ...

  4. receive.denyCurrentBranch 推送错误解决

    场景: 1.搭建Ok了一git服务器 2.本机上的现有源码,现在想纳入git源码管理 操作: 1.服务器上创建了工程仓库 git init 2. 客户端使用tortoisegit添加并提交要纳入源码管 ...

  5. Day04 dom详解及js事件

    day04 dom详解 DOM的基础 Document对象 Element对象 Node对象 innerHTML 事件处理 表单验证   上次课内容回顾: JS中ECMAScript用法: JS定义变 ...

  6. 【Loadrunner】LR破解版录制手机脚本

    LR破解版录制手机脚本          最近在网上听到好多童鞋都在问如何用LR做手机性能测试,恰好自己对这方面也挺感兴趣,经过查阅很多资料,形成此文档以做备注~!如果有感觉我写的不对的地方,敬请指正 ...

  7. Notes模板说明

    模板标题 文件名 模板名 用途 1 活动趋势 Activity.ntf StdActivityTrendsDatabase 记录和报告统计信息,这些统计信息描述用户(客户机)对数据库所在的 Domin ...

  8. DIY自己的GIS程序(2)——局部刷新

    绘制线过移动鼠标程中绘制临时线段防闪烁 参考OpenS-CAD想实现绘制线的功能.希望实现绘制线的过程,在移动线的时候没有闪烁和花屏.但是出现了问题,困扰了2天,前天熬的太晚,搞得现在精力都没有恢复. ...

  9. mysql查询表和字段的注释

    1,新建表以及添加表和字段的注释.   create table t_user(        ID INT(19) primary key auto_increment  comment '主键', ...

  10. Django组件拾忆

    知识预览 一 Django的form组件 二 Django的model form组件 三 Django的缓存机制 四 Django的信号 五 Django的序列化 回到顶部 一 Django的form ...