جایی که تست ها اجرا می شوند

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

اسکریپت پیش نیاز

پروژه های وب معمولاً دارای یک فایل پیکربندی هستند - فایل package.json آنها - که توسط npm، pnpm، Bun یا موارد مشابه تنظیم می شود. این فایل پیکربندی شامل وابستگی های پروژه شما و اطلاعات دیگر و همچنین اسکریپت های کمکی است. این اسکریپت های کمکی ممکن است شامل نحوه ساخت، اجرا یا آزمایش پروژه شما باشد.

در داخل package.json ، باید اسکریپتی به نام test اضافه کنید که نحوه اجرای تست‌های شما را توضیح می‌دهد. این مهم است زیرا هنگام استفاده از npm یا ابزار مشابه، اسکریپت "تست" معنای خاصی دارد . این اسکریپت فقط می‌تواند به یک فایل منفرد اشاره کند که یک استثنا ایجاد می‌کند - چیزی مانند node tests.js - اما توصیه می‌کنیم از آن برای اشاره به یک اجراکننده آزمایشی استفاده کنید.

اگر از Vitest به عنوان اجرای آزمایشی خود استفاده می کنید، فایل package.json شما به شکل زیر خواهد بود:

{
  "name": "example-project",
  "scripts": {
    "start": "node server.js",
    "test": "vitest --run"
  }
}

اجرای npm test با این فایل، مجموعه تست های پیش فرض Vitest را یک بار اجرا می کند. در Vitest، پیش‌فرض این است که تمام فایل‌هایی که به «.test.js» یا مشابه ختم می‌شوند را پیدا کرده و اجرا کنید. بسته به آزمونی که انتخاب کرده اید، دستور ممکن است کمی متفاوت باشد.

ما انتخاب کرده‌ایم که از Vitest، یک چارچوب تستی که به طور فزاینده‌ای محبوب است، برای نمونه‌هایی در طول این دوره استفاده کنیم. شما می توانید اطلاعات بیشتری در مورد این تصمیم در Vitest به عنوان یک دونده آزمایشی بخوانید. با این حال، مهم است که به یاد داشته باشید که چارچوب‌های تست و اجراکننده‌ها - حتی در بین زبان‌ها - معمولاً یک زبان بومی مشترک دارند.

فراخوانی آزمون دستی

راه‌اندازی دستی تست‌های خودکار شما (مانند استفاده از npm test در مثال قبلی) می‌تواند زمانی که شما فعالانه روی یک پایگاه کد کار می‌کنید، عملی باشد. نوشتن آزمایش‌هایی برای یک ویژگی در حین توسعه آن ویژگی می‌تواند به شما کمک کند تا درکی از روشی که این ویژگی باید کار کند را به دست آورید - این به مفهوم توسعه مبتنی بر آزمایش (TDD) می‌پردازد.

دونده های تست معمولاً یک فرمان کوتاه دارند که می توانید برای اجرای برخی یا همه تست های خود از آن فراخوانی کنید و احتمالاً یک حالت تماشاگر که تست ها را با ذخیره آنها دوباره اجرا می کند. همه اینها هنگام توسعه یک ویژگی جدید گزینه‌های مفیدی هستند و به گونه‌ای طراحی شده‌اند که نوشتن یک ویژگی جدید، آزمایش‌های آن یا هر دو را با بازخورد سریع آسان کنند. برای مثال Vitest به طور پیش‌فرض در حالت تماشاگر عمل می‌کند: فرمان vitest تغییرات را مشاهده می‌کند و هر آزمایشی را که پیدا می‌کند دوباره اجرا می‌کند. توصیه می‌کنیم هنگام نوشتن تست‌ها، آن را در پنجره دیگری باز بگذارید تا بتوانید در حین توسعه آن‌ها، بازخورد سریعی در مورد تست‌های خود دریافت کنید.

برخی از دونده ها همچنین به شما اجازه می دهند که تست ها را only در کد خود علامت گذاری کنید. اگر کد شما only شامل تست‌ها می‌شود، تنها این تست‌ها هنگام اجرای تست فعال می‌شوند و عیب‌یابی توسعه تست را سریع‌تر و آسان‌تر می‌کنند. حتی اگر تمام تست‌های شما به سرعت کامل شوند، only استفاده از آن می‌تواند هزینه‌های اضافی شما را کاهش دهد و حواس پرتی آزمایش‌های در حال اجرا غیرمرتبط با ویژگی یا تستی را که روی آن کار می‌کنید، از بین ببرد.

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

آزمایش ها را به عنوان بخشی از پیش ارسال یا بازبینی اجرا کنید

بسیاری از پروژه‌ها تأیید می‌کنند که یک پایگاه کد زمانی که قرار است دوباره در شاخه main آن ادغام شود، به درستی کار می‌کند. اگر در آزمایش‌ها تازه کار هستید، اما در گذشته در پروژه‌های منبع باز مشارکت داشته‌اید، احتمالاً متوجه شده‌اید که بخشی از فرآیند درخواست کشش (PR) تأیید می‌کند که تمام آزمایش‌های پروژه قبول شده‌اند، به این معنی که مشارکت جدید هیجان‌انگیز شما انجام نشده است. بر پروژه موجود تأثیر منفی گذاشت.

اگر تست‌های خود را به صورت محلی اجرا کنید، مخزن آنلاین پروژه شما (به عنوان مثال، GitHub یا سرویس میزبانی کد دیگر) متوجه نمی‌شود که تست‌های شما در حال قبولی است، بنابراین اجرای آزمایش‌ها به عنوان یک کار پیش‌ارسال به همه مشارکت‌کنندگان روشن می‌کند که همه چیز کار می‌کند.

به عنوان مثال، GitHub به این موارد به عنوان "بررسی وضعیت" اشاره می کند که می توانید از طریق GitHub Actions اضافه کنید. اکشن‌های GitHub اساساً نوعی آزمایش هستند: هر مرحله باید موفقیت‌آمیز باشد (نه شکست بخورد یا یک Error ایجاد کند) تا عمل انجام شود. می‌توانید Actions را برای همه PRهای یک پروژه اعمال کنید، و یک پروژه می‌تواند قبل از مشارکت دادن کد، لازم باشد که Actions تصویب شود. اکشن پیش‌فرض Node.js GitHub npm test به عنوان یکی از مراحل آن اجرا می‌کند.

تصویری از فرآیند آزمایش GitHub Actions.
تصویری از فرآیند آزمایش GitHub Actions.

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

تست ها را به عنوان بخشی از یکپارچگی مداوم اجرا کنید

هنگامی که روابط عمومی سبز شما پذیرفته شد، اکثر پایگاه های کد مجدداً آزمایشات را بر اساس شاخه main پروژه شما به جای PR قبلی انجام می دهند. این ممکن است بلافاصله یا به طور منظم (به عنوان مثال، ساعتی یا شبانه) اتفاق بیفتد. این نتایج اغلب به عنوان بخشی از داشبورد یکپارچه سازی پیوسته (CI) نشان داده می شود که سلامت کلی پروژه را نشان می دهد.

این مرحله CI ممکن است اضافی به نظر برسد، مخصوصاً برای پروژه‌هایی که پایگاه‌های کد کوچکی دارند—تست‌هایی که در حین بررسی گذرانده شده‌اند، بنابراین باید پس از انجام تغییر، آن‌ها را پاس کنند. با این حال، این همیشه درست نیست! آزمایشات شما ممکن است به طور ناگهانی شکست بخورند، حتی پس از تولید موفقیت آمیز نتایج سبز. برخی از دلایل این امر عبارتند از:

  • چندین تغییر "به یکباره" پذیرفته شد، که گاهی اوقات به عنوان شرایط نژاد شناخته می شود، و آنها به روش های ظریف و آزمایش نشده بر یکدیگر تاثیر می گذارند.
  • تست‌های شما قابل تکرار نیستند، یا کدهای "شلیک" را آزمایش می‌کنند—هم می‌توانند بدون تغییر کد قبول شوند و هم شکست بخورند.
    • اگر به سیستم‌های خارج از پایگاه کد خود وابسته باشید، ممکن است این اتفاق بیفتد. برای یک پروکسی، آزمایش را تصور کنید که Math.random() > 0.05 — این به طور تصادفی در 5٪ مواقع با شکست مواجه می شود.
  • برخی از تست‌ها برای اجرا در هر روابط عمومی بسیار پرهزینه یا پرهزینه هستند، مانند تست‌های سرتاسر (در مورد این موضوع در انواع تست‌های خودکار بیشتر توضیح داده می‌شود)، و می‌توانند در طول زمان بدون هشدار همیشه شکسته شوند.

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

یک فاصله زمانی در بازگشت

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

برای پروژه های کوچکتر، غریزه شما ممکن است این باشد که آن را به عنوان یک بحران در نظر بگیرید! همه چیز را متوقف کنید، به عقب برگردید یا تغییر توهین آمیز را برگردانید و به وضعیت خوب شناخته شده بازگردید. این می تواند یک رویکرد معتبر باشد، اما مهم است که به یاد داشته باشید که آزمایش (و به طور کلی نرم افزار!) وسیله ای برای رسیدن به هدف است، نه یک هدف به خودی خود. هدف شما احتمالا نوشتن نرم افزار است، نه اینکه تمام تست ها را قبول کنید. درعوض، می‌توانید با پیگیری تغییر شکسته با تغییر دیگری که تست‌های ناموفق را برطرف می‌کند، جلو بروید.

از سوی دیگر، ممکن است پروژه‌های بزرگی را دیده باشید یا روی آنها کار کرده باشید که در حالتی دائماً شکسته هستند. یا بدتر از آن، این پروژه بزرگ دارای یک تست پوسته پوسته است که اغلب آنقدر شکسته می شود که باعث ایجاد خستگی هشدار در توسعه دهندگان شود. این اغلب یک مشکل وجودی است که رهبران باید آن را حل کنند: این تست‌ها حتی ممکن است غیرفعال شوند، زیرا آنها به عنوان "در مسیر توسعه" دیده می‌شوند.

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

منابع

درک خود را بررسی کنید

اسم اسکریپت خاصی که npm و برنامه های مشابه در هنگام تست به دنبالش می گردند چیست؟

بررسی کنید
تست کنید
از پیش ارائه کنید
تایید کنید