JavaRush /وبلاگ جاوا /Random-FA /تست TDD و واحد چیست [ترجمه]
Dr-John Zoidberg
مرحله
Марс

تست TDD و واحد چیست [ترجمه]

در گروه منتشر شد
این مقاله اقتباسی از فصلی از کتاب The Complete Software Career Guide است. نویسنده آن، جان سونمز، آن را می نویسد و چند فصل را در وب سایت خود پست می کند.
تست TDD و واحد چیست [ترجمه] - 1

یک واژه نامه کوتاه برای مبتدیان

تست واحد یا تست واحد فرآیندی در برنامه نویسی است که به شما امکان می دهد تک تک ماژول های کد منبع برنامه را از نظر صحت بررسی کنید. ایده این است که برای هر تابع یا روش غیر ضروری، تست بنویسیم. تست رگرسیون یک نام کلی برای همه انواع تست نرم افزار است که با هدف شناسایی خطاها در مناطق قبلاً آزمایش شده کد منبع انجام می شود. چنین خطاهایی - زمانی که پس از ایجاد تغییرات در برنامه، چیزی که باید به کار خود ادامه دهد از کار می افتد - خطاهای رگرسیون نامیده می شوند. نتیجه قرمز، شکست - شکست تست. تفاوت بین نتیجه مورد انتظار و واقعی. نتیجه سبز، قبولی - نتیجه آزمایش مثبت. نتیجه واقعی با آنچه به دست آمده تفاوتی ندارد. ***
تست TDD و واحد چیست [ترجمه] - 2
من با توسعه تست محور (TDD) و تست واحد رابطه بسیار متفاوتی دارم، از عشق به نفرت و دوباره برمی گردم. من یک طرفدار مشتاق و در عین حال یک شکاک مشکوک در مورد استفاده از این، و دیگر، "بهترین شیوه ها" بودم. دلیل نگرش من بر این واقعیت استوار است که یک مشکل جدی در فرآیندهای توسعه نرم‌افزار پدیدار شده است: توسعه‌دهندگان، و گاهی اوقات مدیران، از ابزارها و روش‌های خاصی فقط به این دلیل استفاده می‌کنند که به «بهترین شیوه‌ها» تعلق دارند. دلیل واقعی استفاده از آنها همچنان نامشخص است. یک روز من شروع به کار بر روی یک پروژه خاص کردم و در این فرآیند به من اطلاع دادند که ما کدهای تحت پوشش تعداد زیادی تست واحد را اصلاح خواهیم کرد. شوخی نیست، حدود 3000 مورد وجود داشت. این معمولاً نشانه خوبی است، سیگنالی که توسعه دهندگان از متدولوژی های پیشرفته استفاده می کنند. کد با این رویکرد اغلب ساختار یافته است و بر اساس یک معماری کاملاً فکر شده است. در یک کلام، وجود تست‌ها باعث خوشحالی من شد، حتی به این دلیل که کار من به عنوان مربی برنامه‌نویسان را آسان‌تر می‌کرد. از آنجایی که قبلاً تست واحد داشتیم، تنها کاری که باید انجام می‌دادم این بود که تیم توسعه را برای پشتیبانی از آنها وصل کنم و شروع به نوشتن کد خودمان کنیم. IDE (محیط توسعه یکپارچه) را باز کردم و پروژه را بارگذاری کردم.
تست TDD و واحد چیست [ترجمه] - 3
پروژه بزرگی بود! من یک پوشه با عنوان "تست های واحد" پیدا کردم. فکر کردم: «عالی. - بیا راه اندازیش کنیم ببینیم چی میشه. فقط چند دقیقه طول کشید، و در کمال تعجب، تمام تست ها گذراندند، همه چیز سبز بود ( "سبز" نتیجه مثبت آزمایش است. سیگنال هایی که نشان می دهد کد همانطور که انتظار می رود کار می کند. قرمز نشان دهنده "شکست" یا شکست است، سپس موردی وجود دارد که کد به درستی کار نمی کند - یادداشت مترجم ). همه آنها امتحان را پس دادند. در آن لحظه شکاک درون من از خواب بیدار شد. چطور شد که سه هزار واحد تست کردند و یکباره همه را گرفتند - و نتیجه مثبت دادند؟ در تمرین طولانی مدت خود، زمانی را به یاد نمی آوردم که بدون یک تست واحد منفی در کد، کار روی پروژه ای را شروع کردم. چه باید کرد؟ به صورت دستی بررسی کنید! ChY یک تست تصادفی را انتخاب کرد، نه آشکارترین آنها، اما بلافاصله مشخص شد که او چه چیزی را بررسی می کند. اما در حین کار بر روی آن، متوجه یک چیز پوچ شدم: این آزمون هیچ مقایسه ای با نتیجه مورد انتظار نداشت (ادعا می کند)! یعنی در واقع هیچ چیز بررسی نشد ! مراحل خاصی در آزمون وجود داشت، انجام شد، اما در پایان آزمون، جایی که او باید نتایج واقعی و مورد انتظار را مقایسه کند، بررسی نشد. "آزمایش" چیزی را آزمایش نکرد. یه تست دیگه باز کردم حتی بهتر: عملگر مقایسه با نتیجه نظر داده شده است. درخشان! این یک راه عالی برای انجام تست قبولی است، فقط کدی را که باعث شکست آن شده است را نظر دهید. یه تست دیگه چک کردم بعد یکی دیگه... هیچ کدوم هیچی چک نکردن. سه هزار آزمایش و همه آنها کاملاً بی فایده است. تفاوت زیادی بین نوشتن تست های واحد و درک تست واحد و توسعه تست محور (TDD) وجود دارد.

