Playwright یک فریمورک قابلاعتماد برای تست end-to-end اپهای وب مدرن است. با آن میتوانید اسکریپتهای تست پایدار بنویسید که روی چند مرورگر اجرا میشوند. ابزارهای قدرتمند Playwright هم نوشتن و debug کردن تستها را سادهتر میکنند.
در این آموزش بررسی میکنیم چطور نتایج تستی را که از یک test run خودکار Playwright تولید میشوند، با استفاده از TestRail CLI در TestRail وارد کنید. با این کار میتوانید نتایج تستهای خودکار را در یک نقطه متمرکز کنید و از همه قابلیتهای تحلیل و گزارشدهی TestRail استفاده کنید.
نمای کلی #
در این آموزش، از یک project نمونه استفاده میکنیم تا مراحل راهاندازی یک project تست خودکار Playwright سازگار با TestRail CLI و آپلود نتایج تست تولیدشده را دنبال کنید.
پس از خواندن این آموزش، میتوانید:
- تستها را از یک project ساده Playwright اجرا کنید
- TestRail CLI را نصب کنید
- instance TestRail خود را پیکربندی کنید
- CLI را اجرا کنید
- test caseها و نتایج تست خود را در TestRail ببینید
پیشنیازها #
برای اجرای یک project تست Playwright، میتوانید Playwright را از طریق npm یا هر یک از روشهای دیگر معرفیشده در مستندات نصب Playwright نصب کنید، اما در این مقاله آن را از طریق npm نصب میکنیم. برای نصب Playwright با npm، تنها پیشنیاز نصب Node.js است.
برای نصب و اجرای TestRail CLI که برای وارد کردن نتایج تست به TestRail استفاده میشود، به Python هم نیاز دارید.
| پیشنیاز | توضیحات |
|---|---|
| Node.js | نسخه مناسب سیستمعامل خود را دانلود کنید و دستورالعملهای نصب را دنبال کنید. برای مطمئن شدن از موفقیتآمیز بودن نصب، دستورهای node --version و npm --version را در command line اجرا کنید؛ باید نسخه نصبشده نمایش داده شود. |
| Python 3.10.4 | نسخه مناسب سیستمعامل خود را دانلود کنید و دستورالعملهای نصب را دنبال کنید.
برای مطمئن شدن از موفقیتآمیز بودن نصب، دستورهای |
نصب project نمونه #
بیایید با دریافت کد project نمونه و نصب dependencyهای لازم شروع کنیم.
- این مورد را clone یا دانلود کنید: project نمونه
- command prompt را در پوشه root پروژه باز کنید و دستور زیر را اجرا کنید.
$ npm install
فایل packages.json شامل کتابخانههایی است که میخواهیم برای این project نصب کنیم. در این مورد، تنها dependency مستقیم Playwright است که خودش به کتابخانههای دیگری وابسته است.
| نیازمندی | توضیحات |
|---|---|
| @playwright/test | فریمورک اتوماسیون تست با قابلیتهای اتوماسیون وب |
بررسی پروژه نمونه #
پروژه نمونه را با IDE دلخواهتان باز کنید و فایلهای test را بررسی کنید. کد testهای خودکار را ساده نگه داشتهایم تا تمرکز این آموزش روی نحوه import کردن نتایج اجرا بماند. این testها شامل چند تعامل ساده با یک وباپلیکیشن TO DO list هستند که توسط Playwright میزبانی میشود.
// @ts-check
const { test, expect } = require('@playwright/test');
const { randomUUID } = require('crypto');
test.beforeEach(async ({ page }) => {
await page.goto('https://demo.playwright.dev/todomvc');
});
test.afterEach(async ({ page }, testInfo) => {
if (testInfo.status !== testInfo.expectedStatus) {
let screenshotPath = `test-results/screenshots/screenshot-${randomUUID()}.png`;
await page.screenshot({ path: screenshotPath, fullPage: true });
testInfo.annotations.push({ type: 'testrail_attachment', description: screenshotPath });
}
});
const TODO_ITEMS = [
'buy some cheese',
'feed the cat',
'book a doctors appointment'
];
test.describe('New Todo', () => {
test('should allow me to add todo items', async ({ page }) => {
// Create 1st todo.
await page.locator('.new-todo').fill(TODO_ITEMS[0]);
await page.locator('.new-todo').press('Enter');
// Make sure the list only has one todo item.
await expect(page.locator('.view label')).toHaveText([
TODO_ITEMS[0]
]);
// Create 2nd todo.
await page.locator('.new-todo').fill(TODO_ITEMS[1]);
await page.locator('.new-todo').press('Enter');
// Make sure the list now has two todo items.
await expect(page.locator('.view label')).toHaveText([
TODO_ITEMS[0],
TODO_ITEMS[1]
]);
await checkNumberOfTodosInLocalStorage(page, 2);
});
});
پیوست کردن screenshotها به report #
برای اینکه بتوانید screenshotهای testهای ناموفق را بهسادگی بگیرید و به TestRail ارسال کنید، میتوانید از propertyهای سفارشی JUnit reporter استفاده کنید. برای این کار، فقط کافی است testRailOptions را طبق کد زیر به فایل config مربوط به Playwright اضافه کنید.
// @ts-check
const { devices } = require('@playwright/test');
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
const testRailOptions = {
// Whether to add <properties> with all annotations; default is false
embedAnnotationsAsProperties: true,
// Where to put the report.
outputFile: './test-results/junit-report.xml'
};
/**
* @see https://playwright.dev/docs/test-configuration
* @type {import('@playwright/test').PlaywrightTestConfig}
*/
const config = {
/* (...) */
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [
['list'],
['html', { outputFolder: 'test-results', open: 'never' }],
['junit', testRailOptions]
],
/* (...) */
};
module.exports = config;
بعد از اینکه JUnit reporter را درست پیکربندی کردید، فقط باید logic گرفتن screenshot را برای زمانی اضافه کنید که نتیجه test مطابق انتظار نیست، و path مربوط به screenshot را به یک testrail_attachment property اضافه کنید. این کار را میتوانید با کد زیر انجام دهید؛ همین کد در test code snippet بالا هم وجود داشت.
test.afterEach(async ({ page }, testInfo) => {
if (testInfo.status !== testInfo.expectedStatus) {
let screenshotPath = `test-results/screenshots/screenshot-${randomUUID()}.png`;
await page.screenshot({ path: screenshotPath, fullPage: true });
testInfo.annotations.push({ type: 'testrail_attachment', description: screenshotPath });
}
});
اجرای پروژه نمونه #
در همان command prompt، دستور زیر را اجرا کنید تا testهای Playwright در پروژه اجرا شوند و نتایج در فرمت JUnit XML ذخیره شود.
$ npx playwright test
اگر دستور Playwright درست اجرا شده باشد، باید بتوانید نتایج testها را در پوشه test-results ببینید. پروژه Playwright طوری پیکربندی شده است که دو فایل report تولید کند. با باز کردن فایل index.html میتوانید یک report تعاملی HTML مربوط به Playwright، مشابه نمونه زیر، ببینید.

