برنامه نویسی

درام تست: Cypress vs Playwright – تست های خود را کنترل کنید (قسمت 1): حاشیه نویسی و تست های گروهی

بررسی حاشیه نویسی ها و آزمایش های گروهی در نمایشنامه نویس Cypress vs: رونمایی از مکانیسم های کنترل در چارچوب های آزمایش.

(تصویر پوشش از Pexels.com توسط استودیوی Cottonbro)



زمان آن زمان برای مقاله دوم “درام تست: Cypress vs Playwright“سریال ، و من فکر کردم که باید چیزی را پوشش دهد که واقعاً می تواند به شما در سازماندهی تست های خود کمک کند و کنترل کاملی بر اجرای خود داشته باشید.

در مورد این حرفهای زیادی برای گفتن وجود دارد ، و بسیاری از ویژگی های مختلف پشتیبانی شده توسط Cypress و Playwright می توانند در این کار به شما کمک کنند. بنابراین ، من فکر کردم که این موضوع برای مقاله ای در این مجموعه موضوع خوبی خواهد بود.

البته ، من در مورد آن صحبت می کنم حاشیه هابا تست های گروهیبا برچسب هاوت فیلترهای آزمون – کاوش نه تنها یک چارچوب تست بلکه دو مورد ، با سرو و نمایشنامه نویس در کنار هم (یا نمایشنامه نویس و سرو در صورت ترجیح)) ، توانایی ها و محدودیت های کامل آنها را نشان می دهد.

در طی کاوش کامل من در مورد این موضوع خاص در سرو و نمایشنامه نویس ، دریافتم که این اطلاعات کاملاً گسترده است. برای کنترل و پیروی از آن آسان تر ، من محتوا را در دو بخش سازماندهی کردم.

  • تست های خود را کنترل کنید (قسمت 1): حاشیه نویسی و تست های گروهی (این مقاله)
  • تست های خود را کنترل کنید (قسمت 2): برچسب ها و فیلترهای تست (به زودی)

من به شدت توصیه می کنم این مقاله اول را به طور کامل و قسمت دوم پس از انتشار آن بخوانید. این به شما کمک می کند تا ویژگی ها را در عمق عالی درک کنید و به شما این امکان را می دهد تا تشخیص دهید که چه کاری می توانید و نمی توانید انجام دهید و مشخص کنید که چه چیزی مناسب نیازهای شما است.


بیایید هر یک از این ابزارها را تشخیص دهیم تا درک کنیم که چگونه می توانند کنترل کاملی را بر چارچوب تست خود ، اعم از این که سرو می شود و چه نمایشنامه‌نویس ، به ما ارائه دهند.

📝 حاشیه نویسی

حاشیه نویسی ها نشانگرهای ویژه یا دستورالعمل هایی هستند که در اسکریپت های آزمون برای تأثیرگذاری بر اجرای آزمون استفاده می شوند. آنها دستورالعمل های اضافی یا ابرداده ای را در چارچوب آزمایش در مورد نحوه انجام آزمایشات خاص یا موارد آزمایش ارائه می دهند. از حاشیه نویسی ها می توان برای پرش از تست ها ، تمرکز روی تست های خاص و انجام سایر کارکردها استفاده کرد.

حاشیه نویسی

طبق مستندات رسمی ، “Cypress نحوی BDD (توسعه رفتار محور) Mocha را اتخاذ کرده است ، که کاملاً با یکپارچه سازی و آزمایش واحد متناسب است

این بدان معنی است که حاشیه نویسی های مورد استفاده برای کنترل اعدام های آزمون مواردی است که توسط Mocha ارائه شده است: .only وت .skipبشر

it.only ()

حاشیه نویسی .only به شما امکان می دهد تا در یک فایل مشخصه روی تست های خاص یا سوئیت ها (تست های گروهی) تمرکز کنید. برای اجرای یک آزمایش خاص در Cypress ، شما به سادگی ضمیمه می کنید .only به it عملکرد. شما می توانید به همان اندازه استفاده کنید .only حاشیه نویسی در یک فایل مشخصه همانطور که می خواهید.

// test-only.cy.js

// This will only execute the second test titled 'Age should be 52',
// which it will pass.

const theName = 'Caine'
const theAge = 52

it('Name should be John Wick', () => {
    expect(theName).to.be.equal('John Wick')
})

it.only('Age should be 52', () => {
    expect(theAge).to.be.equal(52)
})
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در ترمینال ، به نظر می رسد که فقط یک آزمایش واحد وجود دارد. کی .only در یک فایل مشخصه استفاده می شود ، تمام آزمایشات دیگر کاملاً نادیده گرفته می شوند ، گویی که در طول اجرا در آن پرونده وجود ندارند:

شرح تصویر

اطلاعات مشابه در ورود به سیستم Cypress از دونده ظاهر می شود و فقط یک آزمایش واحد را در پرونده مشخصات نشان می دهد:

شرح تصویر

it.skip ()

در .skip حاشیه نویسی در سرو برای پرش از آزمایشات خاص یا سوئیت ها در حین اجرای استفاده می شود. این عملکرد در هنگام توسعه یک آزمایش مفید است ، که به دلایلی که مورد بررسی قرار می گیرد ، یا برای تلاش های آزمایش فعلی شما مهم نیست ، شناخته می شود.

// test-skip.cy.js

// The first test titled 'Name should be John Wick' will fail (incorrect name).
// The second test titled 'Age should be 52' will be skipped.

const theName = 'Caine'
const theAge = 52

it('Name should be John Wick', () => {
    expect(theName).to.be.equal('John Wick')
})

it.skip('Age should be 52', () => {
    expect(theAge).to.be.equal(52)
})
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در ترمینال نشان می دهد که یک تست است درنده (از آن رد شد) و یکی شکست خورده است:

شرح تصویر

همان نتیجه در گزارش Cypress نمایش داده می شود:

شرح تصویر

