k6系列之browser调研

调研

github地址

根据源码分析,k6的browser有三个大模块,一是browser,一个是chromium,还有一个是devices。根据官方给的例子,第一个模块有详细使用案例。

由于browser目前处于实验阶段,go源码中的chromium模块并未打包进入k6的二进制文件中。根据下面查看到的源码,可以看到只是注册返回了browser devices两个模块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//register.go
func init() {
k6modules.Register("k6/x/browser", browser.New())
}
//browser/module.go
func New() *RootModule {
return &RootModule{
PidRegistry: &pidRegistry{},
initOnce: &sync.Once{},
}
}

return &ModuleInstance{
mod: &JSModule{
Browser: mapBrowserToGoja(moduleVU{
VU: vu,
pidRegistry: m.PidRegistry,
browserRegistry: newBrowserRegistry(vu, m.remoteRegistry, m.PidRegistry),
taskQueueRegistry: newTaskQueueRegistry(vu),
}),
Devices: common.GetDevices(),
},
}

也就是说,当你尝试如下,会报错无法使用,因为导入的chromium为空。

1
2
3
4
5
6
7
8
import { chromium } from 'k6/experimental/browser'
export default async function () {
const browser = chromium.launch()
const page = browser.newPage()
page.goto('https://test.k6.io/my_messages.php');
page.close()
browser.close()
}

browser模块的使用之设置cookie

由于所在登录网页有svg的验证码,尝试通过解析验证码的方式来登录,结果有点困难;因此转向寻找设置默认cookie来跳过身份识别直接登录网页。playwright也有类似方法。k6本意上browser最终会尽可能和playwright的api一致,来使得大家不需重新学习新的api(官网说的)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//查看源码common/browser_context.go此处有设置cookies方法,因此需要先行定义一个BrowserContext出来
func (b *BrowserContext) AddCookies(cookies []*Cookie) error {
return nil
}
//mapping_test.go看测试代码
type browserAPI interface {
Close()
Context() *common.BrowserContext
CloseContext()
IsConnected() bool
NewContext(opts goja.Value) (*common.BrowserContext, error)
NewPage(opts goja.Value) (*common.Page, error)
On(string) (bool, error)
UserAgent() string
Version() string
}
//browser/mapping.go
// mapBrowser to the JS module.
func mapBrowser(vu moduleVU) mapping { //nolint:funlen
rt := vu.Runtime()
return mapping{
"context": func() (*common.BrowserContext, error) {
},
"closeContext": func() error {
},
"isConnected": func() (bool, error) {
},
"newContext": func(opts goja.Value) (*goja.Object, error) {
},
"userAgent": func() (string, error) {
},
"version": func() (string, error) {
},
"newPage": func(opts goja.Value) (mapping, error) {
},
}
}
//根据上面代码可知,应该是调用newContext来返回一个BrowserContext

代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//以下代码经过测试没问题
import { browser } from 'k6/experimental/browser';

export const options = {
scenarios: {
ui: {
executor: 'shared-iterations',
options: {
browser: {
type: 'chromium',
},
},
},
},
}

export default async function () {
const context = browser.newContext();
const page = context.newPage();
context.addCookies([{
name: 'sessionToken',
value: '*****',
domain: 'localhost:8088',
path: '/',
expires: 0, // 设置为 0 表示会话 cookie,你可以设置具体的过期时间
httpOnly: false, // 是否为 HTTP-only cookie
secure: false, // 是否要求安全连接
sameSite: 'Lax', // SameSite 属性,可以是 'Lax''Strict''None'
},{
name: '*****',
value: '*****',
domain: 'localhost:8088',
path: '/',
expires: 0, // 设置为 0 表示会话 cookie,你可以设置具体的过期时间
httpOnly: false, // 是否为 HTTP-only cookie
secure: false, // 是否要求安全连接
sameSite: 'Lax', // SameSite 属性,可以是 'Lax''Strict''None'
}]);

console.log('####',context.cookies())
// 打开需要登录的页面
await page.goto('http://localhost:8088/****/****/****');
//截图看看最后对不对
page.screenshot({ path: 'screenshot.png' });
// 关闭浏览器
page.close();
}

附k6 browser指标的意义:
这些指标是 Web Vitals 的一部分,Web Vitals 是一组被 Google 推荐的用于衡量网站性能的指标。

  1. browser_web_vital_cls(Cumulative Layout Shift): 衡量页面上元素的不稳定性,尤其是在加载期间。CLS 表示在页面生命周期内用户体验中不断发生的不期望的布局变化的累积分数。

  2. browser_web_vital_fcp(First Contentful Paint): 标志着用户能够看到页面内容的时间点。具体来说,它是页面开始加载到浏览器绘制页面的第一个像素的时间。

  3. browser_web_vital_lcp(Largest Contentful Paint): 衡量页面加载期间最大的可见内容块(例如图片或文本块)的渲染时间。LCP 提供了有关页面加载性能的重要信息。

  4. browser_web_vital_ttfb(Time to First Byte): 衡量用户发起请求到接收到来自服务器的第一个字节所花费的时间。它反映了服务器响应的速度。

k6 browser和Playwright区别?

k6 browser我的理解(至于Playwright先按下不表,没有调查就没有发言权)

  • 更真实模拟用户,可以多并发用户,以计算整体平均页面性能数据(这个可能是比Playwright更优秀的存在,毕竟单一一次测试结果未必可靠)
  • 主要关注于整体性能测试,提供了页面级别的性能指标,而不是每个请求的详细数据(也许未来会支持?或者自行改源码)
  • 支持可视化,对接influxdb和grafana(可视化存入influxdb发现有存储每个请求的数据,也许能做到细化?)

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!