تست واحد چیست؟

تست TDD و واحد چیست [ترجمه] - 4
ایده اصلی تست واحد نوشتن تست هایی است که کوچکترین "واحد" کد را آزمایش می کنند. آزمون‌های واحد معمولاً به زبان برنامه‌نویسی مشابه کد منبع برنامه نوشته می‌شوند. آنها به طور مستقیم برای آزمایش این کد ایجاد می شوند. یعنی تست های واحد کدی هستند که صحت کدهای دیگر را بررسی می کنند. من از کلمه "تست" کاملا آزادانه در زمینه استفاده می کنم، زیرا تست های واحد به نوعی تست نیستند. آنها چیزی را تجربه نمی کنند. منظور من این است که وقتی یک تست واحد را اجرا می کنید، معمولا متوجه نمی شوید که برخی از کدها کار نمی کنند. این را هنگام نوشتن تست کشف می کنید، زیرا تا زمانی که تست سبز شود، کد را تغییر می دهید. بله، ممکن است کد بعدا تغییر کند و سپس تست شما ممکن است شکست بخورد. بنابراین از این نظر، آزمون واحد یک آزمون رگرسیون است. تست واحد مثل یک تست معمولی نیست که شما چند مرحله داشته باشید که قرار است آنها را طی کنید و ببینید که آیا نرم افزار درست کار می کند یا خیر. در طول فرآیند نوشتن یک آزمون واحد، متوجه می‌شوید که آیا کد آن کاری را که قرار است انجام دهد انجام می‌دهد یا خیر، و تا زمانی که آزمون قبول شود، کد را تغییر می‌دهید.
تست TDD و واحد چیست [ترجمه] - 5
چرا یک آزمون واحد نمی نویسید و بررسی نمی کنید که آیا قبول شده است؟ اگر به این روش فکر کنید، تست های واحد به نوعی الزام مطلق برای ماژول های کد خاص در سطح بسیار پایین تبدیل می شوند. شما می توانید یک آزمون واحد را به عنوان یک مشخصات مطلق در نظر بگیرید . یک تست واحد تعیین می کند که تحت این شرایط، با این مجموعه خاص از ورودی ها، خروجی وجود دارد که باید از این واحد کد دریافت کنید. تست واحد واقعی کوچکترین واحد منسجم کد را شناسایی می کند که در اکثر زبان های برنامه نویسی - حداقل در زبان های شی گرا - یک کلاس است.

گاهی اوقات به چه چیزی تست واحد می گویند؟

تست TDD و واحد چیست [ترجمه] - 6
تست واحد اغلب با تست یکپارچه سازی اشتباه گرفته می شود. برخی از «تست‌های واحد» بیش از یک کلاس را آزمایش می‌کنند یا واحدهای بزرگ کد را آزمایش می‌کنند. بسیاری از توسعه دهندگان ادعا می کنند که تست های واحد را می نویسند در حالی که در واقع تست های جعبه سفید سطح پایین را می نویسند. با این بچه ها بحث نکنید فقط بدانید که آنها در واقع تست های یکپارچه سازی را می نویسند و تست های واحد واقعی کوچکترین واحد کد را جدا از قسمت های دیگر آزمایش می کنند. چیز دیگری که اغلب به آن تست واحد می گویند، تست های واحد بدون بررسی مقدار مورد انتظار است. به عبارت دیگر، تست های واحدی که در واقع چیزی را آزمایش نمی کنند. هر آزمایش، واحد یا غیر واحد، باید شامل نوعی تأیید باشد - ما آن را بررسی نتیجه واقعی در برابر نتیجه مورد انتظار می نامیم. این آشتی است که تعیین می کند آیا آزمون موفق می شود یا ناموفق. امتحانی که همیشه قبول می شود بی فایده است. آزمونی که همیشه شکست بخورد بی فایده است.

