You need to enable JavaScript to run this app.
导航
A/B测试
最近更新时间:2024.05.17 16:14:00首次发布时间:2023.02.15 19:04:52

A/B 测试是互联网产品中常见的场景,主要是根据特定规则将用户分为测试组和对照组,通过对比两组用户的表现来评估不同策略或设计的效果。利用边缘函数,您可以简单地构建A/B测试环境,同时,也可以利用边缘函数的高并发和分布式优势进行简单的数据统计处理工作。

简单的A/B测试

以下示例展示了如何使用Cookie来决定用户所属的测试组或对照组。如果用户的Cookie中包含了特定信息,就返回相应的组的内容;否则,以50%的概率随机返回测试组或对照组的内容。

function handleRequest(request) {
  const NAME = "experiment-0"

  const TEST_RESPONSE = new Response("Test group")
  const CONTROL_RESPONSE = new Response("Control group")

  const cookie = request.headers.get("cookie")
  if (cookie && cookie.includes(`${NAME}=control`)) {
    return CONTROL_RESPONSE
  }
  else if (cookie && cookie.includes(`${NAME}=test`)) {
    return TEST_RESPONSE
  }
  else {
    const group = Math.random() < 0.5 ? "test" : "control" // 50/50 split
    const response = group === "control" ? CONTROL_RESPONSE : TEST_RESPONSE
    response.headers.append("Set-Cookie", `${NAME}=${group}; path=/`)

    return response
  }
}

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request))
})

信息验证和错误统计

您也可以利用边缘函数对测试组的页面做信息验证或错误统计。通常,测试部署的软件可能存在工程BUG等异常,您可以利用边缘函数做一些简单的数据分析。
以下展示了如何利用边缘函数对测试组的页面进行信息验证和错误统计。该示例统计了测试组的不同HTTP状态码(2xx、3xx、4xx、5xx)的分布情况,并定期将统计数据发送到指定的服务器进行进一步分析。同时,该示例还展示了如何根据概率对特定URL进行A/B测试,并记录请求的状态码。

let ttTestRequests = 0;
let tt2xx = 0;
let tt3xx = 0;
let tt4xx = 0;
let tt5xx = 0;
let ttOtherStatusCode = 0;

const uploadURL = 'http://www.example.com/analytic';
async function uploadStatus(e) {
  const obj = new Object();

  obj['totalRequests'] = ttTestRequests;
  obj['2xx'] = tt2xx;
  obj['3xx'] = tt3xx;
  obj['4xx'] = tt4xx;
  obj['5xx'] = tt5xx;
  obj['others'] = ttOtherStatusCode;

  await fetch(uploadURL, {method: 'POST', body: JSON.stringify(obj)});
}

// 每隔5秒钟,边缘函数将会把收集到的状态码分布信息发送到指定服务器进行进一步分析。
addEventListener('@timer(5)', uploadStatus);

//  对 testURL 根据概率进行A/B测试
function recordStatusCode(status_code) {
  ++ttTestRequests;
  if (status_code >= 200 && status_code < 300) {
    ++tt2xx;
  } else if (status_code >= 300 && status_code < 400) {
    ++tt3xx;
  } else if (status_code >= 400 && status_code < 499) {
    ++tt4xx;
  } else if (status_code >= 500 && status_code < 599) {
    ++tt5xx;
  } else {
    ++ttOtherStatusCode;
  }
}

const probability = 0.2;

const testURL = 'http://www.example.com/test';

async function handle(event) {
  // 根据概率进行测试
  if (Math.random() < probability) {

    // 对该 url 进行请求
    const r = await fetch(testURL);

    // 将请求状态码进行收集
    recordStatusCode(r.status);

    return r;
  } else {
    return fetch(event.request);
  }
}

addEventListener("fetch", event => {
  event.respondWith(handle(event))
})