测试涨技术 | 如何为Go语言Web项目做集成测试?

Posted 达内软件测试培训

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了测试涨技术 | 如何为Go语言Web项目做集成测试?相关的知识,希望对你有一定的参考价值。

最新:软件测试免费课程12月25日火热开启,点击文末“阅读原文”快速抢报

【推荐阅读】

测试涨技术 | 如何为Go语言Web项目做集成测试?


  之前的工作中使用 Rails 及其生态中的工具写 Web 项目,而如今使用Go语言开发,最怀念的当数 ActiveRecord的灵活性和 RSpec的语义化测试代码。


测试涨技术 | 如何为Go语言Web项目做集成测试?


  在Go语言中,为了保证项目质量,必然要写测试,简单的单元测试还好,一旦涉及到大量的HTTP请求编码解码,外加数不清的SQL查询,就会让人不想写测试。


为了解决上述两个问题,做如下尝试:

  1、Go语言中的JSON编码解码

  使用 map[string]interface{} 代替预定义的 struct,如此虽可以少定义一些 struct,但各种 type assertion 会让代码变得丑陋不堪。


  2、ORM 可以帮助方便做数据库SQL

  ActiveRecord 是纯OO模型,很多其他语言的ORM也从中做了很多借鉴。由于从语法层面上的限制,Go语言的ORM库基本上都是通过 reflect 拿到表结构,整个写下来看,最多算是提供了一些链式调用的工具吧。


  3、尝试使用qlang

  Go语言设计之初注定不会提供像动态语言式一样的语法糖和灵活性,所以我尝试了 qlang,用它写了一些类似于 rspec 功能的代码,没能达到预期效果,虽然能够和Go语言代码互调,但是其灵活性和ruby差太多,这么比有点过分,毕竟人家 qlang 主要是为Go嵌入式脚本语言设计的。


  4、在go语言中用ruby的语法

  好了,那咱能不能在go语言中用ruby的语法呢?也是有的,goby,但还在茁壮成长,换句话说就是还不成熟,而且人家并不是要写一个ruby编译器,而是想借鉴ruby的语法然后利用Go语言的并发优势以构建高性能微服务。虽然和qlang一样可以与Go语言交互,但并非适合直接运行ActiveRecord/RSpec 库,也不适合造轮子,那它造,就像拿着一个勺子捞丸子,能捞是能捞,但是费劲。


  做了以上尝试和思考,我发现既想使用ActiveRecord/RSpec式的工具,又能和Go语言交互,基本不可能。那就放弃和Go语言交互,只做集成测试。若只想测试HTTP,大可不必使用 ActiveRecord/RSpec,Postman 就够用了,但要是还想检查一下数据库的数据,这就得用 ActiveRecord 了。


取舍之后,重新定义目标:

  1、基于ActiveRecord构建Model。


  2、最终要测试的是整个逻辑处理层HTTP接口的正确性,包括参数的解析,数据的处理与入库,返回的数据。


  3、测试代码运行的过程中生成可读化的文档,已达到对接口及其对数据库的影响如实的体现出来。


  经过一番调研,基于ActiveRecord构建Model完全可以用工具实现。下面就是如何在尽可能少干扰原rspec测试代码的情况下生成文档了。

  

最终做出了一个 rspec-doc gem

  看个例子:

  测试目标 POST http://localhost:6666/dog -d '{"name": "foo", "age": 2}'

  require 'mysql2'

  require 'active_record'

  require 'rspec-doc'

  ActiveRecord::Base.establish_connection(

  adapter: 'mysql2',

  host: 'http://127.0.0.1',

  port: 3306,

  database: 'my_app',

  username: 'root',

  password: 'secret'

  )

  class Dog < ActiveRecord::Base

  end

  RSpec.describe Dog do

  describe 'create' do

  it 'find the inserted dog' do |example|

  resp = RSpecDoc::RestClient.post(example,

  'http://localhost:6666/dog',

  {

  "name": "foo",

  "age": 2

  }.to_json,

  {

  content_type: :json

  })

  expect(resp.code).to eq 200

  dog = Dog.find_by_name 'foo'

  RSpecDoc::ActiveRecord.describe(example, dog) do

  expect(dog.name).to eq 'foo'

  expect(dog.age).to eq 2

  end

  end

  end

  end

  然后运行 rspec dog_spec.rb --require 'rspec-doc' --format RSpecDoc::MarkdownFormatter

  

如果服务正常,则会输出如下:

  ## Dog

  ### create

  - find the inserted dog

  #### Api Request

  POST http://localhost:6666/dog -d '{"name": "foo", "age": 2}'

  **Request Headers**

  | Key | Value |

  | :--- |:--- |

  | Content-Type | json |

  **Request Body**

  ```json

  {

  "name": "foo",

  "age": 2

  }

  ```

  **Response Headers**

  | Key | Value |

  | :--- |:--- |

  | Access-Control-Allow-Origin | * |

  | Content-Type | application/json; charset=UTF-8 |

  | Vary | Origin |

  | Date | Tue, 10 Oct 2017 09:22:26 GMT |

  | Content-Length | 105 |

  **Response Body**

  ```json

  {

  "resultCode": "OK",

  "resultDescription": "成功添加",

  "data": null

  }

  ```

  #### Database Assertion

  **dogs**[id=1]

  | Column | Assertion | Value |

  | :--- |:--- |:--- |

  | name | == | "foo" |

  Finished in 0.01727 seconds (files took 0.76396 seconds to load)

  

这个例子比较简单,却可以看到:

  1、RSpecDoc::RestClient 包装了 rest-client,提供了 HTTP 请求服务,在请求前后生成文档。


  2、RSpecDoc::ActiveRecord 的 describe方法,只要把想要expect的代码原封不动的包进去即可生成文档。


  3、RSpecDoc::MarkdownFormatter 将RSpec结果转化为Markdown。


良好的测试代码意味着什么?

  虽然看起来没什么,但规划良好的测试代码可以做到:

  1、被测试项目不需要改动。


  2、由于ruby语言的灵活性,代码本身有很高的可读性。


  3、以业务为主轴,结构清晰,各部门同事都能看懂。


  4、真实记录HTTP请求,不存在代码与文档不一致问题。


  5、数据库真实测试,却能利用 ActiveRecord 不需要写任何 SQL,甚至不需要定义相关方法。


  当然,不同于普通的rails项目,集成测试要的可读性,所以尽可能用直观的 Hash、Symbol、ActiveRecord 链式调用,减少抽象方法的使用。


免费报名听课!

测试涨技术 | 如何为Go语言Web项目做集成测试?

抓住机会

速速来约

PS:记得查收达妹送你的免费大礼包呦~

测试涨技术 | 如何为Go语言Web项目做集成测试?

*版权声明:

内容与图片均来源于网络(部分内容有修改),如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。

内容推荐:

1、

2、

3、

4、

5、

6、

7、

8、

▲了解更多软件测试资讯,长按上方二维码


点击“ 阅读原文 ”抢报软件测试免费试听课

以上是关于测试涨技术 | 如何为Go语言Web项目做集成测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何为(Angularjs)Web 应用程序进行集成测试

如何为基于 http 的集成测试生成覆盖率报告?

Go 中的高级测试模式:集成测试如何做?

如何为 MEAN 应用程序编写集成测试

如何为 xunit 集成测试编写 GraphQL 变异查询

如何为Linux安装Go语言