همچنین باید فایلی به نام junit-report.xml ، مطابق گزینههای دستور robot، وجود داشته باشد که نتایج testها را در فرمت JUnit XML دارد. این همان فایلی است که TestRail CLI در مرحله بعد آن را parse میکند تا test run را ایجاد کند و نتایج test شما را در TestRail آپلود کند.
<testsuites id="" name="" tests="5" failures="1" skipped="0" errors="0" time="11.882232000008225">
<testsuite name="demo-todo-app.spec.js" timestamp="1664397866418" hostname="" tests="5" failures="1" skipped="0" time="15.464" errors="0">
<testcase name="New Todo should allow me to add todo items" classname="demo-todo-app.spec.js › New Todo › should allow me to add todo items" time="2.369">
</testcase>
<testcase name="New Todo should clear text input field when an item is added" classname="demo-todo-app.spec.js › New Todo › should clear text input field when an item is added" time="1.906">
</testcase>
<testcase name="New Todo should append new items to the bottom of the list" classname="demo-todo-app.spec.js › New Todo › should append new items to the bottom of the list" time="2.634">
</testcase>
<testcase name="Mark all as completed should allow me to mark all items as completed" classname="demo-todo-app.spec.js › Mark all as completed › should allow me to mark all items as completed" time="7.32">
<properties>
<property name="testrail_attachment" value="test-results/screenshots/screenshot-f6f2df78-0eaa-487c-a7a3-97ec6bb66a9a.png">
</property>
</properties>
<failure message="demo-todo-app.spec.js:73:3 should allow me to mark all items as completed" type="FAILURE">
<![CDATA[ demo-todo-app.spec.js:73:3 › Mark all as completed › should allow me to mark all items as completed
Error: expect(received).toHaveClass(expected) // deep equality
- Expected - 3
+ Received + 3
Array [
- "complete",
- "complete",
- "complete",
+ "completed",
+ "completed",
+ "completed",
]
Call log:
- expect.toHaveClass with timeout 5000ms
- waiting for selector ".todo-list li"
- selector resolved to 3 elements
76 |
77 | // Ensure all todos have 'completed' class.
> 78 | await expect(page.locator('.todo-list li')).toHaveClass(['complete', 'complete', 'complete']);
| ^
79 | await checkNumberOfCompletedTodosInLocalStorage(page, 3);
80 | });
81 |
at C:\Github\d-rede\playwright-tests-new\tests\demo-todo-app.spec.js:78:49
]]>
</failure>
</testcase>
<testcase name="Mark all as completed should allow me to clear the complete state of all items" classname="demo-todo-app.spec.js › Mark all as completed › should allow me to clear the complete state of all items" time="1.235">
</testcase>
</testsuite>
</testsuites>
وارد کردن نتایج به TestRail #
پس از اجرای testها و تولید فایلهای JUnit report، میتوانید نتایج test خود و test caseها را بهراحتی به TestRail وارد کنید. این کار باعث میشود automated test runهای شما در TestRail قابل مشاهده باشند و بتوانید تصویر کلیتری از نحوه تست کردن اپلیکیشن خود در TestRail ببینید.
نصب TestRail CLI #
اگر Python از قبل روی دستگاه شما نصب است، نصب TestRail CLI بهسادگی با اجرای دستور زیر در command line انجام میشود.
$ pip install trcli
پیکربندی TestRail #
در مرحله بعد، باید محیط TestRail خود را طبق دستورالعملهای زیر پیکربندی کنید.
- قابلیت TestRail API را فعال کنید: به مسیر Admin > Site Settings بروید، روی تب API کلیک کنید و گزینه Enable API را تیک بزنید.
- یک Custom Field بسازید تا کد test caseهای خودکار شما به caseهای واقعی TestRail map شود. برای این کار به مسیر Admin > Customizations بروید و روی افزودن فیلد. بعد از اینکه به صفحه ایجاد فیلد رسیدید، این custom field باید دو شرط زیر را داشته باشد:
- مقدار System Name باید برابر با automation_id
- مقدار Type باید برابر با Text
ارسال نتایج به TestRail #
بعد از نصب TestRail CLI و تکمیل تنظیمات TestRail instance خود، میتوانید نتایج test را بهسادگی با یک دستور یکخطی مانند نمونه زیر آپلود کنید.
$ trcli -y \
> -h https://INSERT-INSTANCE-NAME.testrail.io \
> --project "My Project" \
> --username INSERT-EMAIL \
> --password INSERT-PASSWORD \
> parse_junit \
> --title "Playwright Automated Test Run" \
> -f "./test-results/junit-report.xml"
توجه داشته باشید که نام فایل بعد از گزینه -f اگر محل پیشفرض report file را تغییر دادهاید، باید با مسیر همان فایل مطابقت داشته باشد. همه گزینههای دیگر هم باید متناسب با TestRail instance و project شما تنظیم شوند. برای دیدن سایر گزینههای command line میتوانید به TestRail CLI README.md در repository پروژه، مقاله مستندات TRCLI، یا راهنمای داخلی CLI از طریق دستورهای زیر مراجعه کنید.
$ trcli --help
$ trcli parse_junit --help
نمایش نتایج در TestRail #
حالا اگر در project خود در TestRail به صفحه Test Cases بروید، میبینید که TestRail CLI بهطور خودکار test caseهایی را که در گزارش نتایج test شما وجود داشتند ایجاد کرده است. توجه کنید که با ترکیب classname و name attributeهای هر test در گزارش JUnit، یک Automation ID یکتا اضافه شده است. این Automation ID برای نگاشت testهای موجود در codebase اتوماسیون شما به test caseهای TestRail استفاده میشود. یعنی هر بار که TestRail CLI را اجرا میکنید، ابتدا تلاش میکند یک test case موجود در TestRail را پیدا و match کند و فقط وقتی test caseای با آن Automation ID وجود نداشته باشد، مورد جدیدی ایجاد میکند.
#
اگر نام testها، نام فایل یا محل آن را تغییر دهید، Automation ID آن testها هم تغییر میکند و دیگر به test caseهای موجود در TestRail نگاشت نمیشوند.

