🌐

k6 DevTools recorder を使ってみた

2024/10/16に公開

k6 DevTools recorder とは

k6 のブラウザテストのスクリプトを生成してくれるツール(Chrome 拡張機能)です。
Chrome DevTools Recorder を使って記録したフローをスクリプトに変換してくれます。

https://grafana.com/docs/k6/latest/using-k6/test-authoring/create-tests-from-recordings/using-the-devtools-recorder/

使ってみる

Create a script from a recording に使い方が書いてあります。
Chrome DevTools Recorder の使い方に従ってフローを記録して Chrome 拡張機能でスクリプトに変換するだけです。

https://test-api.k6.io/ で画面をポチポチしてスクリプトを生成してみました。

// Code generated by ⛰ k6 DevTools Recorder
import {
  Runner
} from "https://jslib.k6.io/k6-replay/1.0.0/index.js"

export const options = {
  scenarios: {
    browser: {
      executor: "shared-iterations",
      options: {
        browser: {
          type: "chromium",
        },
      },
    },
  },
  thresholds: Runner.thresholds,
}

export default async function() {
  const runner = new Runner({
    title: "Recording 2024/10/16 at 20:23:33",
    steps: []
  }, {})

  await runner.runBeforeAllSteps()

  await runner.runStep({
    type: "setViewport",
    width: 1342,
    height: 819,
    deviceScaleFactor: 1,
    isMobile: false,
    hasTouch: false,
    isLandscape: false
  })

  await runner.runStep({
    type: "navigate",
    url: "https://test-api.k6.io/",
    assertedEvents: [{
      type: "navigation",
      url: "https://test-api.k6.io/",
      title: "HTTP and WebSocket APIs for experimentation with k6"
    }]
  })

  await runner.runStep({
    type: "click",
    target: "main",
    selectors: [
      ["aria//public/crocodiles/[role=\"link\"]"],
      ["section:nth-of-type(1) > table:nth-of-type(1) tr:nth-of-type(1) a"],
      ["xpath//html/body/main/section[1]/table[1]/tbody/tr[1]/td[2]/a"],
      ["pierce/section:nth-of-type(1) > table:nth-of-type(1) tr:nth-of-type(1) a"]
    ],
    offsetY: 5.921875,
    offsetX: 89,
    assertedEvents: [{
      type: "navigation",
      url: "https://test-api.k6.io/public/crocodiles/",
      title: ""
    }]
  })

  await runner.runStep({
    type: "click",
    target: "main",
    selectors: [
      ["aria/OPTIONS"],
      ["form.button-form > button"],
      ["xpath///*[@id=\"content\"]/div[1]/form[2]/button"],
      ["pierce/form.button-form > button"]
    ],
    offsetY: 19,
    offsetX: 33.421875
  })

  await runner.runAfterAllSteps()
}

K6_BROWSER_HEADLESS=false にしてブラウザの GUI を表示して試してみます。

❯ k6 version
k6 v0.54.0 (go1.23.1, darwin/arm64)K6_BROWSER_HEADLESS=false k6 run test.js

         /\      Grafana   /‾‾/  
    /\  /  \     |\  __   /  /   
   /  \/    \    | |/ /  /   ‾‾\ 
  /          \   |   (  |  ()  |
 / __________ \  |_|\_\  \_____/ 

     execution: local
        script: test.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * browser: 1 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

ERRO[0004] Failed to load resource: the server responded with a status of 404 (Not Found)  browser_source=network line_number=0 source=browser stacktrace="<nil>" url="https://test-api.k6.io/favicon.ico"

     ✓ Expect page title to be 'HTTP and WebSocket APIs for experimentation with k6'
     ✓ Expect page url to be 'https://test-api.k6.io'
     ✓ Expect page url to be 'https://test-api.k6.io/public/crocodiles'

     browser_data_received.......: 323 kB  65 kB/s
     browser_data_sent...........: 6.9 kB  1.4 kB/s
     browser_http_req_duration...: avg=427.08ms min=179.43ms med=459.61ms max=714.64ms p(90)=651.52ms p(95)=689.73ms
     browser_http_req_failed.....: 5.55%   1 out of 18
     browser_web_vital_fcp.......: avg=1.09s    min=948.9ms  med=1.09s    max=1.24s    p(90)=1.21s    p(95)=1.23s   
     browser_web_vital_fid.......: avg=200µs    min=200µs    med=200µs    max=200µs    p(90)=200µs    p(95)=200µs   
     browser_web_vital_lcp.......: avg=1.09s    min=948.9ms  med=1.09s    max=1.24s    p(90)=1.21s    p(95)=1.23s   
     browser_web_vital_ttfb......: avg=660.8ms  min=637.6ms  med=660.8ms  max=684ms    p(90)=679.36ms p(95)=681.68ms
   ✓ checks......................: 100.00% 3 out of 3
     data_received...............: 0 B     0 B/s
     data_sent...................: 0 B     0 B/s
     iteration_duration..........: avg=4.34s    min=4.34s    med=4.34s    max=4.34s    p(90)=4.34s    p(95)=4.34s   
     iterations..................: 1       0.199924/s
   ✓ playback_failed.............: 0       0/s
     playback_flows..............: 1       0.199924/s
     playback_steps..............: 4       0.799697/s
     vus.........................: 1       min=1       max=1
     vus_max.....................: 1       min=1       max=1


running (00m05.0s), 0/1 VUs, 1 complete and 0 interrupted iterations
browser ✓ [======================================] 1 VUs  00m05.0s/10m0s  1/1 shared iters

ブラウザが起動して Chrome DevTools Recorder で記録した操作が期待通り実行されていることを確認できました。favicon のエラーが出てますがテスト自体は成功しています。

注意点

2024/10/16時点では生成されたスクリプト内で使われている k6-replay に関するドキュメントやリポジトリが見当たらないためスクリプトをカスタマイズしたりすることは難しそうです。

Discussion