第一,自动化代码能够做到 修改一两处就能维护好这些受影响的用例
,我感觉其实更花精力,还必须得项目很稳定。
第二, 修改一两处就能维护好这些受影响的用例
,这种情况太理想了,更多时候 UI 是全部大改的,代码基本要重写。而且你要应用的项目不止一个,有 N 个项目都在迭代更新,真的能有这么多份写好的自动化代码吗?
第三,本身手工测试,就是要点点点,只不过这次,在 dev 环境点完了,开了录制,接下来就可以在 test / staging / release 上快速回归,不需要投入会写代码的人力物力。
第四,如果真的能够定位到 修改一两处就能维护好这些受影响的用例
,其实对于录制来说,真的不用重新录,把某些改动的地方匹配替换一下就行了。
不用维护,哪些 UI 改了就重录替代用例,快录快用。目的是没改的快速回归,以及很多第三方的置入功能,比如 mock 比如 埋点监听 等等。
愿闻其详
目前只做了基于 puppeteer 的,mitmproxy / anyproxy 都可以扩展兼容。
持续思考,持续进步 hhh
正解
真要看重性能,可能你得看下 boomer
......
时间戳,上下游响应之类的关联信息,你要想伪造那份 log 不好搞,不如直接自己写个 log 生成 request 的发生器
因为我用的是 mac 当然这样写。Chromium 又不是只有 mac 版本,换一下就行。
不要去外包!
不要去外包!
不要去外包!
可以的,你在执行的时候保存下 log,然后写个页面每次去获取这个 log,解析一下包装成你想要的数据就行了。
才看到 hhh
是鸭,趋势所在
那就是 grafana 里面设置连接数据库的信息不对。
你选 server 模式的时候,不能写 http://localhost:9090 http://127.0.01:9090,要填本机的真实 ip 地址。
传错地方了,已上传,再试一下~
要带 tag,docker pull shaonian/goc:v1.0
你直接用 docker-compose 起不就完了,干嘛一个个单独拉。
你不是用 docker-compose.yml 起的吗
你应该还没有执行压测吧,没有执行压测那肯定没有测试数据。
如果不是这个问题,就得看看容器的日志,你截图页面没啥意义。
还有要注意一下 grafana 里面配置 prometheus 的一些连接信息,这里不对也会这样。
你这个是 window 10 家庭版,不是专业版,没有打开 Hyper-V 的选项。
要打开这个才能装 docker。
hhhhh
直接代码层面引入第三方插件,智能生成 api 文档。(比如其他人说的 swagger)
脚本实现,抓数据,手写转 swagger 格式。
借助第三方平台实现,现在 yapi 接口管理平台可以导入 har 当文档了,对你来说,应该是最佳选择鸭。
你要明白一个问题,那就是为啥这里只有 max-rps 没有什么 min-rps 。。。
你说的 在 locust 中可以通过 Semaphore 来等待 2000 个 VU 起来
boomer 不用等,开多几个 pod 开场就 2000 个 goroutine。。。
对于 go 来说,只要资源充足,你一开始就能直接产生 2000 个 goroutine,甚至能更多 。。。
--max-rps 是怕并发太多你系统撑不过来,用来限制协程并发数的。。。
你看看实现。
// Start to refill the bucket periodically.
func (limiter *RampUpRateLimiter) Start() {
limiter.quitChannel = make(chan bool)
quitChannel := limiter.quitChannel
// bucket updater
go func() {
for {
select {
case <-quitChannel:
return
default:
atomic.StoreInt64(&limiter.currentThreshold, limiter.nextThreshold)
time.Sleep(limiter.refillPeriod)
close(limiter.broadcastChannel)
limiter.broadcastChannel = make(chan bool)
}
}
}()
// threshold updater
go func() {
for {
select {
case <-quitChannel:
return
default:
nextValue := limiter.nextThreshold + limiter.rampUpStep
if nextValue < 0 {
// int64 overflow
nextValue = int64(math.MaxInt64)
}
if nextValue > limiter.maxThreshold {
nextValue = limiter.maxThreshold
}
atomic.StoreInt64(&limiter.nextThreshold, nextValue)
time.Sleep(limiter.rampUpPeroid)
}
}
}()
}
你只要不设置 rampUpPeroid
rampUpStep
只设置 maxThreshold
资源充足的情况下马上就能触发这个逻辑。
if nextValue > limiter.maxThreshold {
nextValue = limiter.maxThreshold
}
至于你说的 并发每隔一分钟来一次
boomer 并发的是函数,你在函数结尾直接 sleep 一分钟,不就 2000 并发一次了吗。。。
具体例子已给出 ~ 见最佳回复
按日志格式造 request 实现不难,难的是把业务逻辑和规则融入进去,就比如你的第二个问题,才是第一个问题的核心。
举个例子:
线上日志
GET /product
HOST prod.com
PARAM token: old-token
PARAM name: 1-prod-product
发起 prod 请求前,复制一份到 test,更改 HOST 和 匹配规则
if host == "test.com" && "url == /product"
匹配 替换类规则 RULE [1,2]
RULE 1 代表登录类替换逻辑,若 PARAM 匹配到 token cookie ..., 替换成万能 token 或调用函数造 token。
RULE 2 代表关联类替换逻辑,若 PARAM 匹配到 name ... ,根据 get_product(host,token) 获取对应环境的值并替换。
GET /product
HOST test.com
PARAM token: new-token
PARAM name: 2-test-product
然后同时发出,然后 diffy json(response_prod, response_test)
这里还可以做噪音匹配规则,这样对照组都能省,直接去噪。
比如增加 NOISE_RULE [1]
NOISE_RULE 1 代表通用类去噪音规则,diffy --ignore time, createtime, updatetime...
最后,再借助 boomer 登记 diffy,就可以自己直接实现 diffy 归纳路由。
if diff := jsondiff.Diff(response_prod, response_test, diffopts.IgnorePaths([]string{"/time"})); diff != "": {
boomer.RecordFailure("GET", "/product", 0, string(diff))
}
PS:
正确打开方式之前的两幅图,一个是 buger/goreplay 的回放,以及 opendiffy/diffy 的差异对比,这也是传统模式的 录制 + 回放
,主要讲解传统模式 录制 + 回放
的原理,以及落地以后的一些缺陷。
而后提出的优化,也是基于体验这个流程以后,弥补其中的一些不足,并提出优化实现方案。
可以理解为,把线上的流量录制成特定的日志格式,脚本是解析日志格式去发请求的,只要格式保持一致,就通用于大部分的项目。然后,涉及标记的动态数据得替换生成。
不过能理解成接口自动化 + 压测也对,原理都是把请求经过处理,同时对多个服务发出,并实时 diffy 响应。只不过一个是手写代码构造 request 一个是读线上日志构造 request。