DSL domain specific language of Kola

How we design Kola - ApiHugKola background, Kola a consumer driver tester framework
https://apihug.com/zhCN-docs/kola/003_dsl_contract
Concept
在 Kola 定位中 Kola 是什么, 是致力于提供一个让相关各方都能够理解共同创造的测试框架和工具。
同时 Kola 是建立于业界成熟的实践和方法论上,综合工程实践的便利和流程的严谨性, 在主流的测试思想中,这三种 Kola 深受启发:
- TDD: Test driven development
- BDD: Behaviour-Driven Development
- 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")}
UserServiceApiHug 服务, 最好全路径引入, 编译时会校验, 相对路径也可以, 但是保证无重复, IDEA 提供工具自动化完成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 | 附件 |
cookies | cookie 信息 |
headers | header 信息 |
queries | 请求参数(动态) |
paths | 路径参数(动态) |
请求体
JSON 定义:
json("""
{"name": "jake","age": 18,"address": {"country": "$V('from')","zip": 200021}
}
""")
- 标准 json 定义方式
- 动态环境变量
$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()})
- 基于 json path
- Assertj Assertions 全部 bridge, Fluent assertions
- 声明式校验,一写到底,一气呵成
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:
- common: base configuration
- different env overwrite configuration property
- 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", {}
}
参考
- spring test spring-framework/spring-test
- spring test doc spring-framework/reference/testing
- spring boot test spring-boot-test
- spring boot test doc spring-boot/testing
- spring contract spring-cloud-contract
- spring contract doc spring-cloud-contract reference
- cucumber Behaviour-Driven Development
- Spock: Spock Framework
- karate Test Automation Made Simple
- Contract Test Martin Fowler
- PactFlow SmartBear Consumer Driven
- Contract Testing Vs Integration Testing from PactFlow
- Consumer-Driven Contracts: A Service Evolution Pattern
相关文章:
DSL domain specific language of Kola
How we design Kola - ApiHugKola background, Kola a consumer driver tester frameworkhttps://apihug.com/zhCN-docs/kola/003_dsl_contract Concept 在 Kola 定位中 Kola 是什么, 是致力于提供一个让相关各方都能够理解共同创造的测试框架和工具。 同时 Kola 是建立于业界…...
【RISC-V设计-05】- RISC-V处理器设计K0A之GPR
【RISC-V设计-05】- RISC-V处理器设计K0A之GPR 文章目录 【RISC-V设计-05】- RISC-V处理器设计K0A之GPR1.简介2.设计顶层3.内部结构4.端口说明5.设计代码6.总结 1.简介 通用寄存器(General Purpose Register)是处理器设计中的重要组成部分,在…...
Linux/C 高级——shell脚本
1. shell脚本基础概念 1.1概念 shell使用方式:手动下命令和脚本 脚本本质是一个文件,文件里面存放的是特定格式的指令,系统可以使用脚本解析器翻译或解析指令并执行(它不需要编译)。 shell脚本本质:shell命…...
SpringBoot面试题整理(1)
面试整理 前置知识 ApplicationContextInitializerApplicationListenerBeanFactoryBeanDefinitionBeanFactoryPostProcessorAwareInitializingBean/DisposableBeanBeanPostProcessor 面试题 SpringBoot启动流程IOC容器初始化流程Bean声明周期Bean循环依赖SpringMVC执行流程…...
LVS原理及实例
目录 LVS原理 LVS概念 lvs集群的类型 lvs-nat 解释 传输过程 lvs-dr 解释 传输过程 特点 lvs-tun LVS(Linux Virtual Server)常见的调度算法 防火墙标记(Firewall Marking)结合轮询调度 实战案例 lvs的nat模式配置 …...
Spring统一功能处理:拦截器、响应与异常的统一管理
目录 一.拦截器 二.统一数据返回格式 三.统一异常处理 一.拦截器 拦截器是Spring框架提供的核⼼功能之⼀,主要⽤来拦截⽤⼾的请求,在指定⽅法前后,根据业务需要执⾏预先设定的代码。 也就是说,允许开发⼈员提前预定义⼀些逻辑…...
深入理解小程序的渲染机制与性能优化策略
一、小程序的渲染机制 小程序的渲染机制主要由两部分组成:渲染层和逻辑层。渲染层负责页面的渲染,逻辑层负责处理业务逻辑和数据处理。两者通过一个安全的、高效的通信机制进行数据传输和事件通知。 渲染层:在渲染层,WXML 模板会…...
Linux:多线程(二.理解pthread_t、线程互斥与同步、基于阻塞队列的生产消费模型)
上次讲解了多线程第一部分:Linux:多线程(一.Linux线程概念、线程控制——创建、等待、退出、分离,封装一下线程) 文章目录 1.理解Linux下线程——理解tid2. Linux线程互斥2.1相关概念2.2引入问题分析问题解决思路 2.3L…...
Pandas中`str`对象解析与应用实例
在数据科学领域,字符串操作是数据清洗和处理中不可或缺的一部分。Pandas的str对象为我们提供了一个强大而灵活的字符串操作方法集。本文将深入探讨str对象的各种应用,并通过代码示例和输出展示如何有效地处理字符串数据。 关键词 Pandas, 字符串操作, …...
C语言典型例题29
《C程序设计教程(第四版)——谭浩强》 习题2.6 设圆半径r1.5,圆柱高h3,求圆周长、圆面积、圆球表面积、圆球体积、圆柱体积。 scanf输入结果,输出计算结果,输出时要有文字说明,取小数点后两位数…...
Docker 常规安装简介
Docker常规安装简介 欢迎关注我的B站:https://space.bilibili.com/379384819 1. 安装mysql 1.1 docker hub上面查找mysql镜像 网址: https://hub.docker.com/_/mysql 1.2 从docker hub上(阿里云加速器)拉取mysql镜像到本地标…...
理解张量拼接(torch.cat)
拼接 维度顺序:对于 3D 张量,通常可以理解为 (深度, 行, 列) 或 (批次, 行, 列)。 选择一个dim进行拼接的时候其他两个维度大小要相等 对于三维张量,理解 torch.cat 的 dim 参数确实变得更加抽象,但原理是相同的。让我们通过一…...
指针基础知识(笔记)
文章目录 1. 概念理解2. 空指针和野指针3. 计算4. 小结5. size_t6. 案例一: 指针查找并返回指定元素索引7. 指针访问多维数组(涉及 int (*ptr)[3]解析)8. 指针数组9. 函数的值传递与地址引用传递① 函数的值传递(pass by value)② 地址传递(pass by reference) 10. 案例二&…...
[Python学习日记-3] 编程前选择一个好用的编程工具
[Python学习日记-3] 编程前选择一个好用的编程工具 简介 PyCharm IDE的安装 PyCharm IDE安装后的一些常规使用 简介 在踏上 Python 编程的精彩旅程之前,选择一款得心应手的编程工具无疑是至关重要的一步。这就如同战士在出征前精心挑选趁手的武器,它将…...
智能化的Facebook未来:AI如何重塑社交网络的面貌?
随着人工智能(AI)技术的飞速发展,社交网络的面貌正在经历深刻的变革。Facebook(现Meta Platforms)作为全球最大的社交媒体平台之一,正积极探索如何利用AI技术来提升用户体验、优化内容管理并推动平台创新。…...
安全启动的原理
安全启动(Secure Boot)是一种用于确保设备只运行经过认证的软件的安全机制。其核心原理和步骤如下: 1. **硬件信任根(Root of Trust, RoT)**: - 安全启动过程始于硬件信任根,通常是设备上的…...
【ML】pre-train model 是什么如何微调它,如何预训练
【ML】pre-train model 是什么如何微调它,如何预训练 0. 预训练模型(Pre-trained Model)0.1 预训练模型的预训练过程0.2 如何微调预训练模型0.3 总结 1. Contextualized word Embedding2. 怎么 让 bert 模型变小3. 如何微调模型 0. 预训练模型…...
leetcode代码练习——Java的数据结构(具体使用)
注:Java中所有的泛型必须是引用类型 如<Integer>而不是<int> java提供的数学方法: 求最大值Math.max(10,15),最小值Math.min(10,15) 看取值范围: int范围:-2^31-2^31-1 double范围:-2^63-2^63-1 long范围:-2^63-2…...
sqlserver导出数据脚本
文章目录 sqlserver导出数据脚本任务-生成脚本 sqlserver导出数据脚本 任务-生成脚本...
html+css 实现hover中间展开背景
前言:哈喽,大家好,今天给大家分享htmlcss 绚丽效果!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...