ارزش آزمون واحد

چرا من یک مشتاق تست واحد هستم؟ چرا نام آزمایش تعمیم‌یافته، که شامل آزمایش نه کوچک‌ترین بلوک جدا شده از کدهای دیگر، بلکه یک قطعه کد بزرگ‌تر، «تست واحد» است، مضر است؟ اگر برخی از آزمایشات من نتایج دریافتی و مورد انتظار را با هم مقایسه نکنند، مشکل چیست؟ حداقل کد را اجرا می کنند. سعی میکنم توضیح بدم
تست TDD و واحد چیست [ترجمه] - 7
دو دلیل اصلی برای انجام تست واحد وجود دارد. اولین مورد بهبود طراحی کد است. یادتان هست چطور گفتم که تست واحد واقعاً تست نیست؟ وقتی تست های واحد مناسب را می نویسید، خود را مجبور می کنید که کوچکترین واحد کد را جدا کنید. این تلاش ها شما را به کشف مشکلات در ساختار خود کد هدایت می کند. ممکن است جداسازی کلاس تست و شامل نکردن وابستگی های آن برای شما بسیار دشوار باشد و این ممکن است باعث شود که متوجه شوید کد شما خیلی محکم است. ممکن است متوجه شوید که عملکرد اصلی که می‌خواهید آزمایش کنید در چندین ماژول قرار دارد و شما را به این باور می‌رساند که کد شما به اندازه کافی منسجم نیست. وقتی برای نوشتن یک تست واحد می نشینید، ممکن است ناگهان متوجه شوید (و باور کنید، این اتفاق می افتد!) که هیچ ایده ای از کد قرار است انجام دهد. بر این اساس، نمی توانید برای آن آزمون واحد بنویسید. و البته، ممکن است یک اشکال واقعی در پیاده سازی کد پیدا کنید، زیرا تست واحد شما را مجبور می کند خارج از جعبه فکر کنید و مجموعه های مختلفی از ورودی ها را آزمایش کنید که ممکن است در نظر نگرفته باشید.
تست TDD و واحد چیست [ترجمه] - 8
اگر هنگام ایجاد تست های واحد کاملاً به قانون "تست کوچکترین واحد کد جدا از بقیه" پایبند باشید، مطمئناً انواع مشکلات را با آن کد و طراحی آن ماژول ها پیدا خواهید کرد. در چرخه عمر توسعه نرم افزار، تست واحد بیشتر یک فعالیت ارزیابی است تا یک فعالیت آزمایشی. دومین هدف اصلی تست واحد ایجاد مجموعه ای خودکار از تست های رگرسیون است که می تواند به عنوان یک مشخصات سطح پایین رفتار نرم افزار عمل کند. چه مفهومی داره؟ وقتی خمیر را ورز می دهید، آن را نمی شکنید. از این منظر، آزمون های واحد، آزمون ها هستند، به طور خاص آزمون های رگرسیون. با این حال، هدف از تست واحد، ساختن تست های رگرسیون ساده نیست. در عمل، تست های واحد به ندرت رگرسیون را می گیرند، زیرا تغییر در واحد کدی که آزمایش می کنید تقریباً همیشه شامل تغییراتی در خود تست واحد است. تست رگرسیون در سطح بالاتر بسیار موثرتر است، زمانی که کد به عنوان یک "جعبه سیاه" آزمایش می شود، زیرا در این سطح ساختار داخلی کد را می توان تغییر داد، در حالی که انتظار می رود رفتار خارجی یکسان باقی بماند. تست های واحد به نوبه خود ساختار داخلی را بررسی می کنند، به طوری که وقتی آن ساختار تغییر می کند، تست های واحد شکست نخورد. آنها غیر قابل استفاده می شوند و اکنون نیاز به تغییر، دور ریختن یا بازنویسی دارند. شما اکنون بیشتر از بسیاری از توسعه دهندگان نرم افزار کهنه کار در مورد هدف واقعی تست واحد می دانید.

توسعه تست محور (TDD) چیست؟

تست TDD و واحد چیست [ترجمه] - 9
در فرآیند توسعه نرم افزار، یک مشخصات خوب ارزش طلا را دارد. رویکرد TDD این است که قبل از نوشتن هر کدی، ابتدا تستی می نویسید که به عنوان یک مشخصات عمل می کند، یعنی تعریف می کنید که کد باید چه کاری انجام دهد. این یک مفهوم توسعه نرم افزار بسیار قدرتمند است، اما اغلب از آن سوء استفاده می شود. به طور معمول، توسعه مبتنی بر تست به معنای استفاده از تست های واحد برای هدایت ایجاد کد برنامه است. اما در واقع این رویکرد در هر سطحی قابل اعمال است. با این حال، در این مقاله فرض می کنیم که از تست واحد برای برنامه خود استفاده می کنیم. رویکرد TDD همه چیز را برمی گرداند و به جای اینکه ابتدا کد بنویسید و سپس تست های واحد را برای آزمایش آن کد بنویسید، ابتدا یک تست واحد می نویسید و سپس کد می نویسید تا آن تست سبز شود. به این ترتیب، تست واحد توسعه کد را "درایو" می کند. این روند بارها و بارها تکرار می شود. شما تست دیگری می نویسید که عملکرد بیشتری را از آنچه که کد باید انجام دهد را مشخص می کند. سپس کد را بنویسید و تغییر دهید تا مطمئن شوید که تست با موفقیت انجام شده است. هنگامی که یک نتیجه سبز داشتید، کد را دوباره فاکتور می کنید، یعنی آن را مجدداً یا پاکسازی می کنید تا مختصرتر شود. این زنجیره از فرآیندها اغلب "Red-Green-Refactoring" نامیده می شود، زیرا ابتدا آزمون واحد با شکست مواجه می شود (قرمز)، سپس کد برای انطباق با آزمون نوشته می شود و از موفقیت آمیز بودن آن اطمینان حاصل می شود (سبز) و در نهایت کد بهینه می شود. بازسازی). .

هدف TDD چیست؟

تست TDD و واحد چیست [ترجمه] - 10
توسعه تست محور (TDD)، مانند تست واحد، می تواند به اشتباه استفاده شود. خیلی آسان است که کاری را که انجام می دهید «TDD» بنامید و حتی تمرین را دنبال کنید بدون اینکه بفهمید چرا آن را به این صورت انجام می دهید. بزرگترین ارزش TDD این است که آزمایش هایی برای تولید مشخصات کیفی انجام می شود. TDD اساساً تمرین نوشتن مشخصات دقیق است که می توان قبل از نوشتن کدنویسی به طور خودکار بررسی شود. تست ها بهترین مشخصات هستند چون دروغ نمی گویند. آنها پس از دو هفته عذاب با رمز به شما نمی گویند "اصلاً منظورم این نبود." تست ها، وقتی درست نوشته شوند، یا قبول می شوند یا مردود می شوند. آزمایش ها به وضوح نشان می دهد که در شرایط خاص چه اتفاقی باید بیفتد. بنابراین، هدف TDD این است که قبل از شروع اجرای آن، درک کاملی از آنچه باید اجرا کنیم به ما بدهد. اگر با TDD شروع کرده اید و نمی توانید بفهمید که آزمون قرار است چه چیزی را آزمایش کند، باید سوالات بیشتری بپرسید. نقش مهم دیگر TDD حفظ و بهینه سازی کد است. نگهداری کد گران است. من اغلب به شوخی می گویم که بهترین برنامه نویس کسی است که مختصرترین کد را بنویسد که مشکلی را حل کند. یا حتی کسی که ثابت می کند که این مشکل نیازی به حل ندارد و در نتیجه کد را به طور کامل حذف می کند، زیرا این برنامه نویس بود که راه درست را برای کاهش تعداد خطاها و کاهش هزینه های نگهداری برنامه پیدا کرد. با استفاده از TDD، می توانید کاملاً مطمئن باشید که هیچ کد غیرضروری نمی نویسید، زیرا فقط برای قبولی در آزمون ها کد می نویسید. یک اصل توسعه نرم افزار به نام YAGNI وجود دارد (شما به آن نیاز ندارید). TDD از YAGNI جلوگیری می کند.

گردش کار توسعه آزمایش محور معمولی (TDD).

تست TDD و واحد چیست [ترجمه] - 11
درک معنای TDD از دیدگاه صرفاً آکادمیک دشوار است. بنابراین بیایید به نمونه ای از جلسه TDD نگاه کنیم. تصور کنید که پشت میز خود نشسته اید و به سرعت آنچه را که فکر می کنید طراحی سطح بالایی برای ویژگی است که به کاربر اجازه می دهد وارد برنامه ای شده و در صورت فراموشی رمز عبور خود را تغییر دهد، ترسیم کنید. شما تصمیم می گیرید که با اولین پیاده سازی تابع ورود شروع کنید و کلاسی ایجاد کنید که تمام منطق فرآیند ورود را مدیریت کند. شما ویرایشگر مورد علاقه خود را باز می کنید و یک واحد تست به نام "ورود خالی مانع از ورود کاربر می شود" ایجاد می کنید. شما کد واحد تست را می نویسید که ابتدا نمونه ای از کلاس Login (که هنوز ایجاد نکرده اید) ایجاد می کند. سپس کدی را برای فراخوانی متدی در کلاس Login می نویسید که یک نام کاربری و رمز عبور خالی ارسال می کند. در نهایت، یک بررسی در برابر نتیجه مورد انتظار می نویسید و بررسی می کنید که کاربر با لاگین خالی واقعاً وارد نشده باشد. شما سعی می کنید یک تست را اجرا کنید، اما حتی کامپایل نمی شود زیرا کلاس Login ندارید. شما این وضعیت را برطرف می کنید و یک کلاس Login به همراه یک روش در آن کلاس برای ورود به سیستم و دیگری برای بررسی وضعیت کاربر ایجاد می کنید تا ببینید آیا آنها وارد شده اند یا خیر. تاکنون عملکرد این کلاس و روش مورد نیاز ما را پیاده سازی نکرده اید. شما تست را در این مرحله انجام دهید. اکنون کامپایل می شود، اما بلافاصله با شکست مواجه می شود.
تست TDD و واحد چیست [ترجمه] - 12
حالا به کد بازگردید و عملکرد را برای قبولی در آزمون پیاده سازی کنید. در مورد ما، این بدان معنی است که ما باید نتیجه را دریافت کنیم: "کاربر وارد نشده است." شما دوباره تست را اجرا می کنید و حالا قبول می شود. بریم سراغ تست بعدی. حالا بیایید تصور کنیم که باید تستی بنویسید به نام "اگر کاربر یک نام کاربری و رمز عبور معتبر وارد کرده باشد وارد شده است." شما یک تست واحد می نویسید که کلاس Login را نمونه سازی می کند و سعی می کند با نام کاربری و رمز عبور وارد شوید. در یک تست واحد، یک عبارت می نویسید که کلاس Login باید به این سوال که آیا کاربر وارد شده است یا خیر پاسخ دهد. شما این تست جدید را اجرا می‌کنید و البته با شکست مواجه می‌شوید زیرا کلاس Login شما همیشه نشان می‌دهد که کاربر وارد نشده است. شما به کلاس Login خود باز می‌گردید و کدی را پیاده‌سازی می‌کنید تا تأیید کنید که کاربر وارد شده است. در این مورد، شما باید نحوه جداسازی این ماژول را بیابید. در حال حاضر، ساده‌ترین راه برای انجام این کار این است که نام کاربری و رمز عبوری را که در آزمون خود استفاده کرده‌اید، کدگذاری کنید و اگر مطابقت داشتند، نتیجه «user is log in» را برگردانید. شما این تغییر را انجام می دهید، هر دو تست را اجرا می کنید و هر دو موفق می شوند. بیایید به مرحله آخر برویم: شما به کد تولید شده نگاه می کنید و به دنبال راهی برای سازماندهی مجدد و ساده سازی آن هستید. بنابراین الگوریتم TDD این است:
  1. تست ایجاد کرد.
  2. ما برای این تست کد نوشتیم.
  3. کد را بازسازی کرد.

نتیجه گیری

تست TDD و واحد چیست [ترجمه] - 13
این تمام چیزی است که می خواستم در مورد تست واحد و TDD در این مرحله به شما بگویم. در واقع، تلاش برای جداسازی ماژول‌های کد با مشکلات زیادی همراه است، زیرا کد می‌تواند بسیار پیچیده و گیج‌کننده باشد. تعداد بسیار کمی از کلاس ها در انزوا کامل وجود دارند. در عوض، آنها وابستگی دارند و آن وابستگی ها وابستگی دارند و غیره. برای مقابله با چنین شرایطی، کهنه سرباز TDD از ماک هایی استفاده می کند که با جایگزینی اشیا در ماژول های وابسته به جداسازی کلاس های فردی کمک می کند. این مقاله فقط یک مرور کلی و تا حدودی مقدمه ای ساده برای تست واحد و TDD است، ما به جزئیات در مورد ماژول های ساختگی و سایر تکنیک های TDD نمی پردازیم. ایده این است که مفاهیم و اصول اولیه TDD و تست واحد را که امیدواریم اکنون دارید به شما ارائه دهیم. اصلی - https://simpleprogrammer.com/2017/01/30/tdd-unit-testing/
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION