使用 k6 下载整个网站

Seb*_*anR 8 load-testing k6

我目前正在评估 k6 是否适合我们的负载测试需求。我们有一个相当传统的网站架构,使用 Apache 网络服务器、PHP 和 MySQL 数据库。使用 k6 发送简单的 HTTP 请求看起来很简单,我认为我们将能够用它测试所有主要功能,因为我们不太依赖 JavaScript,而且大多数页面都是静态的。

但是,我不确定如何处理请求中返回的 HTML 中引用的资源(样式表、图像等)。我们还需要加载它们,因为这有时会导致数据库请求,这必须是负载测试的一部分。

k6 中是否有一些开箱即用的功能可以让您像浏览器一样加载所有资源?我知道 k6 不会渲染页面,我也不需要它。我只需要请求 HTML 内的所有资源。

Мих*_*ков 7

基本上你有两种选择,都有各自的注意事项:

  1. 记录您的会话- 您可以直接从浏览器导出 har (如图所示),也可以使用为您的浏览器制作的扩展程序,即firefoxchromes。两者都应该可以在没有 k6 云帐户的情况下使用,您只需将它们设置为下载 har,当您停止时,它会自动(并且稍微安静地)下载它们。然后使用 k6 中的 har 转换器(已弃用,但仍然有效)或新的har-to-k6转换器。

    如果您有大量页面和/或资源,甚至如果您有单页面样式的应用程序,此方法特别好,因为它只是获取浏览器请求的 HAR 内容然后将其转换为脚本。如果没有需要输入的动态内容(用户名/密码),则大多数情况下可以按原样使用最终脚本。

    这种方法的最大问题是,如果添加 css 文件,则需要重做整个练习。如果您每次更改 css/js 文件名时都会更改或类似的内容,那么问题就更大了。这就是下一个方法的优点:

  2. 使用parseHTML,然后找到您关心的元素并对它们发出请求。
import http from "k6/http";
import {parseHTML} from "k6/html";

export default function() {
    const res = http.get("https://stackoverflow.com");
    const doc = parseHTML(res.body);
    doc.find("link").toArray().forEach(function (item) {
        console.log(item.attr("href"));
        // make http gets for it
        // or added them to an array and make one batch request
     });
}
Run Code Online (Sandbox Code Playgroud)

将产生

NFO[0001] https://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico?v=4f32ecc8f43d
INFO[0001] https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon.png?v=c78bd457575a
INFO[0001] https://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon.png?v=c78bd457575a
INFO[0001] /opensearch.xml
INFO[0001] https://cdn.sstatic.net/Shared/stacks.css?v=53507c7c6e93
INFO[0001] https://cdn.sstatic.net/Sites/stackoverflow/primary.css?v=d3fa9a72fd53
INFO[0001] https://cdn.sstatic.net/Shared/Product/product.css?v=c9b2e1772562
INFO[0001] /feeds
INFO[0001] https://cdn.sstatic.net/Shared/Channels/channels.css?v=f9809e9ffa90
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,有些网址是相对的而不是绝对的,因此您需要处理这个问题。在这个例子中,只有一些是 css,所以可能需要更多的过滤。这里的问题是您需要编写代码,如果您添加相对链接或其他内容,您需要处理它。幸运的是,k6 是可编写脚本的,因此您可以重用代码:D。


Seb*_*anR 7

我已关注 \xd0\x9c\xd0\xb8\xd1\x85\xd0\xb0\xd0\xb8\xd0\xbb \xd0\xa1\xd1\x82\xd0\xbe\xd0\xb9\xd0\xba\ xd0\xbe\xd0\xb2 建议并编写了我自己的函数来加载资源。您可以设置资源加载方式(使用 批量或顺序获取options.concurrentResourceLoading)。

\n
/**\n * @param {http.RefinedResponse<http.ResponseType>} response\n */\nexport function getResources(response) {\n  const resources = [];\n  response\n    .html()\n    .find(\'*[href]:not(a)\')\n    .each((index, element) => {\n      resources.push(element.attributes().href.value);\n    });\n  response\n    .html()\n    .find(\'*[src]:not(a)\')\n    .each((index, element) => {\n      resources.push(element.attributes().src.value);\n    });\n\n  if (options.concurrentResourceLoading) {\n    const responses = http.batch(\n      resources.map((r) => {\n        return [\'GET\', resolveUrl(r, response.url), null, {\n          headers: createHeader()\n        }];\n      })\n    );\n    responses.forEach(() => {\n      check(response, {\n        \'resource returns status 200\': (r) => r.status === 200,\n      });\n    });\n  } else {\n    resources.forEach((r) => {\n      const res = http.get(resolveUrl(r, response.url), {\n        headers: createHeader(),\n      });\n      !check(res, {\n        \'resource returns status 200\': (r) => r.status === 200,\n      });\n    });\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n