در xit() عملکرد به عنوان یک نام مستعار به it.skip()، ارائه یک روش جایگزین برای اجرای همان عملکرد:

// These two tests are exactly equivalent, and both will be skipped
it.skip('Age should be 52 - Option 1', () => {
    expect(theAge).to.be.equal(52)
})
xit('Age should be 52 - Option 2', () => {
    expect(theAge).to.be.equal(52)
})

راه حل حاشیه نویسی مشروط

سرو به طور بومی پشتیبانی نمی کند حاشیه نویسی مشروطبشر اینها در نمایشنامه نویس معرفی می شوند و برای کنترل اجرای تست ها بر اساس شرایط مشخص استفاده می شوند.

اگر می خواهید در Cypress به این هدف برسید ، با ایجاد اجرای مشروط آزمایشات بر اساس آن شرایط ، باید از راه حل استفاده کنید.

  • می توانید شرط کنترل اجرای را در خارج از آزمون قرار دهید:
// test-cond-ann-workaround-exterior.cy.js

// Ignore the test with title 'Name should be John Wick' if
// the 'runNameTest' environment variable is not set or is false.

const theName = 'Caine'
const theAge = 52

if (Cypress.env('runNameTest')) {
    it('Name should be John Wick', () => {
        expect(theName).to.be.equal('John Wick')
    })
}

it('Age should be 52', () => {
    expect(theAge).to.be.equal(52)
})
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در این حالت ، آزمون ظاهر نمی شود در ترمینال یا گزارش سرو. نکته منفی این رویکرد این است که هنگام مشاهده نتایج آزمون ، شما نمی دانید که این آزمایش در پرونده مشخصات وجود دارد و به دلیل عدم تحقق شرایط ، از بین رفته است.

شرح تصویر

  • از طرف دیگر ، می توانید شرط کنترل اجرای را در آزمون قرار دهید:
// test-cond-ann-workaround-interior.cy.js

// Do not execute the logic of the test 'Name should be John Wick' if
// the 'runNameTest' environment variable is not set or is false.

const theName = 'Caine'
const theAge = 52

it('Name should be John Wick', () => {
    if (!Cypress.env('runNameTest')) {
        return
    }
    expect(theName).to.be.equal('John Wick')
})

it('Age should be 52', () => {
    expect(theAge).to.be.equal(52)
})
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در این سناریو ، منطق موجود در آزمون دور خواهد شد ، اما آزمون همانطور که گذشت نشان می دهد در ترمینال و گزارش سرو. این می تواند گمراه کننده باشد ، زیرا باعث می شود آزمون به نظر برسد که به طور کامل اجرا شده و به تصویب رسیده است ، به جای اینکه نشان دهد منطق آزمون از آن دور می شود. برای جلوگیری از سردرگمی ، ممکن است لازم باشد اطلاعات اضافی را وارد کنید تا به کاربر در مورد آنچه در واقع رخ داده است اطلاع دهید.

شرح تصویر

افزونه Cypress-Pect برای بررسی نتایج آزمایش (توسط Gleb Bahmutov)

Cypress شامل حاشیه نویسی داخلی برای بررسی عدم موفقیت یک تست نیست ، ویژگی ای که در نمایشنامه نویس موجود است. من نتوانستم افزونه Cypress را پیدا کنم که راه حل این ویژگی را شبیه سازی یا فراهم می کند.

✨ اگر از یکی می دانید ، لطفاً به من اطلاع دهید ، زیرا این می تواند واقعاً مفید باشد – به ویژه هنگامی که تست هایی را شامل می شوید که شکست های خاصی را تأیید می کند ، انتظار دارید که آنها شکست بخورند. ✨

به تازگی ، من به افزونه Gleb Bahmutov-Expect-Expect رسیدم. با استفاده از این افزونه ، هنگامی که تست های خود را در ترمینال اجرا می کنید ، می توانید از بین گزینه های دیگر چند تست را که انتظار دارید شکست ، عبور یا پرش کنید ، مشخص کنید.

افزونه Cypress-pect را به عنوان وابستگی به توسعه نصب کنید:

npm i -D cypress-expect
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

سپس تست ها را در ترمینال به شرح زیر اجرا کنید:

npx cypress-expect run --failing  --passing  --pending 

...

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

از حالت تمام صفحه خارج شوید

بیایید یک مثال را در نظر بگیریم. با استفاده از چارچوب سرو ، هنگام اجرای تست در ترمینال ، نتایج زیر به دست آمد:

شرح تصویر

از نتایج ، 11 تست گذشت ، 1 شکست خورده و 2 مورد از بین رفته اند (به عنوان در انتظار) مشخص شده اند.

با اجرای دستور Cypress-Pect با همین اعداد مورد انتظار ، نتیجه مشابهی حاصل می شود:

npx cypress-expect run --passing 11 --failing 1 --pending 2
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

شرح تصویر

اما چه اتفاقی می افتد اگر این شماره ها را مخلوط کنیم و ادعا کنیم که انتظار داریم 7 تست را پشت سر بگذاریم ، 3 شکست و 5 نفر در انتظار باشند؟ واضح است که هیچ یک از این اعداد با نتایج واقعی مطابقت ندارند:

npx cypress-expect run --passing 7 --failing 3 --pending 5
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

شرح تصویر

توجه کنید که در زیر جدول نتایج ، پیامی وجود دارد که بیان شده است ERROR: expected 3 failing tests, got 1بشر

جالب اینجاست که حتی اگر اعداد برای گذراندن و آزمایش های در انتظار شرایط مورد انتظار را برآورده نمی کند ، پیام نمایش داده شده توسط افزونه Cypress-Extect فقط موارد ناکامی را برجسته می کند.

من آزمایش های اضافی را با ترکیب های مختلف عبور ، عدم موفقیت و آزمایش های در انتظار ، صحیح و نادرست انجام دادم و دریافتم که این افزونه فقط به دنبال این ترتیب اولویت ، یک عدم تطابق را در یک زمان گزارش می دهد: عدم موفقیت → عبور → در انتظار