در صفحه Test Runs & Results میتوانیم ببینیم که یک test run با نام Playwright Automated Test Run ایجاد شده است. با باز کردن آن میتوانیم جزئیات نتیجه هر automated test را دقیقتر بررسی کنیم و در سطح کلی تحلیل کنیم که چرا یک test شکست خورده است؛ چون پیام خطایی که test automation framework ارائه کرده نیز همراه با نتیجه test ثبت میشود. همچنین هر attachment، مثل screenshot مربوط به زمان شکست test، همانطور که در تصویر زیر میبینید، در دسترس است.

قدم بعدی چیست؟ #
حالا که نتایج test خود را در TestRail متمرکز کردهاید، علاوه بر بررسی نتایج test runهای خودکار و پیام خطای testهای ناموفق، میتوانید فعالیتهای تست دستی و خودکار را در گزارشهایی تجمیع کنید که test coverage کامل برنامه شما را نشان میدهند و حتی پیشرفت test automation را دنبال میکنند. همچنین میتوانید مثل نتایج تست دستی، یک bug را مستقیماً از نتیجه automated test به issue tracker دلخواه خود گزارش کنید.
برای آشنایی بیشتر میتوانید ویدئوی TestRail’s Reports and Test Metrics را ببینید و یاد بگیرید چطور از قابلیتهای گزارشدهی TestRail استفاده کنید.

