با نحوه ترکیب انواع مختلف آزمایش در یک استراتژی منطقی که با پروژه شما مطابقت دارد آشنا شوید.
خوش بازگشتید! مقاله آخر زمینهسازیهای زیادی درباره نحوه برخورد با انواع مختلف آزمایش و آنچه آنها شامل میشوند ارائه داد و تعاریف نوع آزمایش را روشن کرد. این تصویر میم کوچک را بهیاد میآورید؟ شاید برایتان سؤال شده باشد که همه آن انواع آزمایشی که دربارهشان یاد گرفتید چگونه میتوانند باهم کار کنند.

در ادامه، دقیقاً همین را یاد خواهید گرفت. این مقاله مقدمهای بر نحوه ترکیب این انواع آزمایش در استراتژیهای معقول و انتخاب یکی از آنها که با پروژه شما مطابقت دارد ارائه میدهد.
برای درک بهتر معنای این استراتژیها، میتوانید آنها را با تعدادی شکل مقایسه کنید. در اینجا فهرستی از استراتژیها با اندازهها و دامنههای توسعه مربوطه آورده شده است.
بیایید نگاهی دقیقتر به استراتژیها بیندازیم و با معنای پشت نام آنها آشنا شویم.
تعیین اهداف آزمایش: میخواهید با این آزمایشها به چه چیزی دست یابید؟
پیشاز اینکه بتوانید ساختن استراتژی خوب را شروع کنید، هدف آزمایشتان را مشخص کنید. چه زمانی درنظر میگیرید که برنامهتان بهاندازه کافی آزمایش شده است؟
دستیابی به پوشش آزمایشی بالا اغلب بهعنوان هدف نهایی توسعهدهندگان درزمینه آزمایش درنظر گرفته میشود. اما آیا این همیشه بهترین رویکرد است؟ ممکن است عامل مهم دیگری نیز وجود داشته باشد که باید هنگام تصمیمگیری درباره استراتژی آزمایش درنظر گرفته شود: برآورده کردن نیازهای کاربران.
بهعنوان توسعهدهنده، از برنامهها و دستگاههای بسیار دیگری نیز استفاده میکنید. از این نظر، شما کاربری هستید که به همه این سیستمها تکیه میکنید تا «فقط کار کنند». بهنوبه خود، شما به توسعهدهندگان بیشماری تکیه میکنید تا بهترین تلاش خود را برای عملکرد برنامهها و دستگاههایشان انجام دهند. برای جبران این اعتماد، شما نیز بهعنوان توسعهدهنده تلاش میکنید تا شایسته این اعتماد باشید. بنابراین، اولین هدف شما همیشه باید ارائه نرمافزار کارآمد و خدمت به کاربران باشد. این امر به آزمایشهایی که برای اطمینان از کیفیت برنامه مینویسید نیز گسترش مییابد. کنت سی. Dodds در پست Static vs Unit vs Integration vs E2E Testing for Frontend Apps خود بهخوبی آن را خلاصه میکند:
هرچه آزمایشهای شما بیشتر شبیه نحوه استفاده از نرمافزارتان باشد، اطمینان بیشتری به شما میدهند.
نوشته کنت سی. Dodds
کنت آن را بهعنوان کسب اطمینان در آزمایشها توصیف میکند. هرچه با انتخاب نوع آزمایش مناسب به کاربران نزدیکتر شوید، بیشتر میتوانید به نتایج معتبر آزمایشهایتان اعتماد کنید. بهعبارت دیگر، هرچه در هرم بالاتر بروید، اعتمادبهنفس بیشتری پیدا میکنید. اما صبر کنید، هرم چیست؟
تعیین استراتژیهای آزمایش: نحوه انتخاب استراتژی آزمایش
بهعنوان اولین قدم، مشخص کنید که کدام بخش از الزامات را باید بررسی کنید تا مطمئن شوید که برآورده شدهاند. ببینید از چه نوع آزمایشهایی باید استفاده کنید و در چه سطحی از جزئیات میتوانید بیشترین اطمینان را کسب کنید و درعینحال ساختار هزینه کارآمدی داشته باشید. بسیاری از توسعهدهندگان بااستفاده از قیاس به این موضوع میپردازند. در اینجا رایجترین آنها را که با کلاسیک معروف شروع میشود آوردهایم.