با توجه به مستندات افزونه: “هنگام کار در حالت موازی که در آن تست ها تقسیم می شوند ، این ماژول کار نمی کند ، زیرا فقط یک زیر مجموعه از مشخصات در دستگاه فعلی اجرا می شود

من همچنین مشخص نیستم که آیا این افزونه هنگام اجرای تست ها و ثبت نام در Cypress Cloud به درستی عمل خواهد کرد.

اگر بتواند همه مسائل را به طور همزمان گزارش دهد ، این افزونه جالب و بالقوه کاملاً مفید است. علاوه بر این ، اگر بتواند آزمایشات ناکام را به طور مؤثر رهگیری کند ، از عدم موفقیت آنها در محلی یا خط لوله CI جلوگیری می کند.

حاشیه نویسی نمایشنامه نویس

نمایشنامه نویس یک رویکرد کمی متفاوت برای حاشیه نویسی دنبال می کند. آنها شامل پنج نوع اصلی حاشیه نویسی با توجه به مستندات رسمی آنها هستند: .onlyبا .skipبا ,fixmeبا .fail وت ,slowبشر

test.only ()

نمایشنامه نویس .only حاشیه نویسی به همان روشی که همتای سرو آن کار می کند ، کار می کند. .onlyبشر این امکان را به شما می دهد تا بر روی تست های خاص خاص تمرکز کنید. برای اجرای یک تست خاص در نمایشنامه نویس ، به سادگی اضافه کنید .only به test عملکرد.

import { test, expect } from '@playwright/test';

// test-only.spec.ts

// This will only execute the second test titled 'Age should be 52',
// and it will pass.

const theName = 'Caine'
const theAge = 52

test('Name should be John Wick', async ({ page }) => {
    expect(theName).toEqual('John Wick');
});

test.only('Age should be 52', async ({ page }) => {
    expect(theAge).toEqual(52);
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در ترمینال ، این نشان می دهد که سه آزمایش را پشت سر گذاشته و تمام 3 را پشت سر گذاشته است. این نشان می دهد که آزمایش با عنوان “سن باید 52” در 3 مرورگر پیش فرض (کروم ، فایرفاکس و WebKit) اجرا شود:

شرح تصویر

همین اطلاعات در گزارش پیش فرض HTML نیز ظاهر می شود:

شرح تصویر

test.skip ()

در .skip عملکرد حاشیه نویسی به طور یکسان با همتای سرو آن. این امکان را برای پرش از تست ها یا سوئیت های خاص فراهم می کند ، و آزمایشی را که در حال حاضر ناقص است یا مرتبط نیست ، غیرفعال می کند.

import { test, expect } from '@playwright/test';

// test-skip.spec.ts

// The first test titled 'Name should be John Wick' will fail (incorrect name).
// The second test titled 'Age should be 52' will be skipped.

const theName = 'Caine'
const theAge = 52

test('Name should be John Wick', async ({ page }) => {
    expect(theName).toEqual('John Wick');
});

test.skip('Age should be 52', async ({ page }) => {
    expect(theAge).toEqual(52);
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در ترمینال ، این نشان می دهد که سه تست رد شده است (مربوط به “سن باید 52” باشد) ، و سه آزمایش شکست خورده است (“نام باید جان ویک باشد”) در سه مرورگر.

شرح تصویر

من معتقدم که خروجی در ترمینال وقتی خطاهای نمایشنامه نویس وجود دارد کاملاً “است”زشت“(یا اگر ترجیح می دهید خیلی تمیز نیست). اما این در مقاله دیگری مورد بحث قرار خواهد گرفت.

نتیجه در گزارش HTML یا اجرای نتیجه مشابهی را نشان می دهد:

شرح تصویر

با کلیک بر روی تست ها دقیقاً می توانید آزمایشات را رد کنید پر از برگه در گزارش HTML:

شرح تصویر

test.fixme ()

در نمایشنامه نویس ، .fixme از حاشیه نویسی برای علامت گذاری آزمایشی که در حال شکست است استفاده می شود و نباید در طول آزمایش انجام شود. این حاشیه نویسی در سرو وجود ندارد.

import { test, expect } from '@playwright/test';

// test-fixme.spec.ts

// The first test titled 'Name should be John Wick' will fail (incorrect name).
// The second test titled 'Age should be 52' will be skipped as is marked as fixme.

const theName = 'Caine'
const theAge = 52

test('Name should be John Wick', async ({ page }) => {
    expect(theName).toEqual('John Wick');
});

test.fixme('Age should be 52', async ({ page }) => {
    expect(theAge).toEqual(52);
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در اصل ، .fixme حاشیه نویسی همان تأثیر را در آزمایش دارد .skip حاشیه نویسی (با نادیده گرفتن آزمون).

اگر آن را باور ندارید 😄 ، نتایج موجود در ترمینال را ببینید:

شرح تصویر

و در گزارش پیش فرض HTML:

شرح تصویر

هر آنچه را که می خواهید با آن انجام دهید .fixme همچنین می تواند با .skipبشر تنها مزیت استفاده از .fixme حاشیه نویسی معنایی و برای اهداف مستندات است ، زیرا نشان می دهد که این آزمایش به دلیل خرابی غیرفعال است و نیاز به رفع دارد ، در حالی که .skip خاص نیست

test.fail ()

در .fail حاشیه نویسی برای علامت گذاری تست هایی که انتظار می رود شکست بخورند استفاده می شود. هنگامی که نمایشنامه نویس تست را اجرا می کند ، تأیید می کند که تست در واقع شکست می خورد. اگر این تست انجام نشود ، نمایشنامه نویس به شما اطلاع می دهد.

اگر این تست ها را اجرا کنیم:

import { test, expect } from '@playwright/test';

// test-fail.spec.ts

// The first test will pass because the name is what expected.
// The second test also will pass because although the age is incorrect,
// the test is marked as expected to fail.

const theName = 'John Wick'
const theAge = 52

test('Name should be John Wick', async ({ page }) => {
    expect(theName).toEqual('John Wick');
});

test.fail('Age should be 25 - test pass although assertion fails', async ({ page }) => {
    expect(theAge).toEqual(25);
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

تمام تست ها می گذرد زیرا در آزمون اول ، ادعا راضی است. در آزمون دوم ، جایی که ادعا در حال شکست است ، واقعاً انتظار می رود که شکست بخورد.

این همان چیزی است که ترمینال را نشان می دهد:

شرح تصویر

و گزارش پیش فرض HTML:

شرح تصویر

این .fail حاشیه نویسی در سرو وجود ندارد ، اما من می گویم که می دانم واقعاً مفید است. 👨‍🔧

و چرا این است؟

اگر واقعاً می خواهید بدانید ، باید صبور باشید و صبر کنید تا نتیجه گیری های خود را در پایان مقاله ، به خصوص علاقه مندان به هموطنان سرو ، بیان کنم. 😉

test.fail.only ()

این .fail.only حاشیه نویسی بسیار جالب است … این ترکیبی از دو حاشیه نویسی است .fail وت .only و از آن برای تمرکز روی یک آزمایش خاص که انتظار می رود شکست بخورد ، استفاده می شود ، که هنگام اشکال زدایی در یک آزمایش ناکام مفید است.

import { test, expect } from '@playwright/test';

// test-failonly.spec.ts

// The first test will pass because the name is what expected.
// The second test also will pass because although the age is incorrect,
// the test is marked as expected to fail.

const theName = 'John Wick'
const theAge = 52

test('Name should be John Wick', async ({ page }) => {
    expect(theName).toEqual('John Wick');
});

test.fail.only('Age should be 25 - test pass although assertion fails', async ({ page }) => {
    expect(theAge).toEqual(25);
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

توجه کنید که در این حالت ، فقط آزمایش دوم با عنوان “سن باید 25 باشد – هرچند ادعا شکست می خورد'اعدام شده است. اگرچه این ادعا با شکست مواجه می شود ، این آزمایش از آنجا که انتظار می رود شکست بخورد ، می گذرد.

شرح تصویر

test.slow ()

حاشیه نویسی .slow برای نشان دادن آزمایشی که انتظار می رود کند باشد ، استفاده می شود و زمان آن را سه برابر می کند. این حاشیه نویسی دیگری است که توسط موکا پشتیبانی نمی شود ، و در نتیجه ، نه توسط سرو.

import { test, expect } from '@playwright/test';

// test-slow.spec.ts

// The test is expected to be slow, so we triple its timeout.

test('Test for a very slow page', async ({ page }) => {
    await page.goto('https://www.slowpage.com');
    await expect(page).toHaveTitle('Welcome to the slow page');
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

برای من ، این حاشیه نویسی .slow خوب است ، و من می فهمم که چرا بسیار راحت است. با این حال ، من به خصوص به آن علاقه ندارم. دلایل خود را بعداً در بخش وضوح توضیح خواهم داد

حاشیه نویسی مشروط

در نمایشنامه نویس ، حاشیه نویسی های داخلی را می توان به صورت مشروط اعمال کرد ، به این معنی که در صورت صحت این شرط ، آنها تأثیر می گذارند. علاوه بر این ، حاشیه نویسی های متعدد را می توان در همان تست اعمال کرد که هر کدام پیکربندی خاص خود را دارند.

حاشیه نویسی مشروط توسط سرو پشتیبانی نمی شود ، مگر از طریق راه حل قبلی که قبلاً توضیح داده شد.

این شرایط حاشیه نویسی همچنین می تواند از هرگونه آزمایش آزمایش شده در شیء ارائه شده به آن استفاده کند async عملکرد.

برای این مثال ، هنگامی که مرورگر Firefox است ، از آزمایش استفاده خواهیم کرد:

import { test, expect } from '@playwright/test';

// test-cond-annotation.spec.ts

// Skip the test if the browser is Firefox.

const theName = 'John Wick'

test('Name should be John Wick', async ({ page, browserName }) => {
    test.skip(browserName === 'firefox', 'Still working on it');

    expect(theName).toEqual('John Wick');
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در ترمینال گزارش شده است که یک تست از آن رد شده و دو تست گذشت:

شرح تصویر

ما می توانیم جزئیات بیشتری را در گزارش پیش فرض HTML مشاهده کنیم ، جایی که برگه گذشت دو آزمایش برای Chromium و WebKit را نشان می دهد:

شرح تصویر

و در برگه پرش ، آزمایش Firefox (که با شرایط مطابقت دارد):

شرح تصویر

شما همچنین می توانید آزمایش مشروط را با سایر حاشیه نویسی ها ترکیب کنید در تست ها در این حالت ما در حال ترکیب هستیم .only حاشیه نویسی با مشروط .skip:

import { test, expect } from '@playwright/test';

// test-cond-multiple-annotation.spec.ts

// It will ignore the first test with the title 'Age should be 52'
// and will run only the second test with the title 'Name should be John Wick'
// if browser is not webkit or chromium

const theName = 'John Wick'
const theAge = 52

test('Age should be 52', async ({ page }) => {
    expect(theAge).toEqual(52);
})

test.only('Name should be John Wick', async ({ page, browserName }) => {
    test.skip(browserName === 'webkit' || browserName === 'chromium', 'Skip for webkit and chromium');

    expect(theName).toEqual('John Wick');
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در این مثال آخر ، آزمایش اول نادیده گرفته می شود و فقط آزمایش دوم به دلیل حاشیه نویسی. با این حال ، اگر مرورگر WebKit یا Chromium باشد ، این تست دوم از بین می رود و فقط زمانی اجرا می شود که مرورگر Firefox باشد.

شرح تصویر

ما در گزارش HTML نتایج مشابهی کسب می کنیم:

شرح تصویر

شرح تصویر

توجه داشته باشید که اولین تست با عنوان “سن باید 52” باشد کاملاً نادیده گرفته می شود و در گزارش ظاهر نمی شود.

حاشیه نویسی در قلاب های قبل از

همچنین می توانید از حاشیه نویسی با یا بدون شرط در آن استفاده کنید beforeEach قلاب در این حالت ، حاشیه نویسی برای کلیه آزمایشات موجود در بلوک اعمال می شود .beforeEachبشر

مثال .fixme حاشیه نویسی مشروط در .beforEach قلاب:

import { test, expect } from '@playwright/test';

// test-fixme-beforeeach.spec.ts

// It will skip both tests if we are testing on mobile devices.
// Otherwise, it will visit google.com and check the page title in
// one of the tests and the URL in the other.

test.beforeEach(async ({ page, isMobile }) => {
    test.fixme(isMobile, 'Google page not in mobile yet');

    await page.goto('https://www.google.com');
});

test('Check Google page', async ({ page }) => {
    await expect(page).toHaveTitle('Google')
});

test('Check Google url', async ({ page }) => {
    await expect(page).await expect(page).toHaveURL('https://www.google.com')
});

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

از حالت تمام صفحه خارج شوید

شرح تصویر

توجه کنید که وقتی قرار می دهیم fixme حاشیه نویسی در .beforeEach قلاب ، در مورد هر دو آزمایش در آن بلوک صدق می کند.

مثال a .fail حاشیه نویسی (بدون شرط) در a .beforeEach قلاب:

import { test, expect } from '@playwright/test';

// test-fixme-beforeeach2.spec.ts

// It will pass both tests because they are expected to fail
// (notice the wrong title and the wrong URL in the assertions).

test.beforeEach(async ({ page, isMobile }) => {
    test.fail();

    await page.goto('https://www.google.com');
});

test('Check Google page fails', async ({ page }) => {
    await expect(page).toHaveTitle('Googleeeeeeee')
});

test('Check Google url fails', async ({ page }) => {
    await expect(page).toHaveURL('https://www.google.commmmmmmm')
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

شرح تصویر

در این حالت ، زیرا .fail حاشیه نویسی شامل یک شرط نیست ، انتظار می رود که تمام آزمایشات شکست بخورد.

تست های حاشیه نویسی

اگر می خواهید تست های خود را با اطلاعات دقیق تر از فقط یک برچسب برچسب گذاری کنید ، می توانید با استفاده از annotation خاصیت در شیء گزینه های آزمون ، هنگام اعلام آزمون.

حاشیه نویسی شیء است که شامل a type و الف description برای زمینه اضافه شده ، و آنها از طریق API گزارشگر قابل دسترسی هستند. در نمایشنامه نویس ، گزارشگر داخلی HTML همه حاشیه نویسی ها را به جز مواردی که آنها نشان می دهد ، نمایش می دهد type با یک زیرک شروع می شود _بشر

این حاشیه نویسی های دقیق در Cypress پشتیبانی نمی شود ، و اگر می خواهید آزمایشات خود را با جزئیات مستند کنید ، آنها را بسیار مفید می دانم ، بنابراین می توانید در صورت نیاز هنگام بررسی نتایج آزمون ، آن اطلاعات را مرور کنید.

import { test, expect } from '@playwright/test';

// test-with-annotation.spec.ts

// Annotate the tests with a detailed description of the issue.

const theName = 'WICK-A11Y'

test('Plugin name should be WICK-A11Y', {
    annotation: {
        type: 'issue',
        description: 'Fix issue with with plugin name https://github.com/sclavijosuero/wick-a11y/issues',
    },
}, async ({ page }) => {
    expect(theName).toEqual('WICK-A11Y');
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در ترمینال تمام تست ها می گذرد:

شرح تصویر

وقتی جزئیات آزمون را در گزارش پیش فرض HTML بررسی می کنیم ، می توانید اطلاعات حاشیه نویسی ارائه شده در type وت description زمینه ها:

شرح تصویر

حاشیه نویسی تست دقیق در سرو پشتیبانی نمی شود. من آنها را برای مستند سازی تست های خود با جزئیات بسیار مفید می دانم و به شما امکان می دهد در صورت نیاز هنگام بررسی نتایج آزمون ، آن اطلاعات را بررسی کنید.

همچنین می توانید چندین حاشیه نویسی را به همان آزمون اختصاص دهید:

test('complete report evaluation', {
  annotation: [
    { type: 'bug', description: 'Check details at: https://github.com/microsoft/playwright/issues/23180' },
    { type: 'efficiency', description: 'This test has performance delays.' },
  ],
}, async ({ page }) => {
  // Additional test logic here...
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

حاشیه نویسی زمان اجرا

می توانید حاشیه نویسی را به صورت پویا به آن اضافه کنید test.info().annotations حتی در حالی که آزمون در حال انجام است.

test('sample test case', async ({ page, browserName }) => {
  const version = browserName.version();
  test.info().annotations.push({
    type: 'browserDetails',
    description: `Browser version: \${version}`,
  });

  // ...
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در این تست ، حاشیه نویسی حاوی نسخه مرورگر فعلی به صورت پویا ایجاد شده و به آزمون مرتبط است. این تضمین می کند که اطلاعات نسخه مرورگر در گزارش نتایج آزمون گنجانده شده است ، زمینه ارزشمندی را برای تجزیه و تحلیل نتایج آزمون فراهم می کند.

💕 تست های گروهی (AKA Suites)

با تست های گروهی (سوئیت) می توانید تست های مرتبط را با نام منطقی سازماندهی کنید و شناسایی و مدیریت را ساده کنید. این نامگذاری به تشخیص هدف و دامنه آنها کمک می کند ، ضمن تسهیل اجرای یا محرومیت از گروه های آزمایشی خاص. چنین سازمانی باعث افزایش کارآیی آزمایش شده و وضوح در مدیریت آزمون را حفظ می کند.

گروههای سرو

Cypress همچنین از نحو BDD Mocha برای تست گروه بندی ، استفاده استفاده می کند describe() وت context() برای تعریف گروه های آزمایشی.

توصیف ()

در describe() از عملکرد در سرو برای تعریف یک مجموعه آزمایش استفاده می شود که موارد آزمایش مربوط به آن را با هم گروه ها انجام می دهند. این به عنوان یک ظرف برای it() بلوک ها ، به شما امکان می دهد تست های سازماندهی و ساختار را به صورت خواندنی و قابل نگهداری سازماندهی کنید.

describe('Test Suite Name', () => {

  it('Test case 1', () => {
    // Test logic for case 1
  });

  it('Test case 2', () => {
    // Test logic for case 2
  });

});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

متن ()

تابع context() یکسان با describe()، به عنوان یک نام مستعار خدمت می کنید.

بسیاری از مهندسین QA Cypress ، خودم ، از آنها استفاده می کنند describe() در یک فایل مشخص به عنوان گروه اصلی تست بیرونی ، و context() برای ایجاد زیر گروه هایی از تست های مرتبط در قسمت اصلی describe()بشر با این حال ، به بهترین دانش من ، یک کنوانسیون جهانی پذیرفته شده یا بهترین روش تعریف شده برای این استفاده وجود ندارد.

بیایید این مثال را بررسی کنیم:

// test-groups.cy.js

describe('User Authentication Suite', () => {

    context('Login Tests', () => {
      it('should log in with valid credentials', () => {
        // Test logic for valid login
      });

      it('should not log in with invalid credentials', () => {
        // Test logic for invalid login
      });
    });

    context('Registration Tests', () => {
      it('should register a new user', () => {
        // Test logic for new user registration
      });

      it('should not register with an existing email', () => {
        // Test logic for duplicate email registration
      });
    });

  });
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در مشخصات بالا ، describe() عملکرد برای تعریف مجموعه آزمون اولیه ، مانند 'مجموعه احراز هویت کاربر'. این ماده به عنوان یک ظرف برای چندین مورد آزمایش احراز هویت مرتبط است ، و یک مرور کلی از سطح عملکردی که مورد آزمایش قرار می گیرد ، ارائه می دهد.

در context() تابع برای ایجاد زیر گروه هایی مانند 'استفاده می شودتست های ورود به سیستم'و'تست های ثبت نام“، به طور موثری تست های نزدیک را برای آن مناطق خاص سازماندهی می کنید.

در گزارش سرو ، می توانید مشاهده کنید که هر چهار آزمایش در یک نمایش سلسله مراتبی اجرا می شوند و گروه بندی ساختاری آنها را نشان می دهند:

شرح تصویر

توجه داشته باشید که describe() وت context() همچنین از استفاده از حاشیه نویسی های سرو پشتیبانی کنید .only وت .skipبشر بیایید به نمونه ای از این موضوع نگاه کنیم:

// test-groups-annotation.cy.js

describe('User Management Suite', () => {

  context('User Registration', () => {
    it('should register a new user successfully', () => {
      // Test logic for user registration
    });

    it.skip('should not register with already existing email', () => {
      // Test logic for duplicate email registration
    });
  });

  context('User Login', () => {
    it('should login with valid credentials', () => {
      // Test logic for valid login
    });

    it.only('should not login with invalid credentials', () => {
      // Test logic for invalid login
    });
  });

});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

مجموعه تست به نام 'مجموعه مدیریت کاربر'، با استفاده از describe() عملکرد ، آزمایشات را در دو زیر گروه با سازماندهی می کند context(): 'ثبت کاربر'و'ورود کاربر'.

زیر 'ثبت کاربر' context()، دو آزمایش وجود دارد: 'باید یک کاربر جدید را با موفقیت ثبت کنید'، و'نباید با ایمیل موجود در حال حاضر ثبت نام کنید“که .skip حاشیه نویسی

برای 'ورود کاربر' context()، دو آزمایش نیز وجود دارد: 'باید با اعتبار معتبر وارد شوید'، و'نباید با اعتبار نامعتبر وارد شوید'با یک .only حاشیه نویسی در آخرین مورد.

به نظر شما کدام یک از چهار تست هنگام اجرای این پرونده مشخصات اجرا می شود؟
لحظه ای فکر کنید …

این همان چیزی است که به نظر می رسد مانند اجرای در پرونده Cypress:

شرح تصویر

فقط در آزمون دوم ، “نباید با اعتبار نامعتبر وارد شوید” ، در مرحله دوم context() 'ورود کاربراجرا خواهد شد این دقیقاً تست مشخص شده با .only حاشیه نویسی

قانون این است که در یک پرونده آزمایشی ، فقط آزمایشات با حاشیه نویسی. بدون توجه به تعداد سوئیت ها در پرونده تست یا در آن سطح توخالی از آن استفاده می شود.

گروه های نمایشنامه نویس

(توجه: PW مطالب را در ترمینال نشان می دهد و گزارش می دهد – سر در مقابل بدون سر)
https://playwright.dev/docs/test-annotations#group-tests

test.describ ()

در test.describe() از عملکرد در نمایشنامه نویس برای ایجاد یک مجموعه تست استفاده می شود ، و موارد تست مربوط به گروه را با هم گروه بندی می کند. به عنوان یک ظرف برای test() بلوک ها ، کمک به سازمان و ساختار تست ها.

می توانید از حاشیه نویسی های نمایشنامه نویس استفاده کنید .onlyبا .skipوت .fixme برای کنترل اعدام describe بلوک

همان قانونی که در مورد Cypress صدق می کند نیز در مورد نمایشنامه نویس اعمال می شود: در یک پرونده آزمایشی ، فقط آزمایشات با حاشیه نویسی. به طور کلی اجرا می شود ، صرف نظر از اینکه تعداد زیادی از سوئیت ها در پرونده آزمایش هستند یا در آن سطح توخالی از حاشیه نویسی استفاده می شود.

همچنین الف .describe می تواند شامل توصیفات تو در تو برای تعریف دامنه های مختلف در پرونده آزمون باشد.

const { test, expect } = require('@playwright/test');

// test-groups-annotation.spec.ts

test.describe('Main Application', () => {

  test.describe('User Management', () => {

    test.describe('User Registration', () => {
      test.fail('should show error for invalid email', async ({ page }) => {
        expect(true).toBe(false);
      });

      test('should successfully register a new user', async ({ page }) => {
        expect(true).toBe(true);
      });
    });

    test.describe.skip('User Deletion', () => {
      test('should delete user successfully', async ({ page }) => {
        expect(true).toBe(true);
      });

      test('should not delete non-existent user', async ({ page }) => {
        expect(true).toBe(true);
      });
    });
  });

  test.describe('User Authentication', () => {
    test('should log in with valid credentials', async ({ page }) => {
      expect(true).toBe(true);
    });

    test.fixme('should not log in with invalid credentials', async ({ page }) => {
      expect(true).toBe(true);
    });
  });
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

و این نتیجه است: نه تست می گذرد و نه تست از دست می رود.

شرح تصویر

شرح تصویر

حاشیه نویسی مشروط در TEST.ESECECTION ()

همچنین می توانید حاشیه نویسی مشروط را برای گروه ها اعمال کنید. در اینجا نمونه ای از پرش از شرط بندی گروهی از تست ها آورده شده است:

import { test, expect } from '@playwright/test';

// test-cond-annotation-groups.spec.ts

test.describe('browser-specific tests', () => {
    test.skip(({ browserName }) => browserName === 'firefox', 'Skip on Firefox!');

    test.beforeEach(async ({ page }) => {
        // This hook skips on Firefox.
        await page.goto('https://www.google.com');
    });

    test('test', async ({ page }) => {
        // This test skips on Firefox.
        await expect(page).toHaveTitle('Google')
    });
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در beforeEach هوک و آزمایش فقط در صورتی اجرا می شود که مرورگر Firefox باشد ، زیرا پرش شرطی در داخل اعمال می شود .describe بلوک

شرح تصویر

شرح تصویر

در آخر ، می خواهم ذکر کنم که می توانید حاشیه نویسی های مفصلی را برای گروه هایی که از آنها استفاده می کنند تعریف کنید annotation خاصیت

import { test, expect } from '@playwright/test';

// test-annotation-groups.spec.ts

// Annotation belong to the describe block
test.describe('invoice tests', {
    annotation: { type: 'category', description: 'invoice' },
}, () => {
    test('check invoice details', async ({ page }) => {
        // ...
    });
    test('verify complete invoice', async ({ page }) => {
        // ...
    });
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

test.describ.configure ()

در نمایشنامه نویس ، test.describe.configure() برای تنظیم پیکربندی برای یک مجموعه تست خاص استفاده می شود. می توان آن را یا در سطح بالا در پرونده تست یا در داخل یک توصیف اجرا کرد.

این روش به شما امکان می دهد تا رفتار تست ها را در آن مجموعه تنظیم کنید ، مانند تنظیم یک زمان بندی ، مشخص کردن آزمایشات یا پیکربندی حالت اجرای (parallelبا serial، یا default). بنابراین راهی برای تنظیم محیط اجرای یا آزمون قوانین اجرای برای مجموعه ای از تست های گروه بندی شده تحت یک test.describe بلوک

در مثال زیر ، نمایشنامه نویس هر دو را اجرا می کند describe به طور موازی بلوک می شود ، اما تست های داخل هر یک describe به ترتیب اجرا می شوند:

test.describe.configure({ mode: 'parallel' });

test.describe('A, runs in parallel with B', () => {
  test.describe.configure({ mode: 'default' });
  test('in order A1', async ({ page }) => {});
  test('in order A2', async ({ page }) => {});
});

test.describe('B, runs in parallel with A', () => {
  test.describe.configure({ mode: 'default' });
  test('in order B1', async ({ page }) => {});
  test('in order B2', async ({ page }) => {});
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید


شما گفتید Cypress vs Praywright ، بنابراین … صحبت کنید!

خوب ، همانطور که قول داده ام صحبت خواهم کرد! 📣

بیایید با حاشیه ها:

همه ما می توانیم موافقت کنیم که تمام حاشیه نویسی هایی که توسط Cypress پشتیبانی می شود (CY) همچنین توسط نمایشنامه نویس پشتیبانی می شود (PW)، و اینها هستند .only وت .skipبشر با این حال ، نمایشنامه نویس گزینه های کاملاً دیگری را ارائه می دهد: .fixmeبا .failوت .slowبشر

برای من ، برخی از این حاشیه نویسی های اضافی در نمایشنامه نویس واقعاً جالب هستند (برخی دیگر ، نه خیلی زیاد)!

در .fixme حاشیه نویسی (PW) اساساً همان کار را انجام می دهد .skip، اما کلمه “fixme” به وضوح نشانگر اقداماتی است که هنوز هم باید مورد توجه قرار گیرد. اگرچه ضروری نیست ، اما فکر می کنم مفید است.

حالا ، .fail حاشیه نویسی (PW)واو! این یکی واقعاً باحال است! من قبلاً اشاره کردم که چرا به شما می گویم چرا ، و اکنون لحظه است.

هنگامی که من افزونه منبع منبع باز Cypress-AJV-Schema-Volidator را برای اعتبار سنجی طرحواره JSON در آزمایش API Cypress ایجاد کردم ، همچنین برخی از آزمایشات را انجام دادم که در آن طرح باید شکست بخورد. به این ترتیب ، هنگامی که من نسخه جدیدی را انجام می دهم ، می توانم نتایج آن تست ها را بررسی کنم تا اطمینان حاصل شود که خطاهای طرحواره به درستی پرچم گذاری شده است. با این حال ، همانطور که تصور می کنید ، این شکست ها باعث می شود اقدامات GitHub برای CI/CD شکست بخورد. اشکالی ندارد زیرا این همان کاری است که قرار است انجام دهد – از آزمون – اما حاشیه نویسی مانند نمایشنامه نویس .fail برای مواردی که انتظار می رود آزمایش انجام شود ، بدون تأثیرگذاری بر خط لوله CI/CD بسیار مفید خواهد بود.

در واقع ، من در نظر دارم یک افزونه جدید Cypress برای پشتیبانی از a ایجاد کنم .fail حاشیه نویسی

اکنون نوبت این است .slow حاشیه نویسی (PW)بشر همانطور که قبلاً نیز اشاره کردم ، این حاشیه نویسی برای من چیز بزرگی نیست. در واقع ، من در صورت وجود (حداقل در کد آزمون نهایی) از آن در سرو جلوگیری می کنم. دلیل این امر این است که ، همانطور که بسیاری از شما می دانید ، من طرفدار بزرگی از انتظار خودسرانه نیستم. در .slow حاشیه نویسی سه برابر زمان یک آزمون است ، اما چرا دو برابر نیست یا چهار گانه در عوض؟

دلایل زیادی وجود دارد که یک آزمایش می تواند کند باشد و این موارد می تواند منجر به آزمایش های پوسته پوسته شود. اگر یک آزمایش پوسته پوسته شود ، من مطمئناً بسیار علاقه مندم که چرا را کشف کنم. پس از شناسایی ، من ترجیح می دهم مسئله را به روش های دیگری غیر از افزایش زمان وقوع حل کنم. اگر باید زمان را افزایش دهم ، ترجیح می دهم این کار را فقط برای عنصر موجود در آزمایش ایجاد کند و باعث کندی شود.

بنابراین ، برای من ، .slow حاشیه نویسی بیشتر از ویژگی های مثبت است. با این حال ، من کاملاً می فهمم که چرا می تواند جذاب باشد ، به خصوص در روند اشکال زدایی.

حاشیه نویسی مشروط… این قطعاً یک “استفوق العادهویژگی در نمایشنامه نویس! این کنترل کامل را بر روی کدام آزمایشات برای اجرای در زمان اجرا فراهم می کند. آره عزیزم! 🕶

این شرایط را می توان تقریباً به هر چیزی تنظیم کرد ، از جمله اعمال قدرتمند نمایشنامه نویسان قدرتمند. علاوه بر این ، توانایی شامل حاشیه نویسی مشروط در beforeEach Hooks سطح دیگری از کنترل را بر اجرای آزمون شما ارائه می دهد.

یک چیز دیگر قبل از حرکت از حاشیه نویسی: امکان حاشیه نویسی تست ها با جزئیات بیشتر با استفاده از annotation دارایی (PW)، حتی به صورت پویا ، ممکن است برای بسیاری از مهندسان QA بسیار مهم نباشد ، اما مطمئناً برای کسانی که عاشق مستند سازی تست های خود هستند مفید خواهد بود.

و حالا بیایید در مورد آن صحبت کنیم تست های گروهی (سوئیت):

مشابه حاشیه نویسی ، هر کاری که سرو می تواند در مورد سوئیت انجام دهد توسط نمایشنامه نویس پشتیبانی می شود. با این حال ، سوئیت های نمایشنامه نویس ویژگی های قدرتمند دیگری مانند حاشیه نویسی مشروط و امکان حاشیه نویسی آن مجموعه ها با اطلاعات دقیق تر با استفاده از قبلاً ذکر شده annotation خاصیت

علاوه بر این ، نمایشنامه نویس پشتیبانی می کند test.describe.configure، به شما امکان می دهد رفتار سوئیت ها و آزمایشات را در حین اجرا تنظیم کنید ، مانند اجرای آنها به صورت موازی یا سریال. این ، همراه با قابلیت نمایشنامه نویس برای اجرای مشخصات تست به طور موازی ، اجرای قابل توجهی را به صورت قابل توجهی تسریع می کند و به شرط کنترل کامل بر روی آنها.

بسته بندی کردن

وای ، خیلی زیاد است!

در این مقاله ، ما نه تنها در مورد حاشیه نویسی ها و تست های گروهی-سوئیت هایکا-بلکه ما همچنین همه جزئیات ریز و درشت را در مورد آنچه می توانید و نمی توانید بررسی کردیم ، تفاوت های بین سرو و نمایشنامه نویس (یا نمایشنامه نویس و سرو) را بررسی کردیم. در هر یک از این چارچوب های تست انجام دهید.

اگر می خواهید با تمام نمونه های مورد بحث در این مقاله آزمایش کنید ، می توانید مخزن Sclavijosuero/Cypress-VS-Playwright-FrameWorks را کلون کنید. 🧪

این مخزن همچنین حاوی نمونه هایی از مقاله اول این سریال با عنوان “The Test Drama (The Openo Salvo): Cypress vs Playwright نصب – Good ، The Bad و … Bug -ly!” و خواهد بود. با نمونه هایی برای تمام مقالات آینده در این سری به روز شده است.

به سلامتی!


دوست دارم از شما بشنوم! لطفا فراموش نکنید که اگر این مقاله را مفید یا روشنگری پیدا کردید ، از من پیروی کنید ، نظر یا واکنشی بگذارید. ❤ 🦄 🤯 🔥 🔥

شما همچنین می توانید در جدید من با من ارتباط برقرار کنید کانال یوتیوب: https://www.youtube.com/@sebastianclavijosuero

اگر می خواهید از کار من حمایت کنید ، در نظر بگیرید که یک قهوه برای من بخرید یا در یک جلسه آموزشی مشارکت کنید ، بنابراین می توانم با همه شما یادگیری و به اشتراک گذاری چیزهای جالب را ادامه دهم.
از حمایت شما متشکرم
برای من قهوه بخرید

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا