رفتن به محتوای اصلی

A/B Testing

آزمایش‌های پایدار visitor-based، مدیریت Variantها، وضعیت اجرا و Conversion Goal در آلفانا.

A/B Testing در آلفانا برای مقایسه چند نسخه از یک تجربه و بررسی اثر هرکدام بر رفتار واقعی کاربران طراحی شده است.

آزمایش‌ها از مسیر زیر در داشبورد مدیریت می‌شوند:

text
/dashboard/ab-tests

هر Experiment می‌تواند بین ۲ تا ۸ Variant داشته باشد. برای هر Variant یک Weight عددی تعریف می‌شود تا سهم آن از Assignment مشخص باشد. در کنار Variantها، هر آزمایش یک Goal، وضعیت اجرا و تنظیماتی برای نحوه شمارش Conversionها دارد.

هدف این است که به‌جای تصمیم‌گیری بر اساس حدس، بتوانید دو یا چند تجربه را در شرایط کنترل‌شده در اختیار کاربران قرار دهید و نتیجه را بر اساس رفتار ثبت‌شده مقایسه کنید.

## وضعیت آزمایش
id: experiments
مقادیر فعلی `status` برای Experiment عبارت‌اند از:

```text
draft
running
paused

رفتار هر وضعیت:

  • draft برای آزمایشی است که هنوز وارد مرحله اجرا نشده است.
  • running نشان می‌دهد آزمایش فعال است و Visitorها می‌توانند Assignment دریافت کنند.
  • paused اجرای آزمایش را متوقف می‌کند و Assignment فعال جدیدی از مسیر evaluate انجام نمی‌شود.

فقط Experimentهایی که در وضعیت running قرار دارند در جریان Evaluation می‌توانند Variant Assignment برگردانند.

این تفاوت مهم است؛ وجود یک Experiment در Dashboard به‌تنهایی به معنای فعال بودن آن برای کاربران نیست.

Variantها#

هر آزمایش حداقل ۲ و حداکثر ۸ Variant دارد.

برای هر Variant یک weight عددی تعریف می‌شود. Weightها مشخص می‌کنند هر Variant چه سهمی از Assignment کاربران داشته باشد.

برای مثال، یک آزمایش ساده می‌تواند شامل دو Variant باشد:

text
control    50
variant_b  50

یا می‌توانید توزیع متفاوتی تعریف کنید:

text
control    80
variant_b  20

Weight برای کنترل توزیع Assignment استفاده می‌شود و به شما اجازه می‌دهد یک تجربه جدید را ابتدا روی بخش محدودتری از کاربران اجرا کنید.

Assignment پایدار#

Assignment آزمایش در آلفانا بر اساس visitorId پایدار است.

یعنی اگر یک Visitor برای یک Experiment به Variant مشخصی اختصاص داده شود، Evaluationهای بعدی همان آزمایش برای همان visitorId باید همان Assignment را حفظ کنند.

این رفتار کمک می‌کند کاربر در بازدیدهای مختلف بین Variantها جابه‌جا نشود و تجربه آزمایش برای او ثابت بماند.

برای مثال، اگر Visitor زیر:

text
visitorId: visitor_123

در Experiment با key زیر:

text
checkout-test

به Variant:

text
variant_b

اختصاص داده شود، Evaluation بعدی همان Experiment برای همان Visitor بر اساس Assignment پایدار انجام می‌شود.

پایداری Assignment برای تفسیر درست نتیجه آزمایش اهمیت دارد؛ چون تغییر مداوم Variant می‌تواند رفتار کاربر و در نتیجه داده Conversion را مخدوش کند.

Evaluation در SDK#

SDK برای دریافت Assignmentهای A/B Test از endpoint زیر استفاده می‌کند:

text
POST /api/ab-tests/evaluate

این endpoint با App Secret همان App و بررسی دامنه ثبت‌شده App محافظت می‌شود.

بنابراین Evaluation آزمایش‌ها بخشی از جریان Runtime SDK است و از credential مربوط به همان App استفاده می‌کند.

پاسخ Evaluation یک map از Experiment Key به Variant Key است.

برای مثال:

json
{
  "checkout-test": "variant_b",
  "pricing-test": "control"
}

اگر برای یک Experiment در Evaluation فعلی Assignment قابل استفاده‌ای وجود نداشته باشد، مقدار آن می‌تواند null باشد:

json
{
  "checkout-test": null
}

این وضعیت می‌تواند برای آزمایشی رخ دهد که در شرایط فعلی Assignment فعال ارائه نمی‌کند.

تنظیمات Experiment#

هر Experiment علاوه بر Variantها و Goal، چند تنظیم مهم برای نحوه محاسبه نتیجه دارد:

تنظیممقادیر
conversionWindowHoursاز ۱ تا ۷۲۰ ساعت
countByvisitor یا session
deviceFilterall، desktop، mobile یا tablet
Goal Typepage_view یا click

این تنظیمات مشخص می‌کنند چه Conversionهایی در نتیجه آزمایش شمرده شوند و هر Conversion در چه contextی معتبر باشد.

conversionWindowHours#

conversionWindowHours بازه زمانی‌ای را مشخص می‌کند که Conversion بعد از Assignment می‌تواند به همان Experiment نسبت داده شود.

مقدار این تنظیم باید بین:

text
1

تا:

text
720

ساعت باشد.

انتخاب Window مناسب به نوع رفتار مورد انتظار بستگی دارد.

برای مثال، اگر Goal آزمایش رفتاری است که معمولاً چند دقیقه بعد از دیدن Variant اتفاق می‌افتد، Window بسیار طولانی ممکن است context آزمایش را بیش از حد باز کند.

در مقابل، برای Journeyهایی که تصمیم کاربر زمان بیشتری می‌برد، Window کوتاه می‌تواند بخشی از Conversionهای مرتبط را از دست بدهد.

بنابراین این مقدار را متناسب با چرخه واقعی رفتار کاربر انتخاب کنید.

countBy#

تنظیم countBy مشخص می‌کند Conversionها بر چه مبنایی شمرده شوند.

مقادیر پشتیبانی‌شده:

text
visitor
session

اگر مقدار روی visitor باشد، شمارش بر مبنای Visitor انجام می‌شود.

اگر مقدار روی session باشد، Session مبنای شمارش قرار می‌گیرد.

انتخاب بین این دو باید با سؤال اصلی آزمایش هماهنگ باشد.

اگر می‌خواهید بدانید چند کاربر یکتا به Goal رسیده‌اند، visitor معمولاً context مناسب‌تری ایجاد می‌کند.

اگر رفتار موردنظر به Sessionهای مستقل وابسته است، session می‌تواند مبنای مناسب‌تری باشد.

deviceFilter#

با deviceFilter می‌توانید Experiment را بر اساس نوع Device محدود کنید.

مقادیر فعلی:

text
all
desktop
mobile
tablet

مقدار all یعنی آزمایش برای همه Deviceهای پشتیبانی‌شده قابل استفاده است.

مقادیر دیگر اجازه می‌دهند Experiment فقط برای یک دسته مشخص از Device اجرا شود.

این قابلیت زمانی مفید است که تجربه مورد آزمایش فقط در یک Layout یا Device خاص معنا داشته باشد.

برای مثال، اگر تغییر فقط به Navigation موبایل مربوط است، اجرای همان Experiment برای Desktop می‌تواند داده‌ای ایجاد کند که به سؤال اصلی آزمایش ارتباطی ندارد.

Goal آزمایش#

هر Experiment یک Goal دارد که مشخص می‌کند موفقیت آزمایش بر اساس چه رفتار ثبت‌شده‌ای سنجیده شود.

Goal Typeهای فعلی عبارت‌اند از:

text
page_view
click

page_view#

این Goal زمانی مناسب است که رسیدن کاربر به یک صفحه مشخص نشانه Conversion باشد.

برای مثال:

text
/checkout/success

یا:

text
/signup/complete

click#

این نوع Goal زمانی استفاده می‌شود که کلیک روی یک Element یا Interaction مشخص رفتار موردنظر آزمایش باشد.

انتخاب Goal باید مستقیماً با فرضیه Experiment مرتبط باشد. اگر تغییر شما قرار است روی تکمیل خرید اثر بگذارد، Goal بهتر است همان رفتار نهایی را اندازه بگیرد، نه یک Interaction میانی که الزاماً به Conversion منجر نمی‌شود.

Control Variant#

اولین Variant هر Experiment نقش Control را در محاسبه Uplift دارد.

یعنی نتیجه سایر Variantها نسبت به اولین Variant مقایسه می‌شود و Uplift بر اساس تفاوت عملکرد آن‌ها با Control محاسبه می‌شود.

به همین دلیل، ترتیب Variantها فقط یک موضوع ظاهری نیست.

اگر نسخه فعلی محصول قرار است مبنای مقایسه باشد، آن را به‌عنوان اولین Variant تعریف کنید تا Control آزمایش مشخص و قابل‌تفسیر باقی بماند.

برای مثال:

text
1. control
2. new_checkout

در این ساختار، عملکرد new_checkout نسبت به control سنجیده می‌شود.

استفاده از Assignment در SDK#

بعد از دریافت Assignment، SDK snapshot آزمایش‌ها را در اختیار APIهای Tracker قرار می‌دهد.

برای خواندن همه Assignmentها می‌توانید از:

typescript
tracker.getAbVariants();

استفاده کنید.

اگر فقط Variant یک Experiment مشخص را می‌خواهید:

typescript
const variant = tracker.getAbVariant("checkout-test");

اگر Assignment فعالی وجود نداشته باشد، مقدار می‌تواند null باشد.

در React نیز Hookهای اختصاصی برای همین جریان در دسترس‌اند.

استفاده در React#

برای خواندن Variant یک Experiment:

tsx
import { useAbVariant } from "alphana-sdk/react";

function Checkout() {
  const variant = useAbVariant("checkout-test");

  if (variant === "variant_b") {
    return <NewCheckout />;
  }

  return <CurrentCheckout />;
}

اگر فقط می‌خواهید بررسی کنید Visitor در یک Variant مشخص قرار دارد:

tsx
import { useIsAbVariant } from "alphana-sdk/react";

function Checkout() {
  const isNewCheckout = useIsAbVariant("checkout-test", "variant_b");

  return isNewCheckout ? <NewCheckout /> : <CurrentCheckout />;
}

برای دریافت map همه Assignmentهای فعلی نیز useAbTests() در دسترس است.

Refresh کردن Experimentها#

در Tracker می‌توانید Assignmentها را با APIهای مربوط به A/B Test refresh کنید.

برای مثال:

typescript
await tracker.fetchAbTests();

همچنین می‌توانید فقط مجموعه مشخصی از Experiment Keyها را برای refresh در نظر بگیرید:

typescript
await tracker.fetchAbTests(["checkout-test", "pricing-test"]);

در حالت معمول، lifecycle SDK Evaluation اولیه را مدیریت می‌کند و لازم نیست پیش از هر Render یا Interaction درخواست جدیدی ارسال کنید.

دنبال کردن تغییر Assignmentها#

اگر لازم است بخشی از کد هنگام تغییر Assignmentها واکنش نشان دهد، onAbTestsChange() برای subscription به تغییرات در دسترس است.

این API برای integrationهای Vanilla مناسب است.

در React معمولاً Hookهای useAbTests()، useAbVariant() و useIsAbVariant() انتخاب ساده‌تری هستند، چون تغییر snapshot را با lifecycle Render هماهنگ می‌کنند.

طراحی یک Experiment قابل‌تفسیر#

قبل از اجرای Experiment، بهتر است چند چیز روشن باشد:

  • دقیقاً چه تغییری را آزمایش می‌کنید؟
  • Control کدام Variant است؟
  • Goal اصلی چیست؟
  • Conversion در چه بازه زمانی باید شمرده شود؟
  • شمارش باید Visitor-based باشد یا Session-based؟
  • آزمایش برای همه Deviceها معنا دارد یا فقط یک Device؟
  • Weight هر Variant چقدر است؟

هرچه فرضیه و Goal مشخص‌تر باشند، نتیجه Experiment هم راحت‌تر قابل‌تفسیر خواهد بود.

A/B Test فقط زمانی ارزش دارد که تفاوت بین Variantها به یک سؤال واقعی محصول وصل شده باشد.