کلاسیک: هرم آزمون
بهمحض اینکه شروع به جستجوی استراتژیهای آزمایش کنید، احتمالاً با هرم خودکارسازی آزمایش بهعنوان اولین قیاس مواجه خواهید شد. مایک کوهن این مفهوم را در کتاب خود با عنوان «موفقیت با Agile» معرفی کرد. بعداً، مارتین فاولر این مفهوم را در مقاله هرم آزمون عملی خود گسترش داد. میتوانید هرم را بهصورت زیر نمایش دهید:

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

هرم سعی میکند این مشکل را با تمرکز بیشتر شما روی آزمایشهای واحد و اولویتبندی دقیق موارد تحت پوشش آزمایشهای E2E حل کند. برای مثال، مهمترین مسیرهای کاربر یا مکانهایی که بیشتر درمعرض نقص هستند. همانطور که مارتین فاولر تأکید میکند، دو نکته مهم در هرم کوهن به شرح زیر است:
- آزمایشهایی با جزئیات متفاوت بنویسید.
- هرچه سطح بالاتری داشته باشید، باید آزمایشهای کمتری داشته باشید.
Pyramid تکامل یافت! اقتباسهای هرمهای آزمایشی
چندین سال است که بحثها حول این هرم میچرخد. بهنظر میرسد این هرم استراتژیهای آزمایش را بیشازحد ساده میکند، بسیاری از انواع آزمایش را نادیده میگیرد، و دیگر برای همه پروژههای دنیای واقعی مناسب نیست. بنابراین، ممکن است گمراهکننده باشد. آیا هرم شکل خود را ازدست داده است؟ Guillermo Rauch نظری درباره آن دارد:
آزمایشها را بنویسید. نه خیلی زیاد. بیشتر ادغام.
اثر گیلرمو راوچ
این یکی از رایجترین نقلقولهای ذکرشده در این موضوع است، پس بیایید آن را تجزیه کنیم:
- «نوشتن آزمایش». نه فقط به این دلیل که اعتماد ایجاد میکند، بلکه به این دلیل که در زمان نگهداری صرفهجویی میکند.
- «نه خیلی زیاد». پوشش ۱۰۰٪ همیشه خوب نیست زیرا دراینصورت آزمایش شما اولویتبندی نمیشود و نگهداری زیادی لازم خواهد بود.
- «Mostly integration» (بیشتر ادغام). در اینجا نیز تأکید بر آزمایشهای ادغام است: این آزمایشها بیشترین ارزش تجاری را دارند زیرا با حفظ زمان اجرای معقول، سطح اطمینان بالایی را بهصورت روزانه برای شما فراهم میکنند.
این باعث میشود دوباره درباره هرم آزمایش فکر کنید و تمرکزتان را به آزمایش ادغام تغییر دهید. طی چند سال گذشته، اقتباسهای زیادی پیشنهاد شده است، بنابراین بیایید به رایجترین آنها نگاه کنیم.
الماس آزمایشی
اولین اقتباس، تأکید بیشازحد بر آزمایش واحد را، همانطور که در هرم آزمایش دیده میشود، حذف میکند. تصور کنید که به پوشش ۱۰۰٪ در آزمونهای واحد رسیدهاید. اما دفعه بعد که کد را بازسازی میکنید، باید بسیاری از این آزمونهای واحد را بهروز کنید و ممکن است وسوسه شوید که از آنها صرفنظر کنید. بنابراین فرسایش پیدا میکنند.
درنتیجه، و همراه با تمرکز بیشتر بر آزمایش یکپارچهسازی، ممکن است شکل زیر ایجاد شود:

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

این شکل ما را یاد لانه زنبور میاندازد، به همین دلیل این نام را برای آن انتخاب کردهایم. لایههای زیر را دارد:
- آزمایشهای یکپارچه. مقاله «اسپاتیفای» از نقلقولی از J. استفاده میکند. ب. Rainsberger برای تعریف این لایه: «آزمایشی که براساس درستی سیستم دیگری قبول یا رد میشود.» چنین آزمایشهایی وابستگیهای خارجی دارند که باید درنظر بگیرید و برعکس، سیستم شما ممکن است وابستگیای باشد که سیستمهای دیگر را خراب میکند. مشابه آزمونهای E2E در قیاسهای دیگر، از این آزمونها با دقت و فقط برای ضروریترین موارد استفاده کنید.
- آزمایشهای یکپارچهسازی. مشابه سایر اقتباسها، باید روی این لایه تمرکز کنید. این سطح شامل آزمایشهایی است که درستی سرویس شما را بهصورت مجزاتر، اما همچنان در ترکیب با سرویسهای دیگر، درستیسنجی میکند. یعنی آزمایشها شامل برخی سیستمهای دیگر نیز میشود و بر نقاط تعامل تمرکز دارد، برای مثال، ازطریق آزمایشهای میانای برنامهسازی کاربردی.
- آزمایش روی جزئیات پیادهسازی. این آزمایشها شبیه آزمایشهای واحد هستند—آزمایشهایی که بر بخشهایی از کد تمرکز دارند که بهطور طبیعی جدا شدهاند و بنابراین پیچیدگی داخلی خود را دارند.
اگر میخواهید درباره این استراتژی آزمایش بیشتر بدانید، پستی را که هرم آزمایش را با لانه زنبور مقایسه میکند از مارتین فاولر و مقاله اصلی از Spotify را ببینید.
جام آزمایشی
میتوانید تمرکز تکراری روی آزمایشهای ادغام را ببینید. بااینحال، نوع دیگری که در مقاله قبلی با آن مواجه شدید، در تئوری آزمایش نمیشود، اما همچنان جنبه مهمی است که باید در استراتژی آزمایش درنظر بگیرید. تحلیل ایستا در هرم آزمون و در اکثر اقتباسهایی که تاکنون دیدهاید وجود ندارد. یک اقتباس از هرم آزمون وجود دارد که تحلیل ایستا را درنظر میگیرد و درعینحال تمرکز را بر آزمونهای یکپارچهسازی حفظ میکند. جام آزمایش از نقلقول قبلی گیلرمو راوچ سرچشمه گرفته و توسط کنت سی. توسعه یافته است. Dodds:

جام آزمایش یک قیاس است که دانهبندی آزمایشها را به روشی کمی متفاوت نشان میدهد. این مدل چهار لایه دارد:
- تجزیهوتحلیل ایستا. این ابزار نقش حیاتی در این قیاس ایفا میکند و به شما امکان میدهد تا با اجرای مراحل اشکالزدایی که قبلاً توضیح داده شد، غلطهای املایی، اشتباهات سبک، و سایر اشکالها را شناسایی کنید.
- آزمونهای واحد. این آزمایشها تضمین میکنند که کوچکترین واحد شما بهدرستی آزمایش شده است، اما جام آزمایشها به همان اندازه هرم آزمایش بر آنها تأکید نمیکند.
- یکپارچهسازی. این تمرکز اصلی است زیرا هزینه و اطمینان بالاتر را به بهترین شکل متعادل میکند، مانند سایر اقتباسها.
- آزمایشهای میانای کاربر. این آزمایشها، ازجمله آزمایشهای E2E و آزمایشهای بصری، در بالای هرم آزمایش قرار دارند، مشابه نقش آنها در هرم آزمایش.
برای کسب اطلاعات بیشتر درباره جام آزمایش، پست وبلاگ کنت سی. را ببینید. Dodds در این موضوع.
برخی رویکردهای بیشتر با تمرکز بر واسط کاربر
همه اینها خوب است اما مهم نیست که استراتژی خود را چه مینامید، «هرم»، «لانه زنبور»، یا «الماس»، هنوز چیزی کم است. اگرچه خودکارسازی آزمایش ارزشمند است، مهم است بهیاد داشته باشید که آزمایش دستی همچنان ضروری است. آزمایش خودکار باید تکالیف روال کاری را کاهش دهد و مهندسان تضمین کیفیت را آزاد کند تا روی حوزههای حیاتی تمرکز کنند. خودکارسازی باید مکمل آزمایش دستی باشد، نه جایگزین آن. آیا راهی برای ادغام آزمایش دستی با خودکارسازی برای نتایج بهینه وجود دارد؟
قیف بستنی آزمایشی و خرچنگ آزمایشی
درواقع دو اقتباس از هرم آزمایشی وجود دارد که بیشتر بر این روشهای آزمایش متمرکز بر میانای کاربر تمرکز دارند. هر دو مزیت اطمینان بالا را دارند، اما طبیعتاً بهدلیل اجرای آزمایشی کندتر، پرهزینهتر هستند.
اولی، مخروط یخی آزمایشی، شبیه هرم وارونه است. بدون مرحله آزمایش دستی، به آن پیتزای آزمایش هم گفته میشود.

مخروط بستنی بیشتر بر آزمایش دستی یا آزمایش میانای کاربر تمرکز دارد و کمترین تمرکز را بر آزمایش واحد دارد. این مشکل اغلب در پروژههایی شکل میگیرد که توسعهدهندگان کار را با چند ایده محدود درباره استراتژی آزمایش شروع کردهاند. کد ice یک ضدالگو درنظر گرفته میشود و این درست است. این کد ازنظر منابع و کار دستی پرهزینه است.
هرم آزمون خرچنگ شبیه به هرم آزمون قیف بستنی است، اما تأکید بیشتری بر آزمایش E2E و آزمایش دیداری دارد:

