测试驱动开发与API文档
可以通过时序图来进行开发。
测试驱动开发就是先测试再编码
方法论TDD测试驱动开发
目前使用的测试库为rspec,由于还要测接口API,需要使用到RSpec API Doc Generator在gemfile文件中配置添加gem 'rspec_api_documentation'
。然后再bundle
它,bundle install
。可以按照文档给予的案例,创建spec/acceptance
,执行命令为mkdir spec/acceptance
,编辑创建order测试用例code spec/acceptance/orders_spec.rb
,具体内容详见链接。
require 'rails_helper'
require 'rspec_api_documentation/dsl'
resource "测试items" do
get "/api/v1/items" do
example "Listing items" do
do_request
expect(status).to eq 200
end
end
end
然后生成文档bin/rake docs:generate
,可以在api/doc
里看到创建文档HTML,使用npx http-server .
,起一个服务打开页面,可以查看/api/v1/items
接口的文档内容。
由于用的是官方文档的案例,现在创建验证邮箱code的API的文件,在spec/acceptance/
目录下创建validation_codes_spec.rb
文件,编写测试的请求,目前测试请求返回值status设为400的时候则成功。
require 'rails_helper'
require 'rspec_api_documentation/dsl'
resource "验证码" do
post "/api/v1/validation_codes" do
example "请求发送验证码" do
do_request
expect(status).to eq 400
end
end
end
在app/models/validation_code.rb
,修改email为必填。
class ValidationCode < ApplicationRecord
validates :email, presence: true
end
修改validation_codes_controller.rb
文件,失败的时候status为400。
class Api::V1::ValidationCodesController < ApplicationController
def create
code = SecureRandom.random_number.to_s[2..7]
validation_code = ValidationCode.new email: params[:email],
kind: 'sign_in', code: code
if validation_code.save
render json:{ code: code } , status: 200
else
render json: { errors: validation_code.errors }, status: 400
end
end
end
API文档只展示正确示例
为了展示正确的示例,还需要修改接口测试文件,具体内容详见链接。
require 'rails_helper'
require 'rspec_api_documentation/dsl'
resource "验证码" do
post "/api/v1/validation_codes" do
parameter :email, type: :string
# 接受一个参数email 类型为 string
let(:email) { '1@qq.com' }
# 请求时带上测试用例
example "请求发送验证码" do
do_request
expect(status).to eq 200
end
end
end
修改后在执行bin/rake docs:generate
,之后可以在启动的接口页面服务中看到如下的内容。
解决请求中的JSON问题
配置spec_helper.rb
给在请求类型为acceptance的带上请求头参数。
require 'rspec_api_documentation'
RspecApiDocumentation.configure do |config|
config.request_body_formatter = :json
end
RSpec.configure do |config|
# 配置在每次请求之前如果发现请求的类型是accpetance的就给加上请求头参数
config.before(:each) do |spec|
if spec.metadata[:type].equal? :acceptance
header 'Accept', 'application/json'
header 'Content-Type', 'application/json'
end
end
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
end
解决显示为接口文档页面body显示[binary data]
的问题,详见issue。
需要创建文件config/initializers/rspec_api_documentation.rb
,定义repsonse_body
的encode
。
# 解决响应中的JSON显示二进制内容的issue
module RspecApiDocumentation
class RackTestClient < ClientBase
def response_body
last_response.body.encode("utf-8")
end
end
end
由于接口发送的验证码是通过邮箱发送的,不应该在接口中展示,则还需要修改validation_codes_controller.rb
和validation_codes_spec.rb
。
class Api::V1::ValidationCodesController < ApplicationController
def create
code = SecureRandom.random_number.to_s[2..7]
validation_code = ValidationCode.new email: params[:email],
kind: 'sign_in', code: code
if validation_code.save
render status: 200
else
render json: { errors: validation_code.errors }, status: 400
end
end
end
require 'rails_helper'
require 'rspec_api_documentation/dsl'
resource "验证码" do
post "/api/v1/validation_codes" do
parameter :email, type: :string
# 接受一个参数email 类型为 string
let(:email) { '1@qq.com' }
# 请求时带上测试用例
example "请求发送验证码" do
do_request
expect(status).to eq 200
expect(response_body).to eq ' '
end
end
end
重新执行rake后可以看到修改后的接口文档,测试接口文档的内容如下所示。