این راهبرد آزمایشی شامل یک جنبه دیگر نیز میشود: این راهبرد درستیسنجی میکند که برنامه شما عملکرد و ظاهر خوبی داشته باشد. خرچنگ آزمایشگر اهمیت آزمایش بصری را که در مقاله قبلی تعریف شده است برجسته میکند. آزمایش یکپارچهسازی، که به آزمایش مؤلفه و آزمایش API تقسیم میشود، بیشتر به پسزمینه منتقل میشود و آزمایش واحد در اینجا نقش فرعیتری ایفا میکند. جزئیات بیشتر درباره این استراتژی آزمایش را میتوانید در این مقاله درباره خرچنگ آزمایش پیدا کنید.
این دو استراتژی آزمایش با اینکه پرهزینهتر هستند، جایگاه خود را دارند: برای مثال، در پروژههای کوچکتر که به آزمایشهای کمتری نیاز است یا پیچیدگی کمتری باید پوشش داده شود. در این مورد، یک استراتژی آزمایش کامل که بر آزمایش یکپارچهسازی تمرکز دارد ممکن است بیشازحد پیچیده باشد.
اگرچه این دو استراتژی آزمایش پرهزینهتر هستند، اما جایگاه خود را دارند، برای مثال، در پروژههای کوچکتر که به آزمایشهای کمتری نیاز دارند و نیازی به پوشش پیچیدگیهای زیادی ندارند. در این مورد، استراتژی آزمایش در مقیاس کامل با تمرکز بر آزمایش یکپارچهسازی ممکن است بهطور غیرضروری پیچیده باشد.
توصیه کاربردی: بیایید راهبرد بچینیم!
اکنون با رایجترین راهبردهای آزمایش آشنا شدهاید. با مدل کلاسیک (هرم آزمون) شروع کردید و با اقتباسهای متعدد آن آشنا شدید. اکنون باید آنها را برای محصولتان ارزیابی کنید و تصمیم بگیرید کدامیک برای پروژهتان بهترین است. پاسخ این سؤال باید با عبارت محبوب همه شروع شود: «بستگی دارد». اما این موضوع باعث نمیشود دقت آن کمتر شود.

انتخاب مناسبترین راهبرد آزمایش از بین موارد شرحدادهشده (و حتی مواردی که ذکر نشدهاند) به برنامه شما بستگی دارد. این الگو باید با معماری، الزامات، و از همه مهمتر، کاربران و الزامات آنها مطابقت داشته باشد. همه این موارد ممکن است از برنامهای به برنامه دیگر متفاوت باشد. این کاملاً طبیعی است. بهیاد داشته باشید که مهمترین هدف شما خدمت به کاربران است، نه تعریف کتاب درسی.
در بیشتر مواقع، جدا کردن و تعریف کردن آزمایشهای دنیای واقعی بهصورت جداگانه دشوار است. حتی خود مارتین فاولر بر جنبه مثبت تعاریف متفاوت، مانند مورد آزمونهای واحد، تأکید میکند. همانطور که جاستین سیرلز بهدرستی در توئیت خود بیان میکند:
[…] آزمایشهای گویایی بنویسید که مرزهای مشخصی را تعیین میکنند، سریع و قابلاطمینان اجرا میشوند، و فقط بهدلایل مفید ناموفق میشوند.
اثر جاستین سیرلز
روی آزمایشهایی تمرکز کنید که خطاهای واقعی را که ممکن است کاربران با آنها مواجه شوند گزارش میکنند و از هدف خود منحرف نشوید. آزمایشها باید بهگونهای طراحی شوند که برای کاربر مفید باشند، نه اینکه فقط پوشش ۱۰۰٪ ارائه دهند یا درباره اینکه کدام درصد از کدام نوع آزمایش باید نوشته شود بحث کنند.
روی آزمایشهایی تمرکز کنید که خطاهای واقعی را که ممکن است کاربران با آنها مواجه شوند گزارش میکنند و حواستان از هدفتان پرت نشود. آزمایشها باید بهگونهای طراحی شوند که برای کاربر مفید باشند، نه اینکه فقط پوشش ۱۰۰٪ ارائه دهند یا بحثهایی درباره اینکه چه درصدی از یک نوع آزمایش خاص را باید بنویسید ایجاد کنند.