در اردیبهشت ماه سال جاری بود که پس از یک دیپلوی اشتباه در سرویس ارتباطی با یک OMS، شرکت تحلیلگر امید خسارتی بالغ بر چند صد میلیون ریال متحمل شد. این خسارت به تنهایی میتواند یک شرکت را ورشکست کند اما در کنار خسارت مالی، بی اعتماد شدن مشتریان ضربهی مهلک تری بود. پس از آن ما به بازنگری به فرایند های انتشار محصول پرداختیم و سعی کردیم نهتنها چابکی در اضافه کردن فیچر به محصول بیشتر شود، اطمینان از محصول نیز به صددرصد برسد.
۱. بدهی فنی
بزرگترین اشتباهی که یک تیم چابک می تواند گرفتار آن شود، بدهی فنی ست. برخلاف تفکر اشتباه بسیاری از اجایل کاران ایران که بدهی فنی را لازمهی چابکی میدانند و آن را مترداف با کاهش کیفیت و کنارگذاشتن بعضی از فرایند ها میدانند، هیچ متدولوژی چابکی کاهش کیفیت را مجاز نمیداند. فقط در مواقع نادری که محصول باید سریعتر از موعد مشخص برسد و نیاز بازار به محصول بسیار زیاد است، خرد کردن و کوچک کردن فیچر، مجاز شمرده شده است.
بدهی فنی مفهومی در توسعه نرم افزار است که منعکس کننده هزینه ضمنی کار اضافی ای ناشی از انتخاب یک راه حل آسان در زمان حال به جای استفاده از یک رویکرد بهتر که طولانی تر خواهد بود می باشد. بعنوان مثال اگر فیچر در آیندهی ۳ ماهه به تحمل کردن بار ۱۰هزار کاربر نیاز دارد، میتوان در ابتدا به گونه ای محصول را ارائه کرد که تحمل بار کمتری داشته و در اینده به افزایش scalability محصول فکرکرد، اما هرگز نباید کیفیت ارایه محصول و تست و رابط کاربری آسیب ببیند. پس در گام اول سعی کنید فرهنگ غلط بدهی فنی را از تیم خود پاک سازی کنید. سپس در گام بعدی جدولی شامل ۳ ستون عنوان بدهی فنی، میزان نفر برساعت و الویت بسازید و تمامی بدهی های فنی سیستم خود را شناسایی کرده و در هر iteration برای رفع آنها برنامه ریزی کنید.
۲. تست
بزرگترین اشتباه یک برنامه نویس تست نکردن کد خود و دومین اشتباه بزرگش تحویل بدون تست کد به تستر هست( زیرا باعث افزایش رفت و برگشت بین برنامه نویس و تستر و کند شدن فرایند توسعه می شود! ) برنامه نویس باید تست را یکی از وظایف خود بداند و کد خود را بدون تست حتی به محیط تست نرم افزار (staging) منتقل نکند. تست نوشتن برای برنامه ای که تست های بسیار زیادی برای آن نوشته شده، ساده و آسان است اما احتمال اینکه پروژه ای که شما هم اکنون روی آن کار می کنید، تست نداشته باشد زیاد است. برنامه نویسان برای تست پروژه های بدون تست اشتباهات پرتکراری می کنند
در حین اضافه کردن تست به کد های پیشین، هرگز فراموش نکنید که کد جدید بدون تست به پروژه اضافه نکنید.
از بزرگترین مشکلات برنامه نویسان جوگیری ست:)) کسی که تا چندی قبل برای کد خود تست نمینوشته، به TDDروی می آورد ! توسعه تست محور به دلایل بسیار زیادی از قبیل کند کردن مراحل توسعه نرم افزار و ضربه زدن به دید کلی و معماری سطح بالای نرم افزار، مدت زیادی است منسوخ شده است. البته استثنا نیز وجود دارد و این روش برای پیدا کردن باگی که از سمت کاربر گزارش شده بسیار مناسب است. یعنی شرایط رخ دادن باگ را ماک کرده و سعی کنید باگ را reproduceکنید. این گونه یک TDD موفق خواهید داشت.
اگر تا بحال تست ننوشتید و در تیم شما فرهنگ نوشتن تست جا نیفتاده، هرگز به سراغ تکنیک BDD برای نوشتن تست نروید. نوشتن تست همانند نوشتن کد فرایندی ست که در آن داشتن تجربه امری پراهمیت ست و در صورتی که تجربه ای در آن نداشته باشید می تواند بسیار کند و فرسایشی باشد و حتی به شکست بینجامد. پس به نوشتن unit test با دیدگاه BDD یعنی ( given when then ) بپردازید و پس از گرفتن حداقل ۶۰ درصد code coverage در صورت نیاز (و تمایل زیرا به عقیده من bdd به نوشتن تست های بهتر نمی انجامد) به bdd بپردازید.
شروع تست نوشتن برای یک پروژه بدون تست، سرگیجه آور است چون نمی دانیم از کجا شروع کنیم. برای این کار از use case diagram و user story های مهم استفاده کنید. به قانون ۸۰ ۲۰ (قانون پارِتو) ایمان بیاورید! با نوشتن تست برای تنها ۲۰ درصد از یوزر استوری ها میتوانید به محصولتان، ۸۰ درصد اطمینان کنید !
از integration test غافل نشوید تست های جامعی که تمامی اجزای کد و ارتباط کلاس ها و دیتابیس و دیگر اجزای سیستم را یکجا تست بگیرد، coverage زیادی برای شما به ارمغان میآورد و تست های کاملتری محسوب میشوند.
ضبط کردن فرایند های پرتکرار به کمک ابزار های تست ui و اجرا کردن آنها بعد از تغییرات، بسیار فرایند تست ساده و سریعی ست که به اعتقاد من، حتی یک مدیر محصول که دانش برنامه نویسی هم ندارد می تواند انجام دهد! این گونه تست ها هم Integration test حساب میشود و هم فرایند های سطحی و ساده ی سیستم را به خوبی تست میکند.
۳. بازنگری به فرایند deploy
آیا فکر میکنید که با تست همه چیز خوب می شود. قطعا نه! باز هم احتمال وجود باگ در سیستم وجود دارد. با بازنگری به فرایند دیپلوی می توانید احتمال بروز باگ را کمتر از قبل کنید.
حتما از ابزار های ci cd استفاده کنید. به عقیده من بهترین آن gitlab می باشد. به کمک آن اشتباهات ساده در فرایند ساخت و تست خودکار و همچنین دیپلوی را به صفر برسانید. در صورتی که node ها و سرور هایی که کاربران از آنها استفاده میکنند و نرم افزار باید در هر انتشار بر آنها deploy شود، حتما از ansible استفاده کنید که هم در وقتتان صرفه جویی شود و هم از اشتباهات پرتکرار و ساده ای چون فراموش کردن یک node یا یک دستور جلوگیری کنید.
حتما AB test کنید بهتر است محیطی فراهم کنید که نسخه ی جدید محصولتان ابتدا برای ده درصد از کاربرانتان فعال گردد و سپس پس از گرفتن بازخورد آنها، برای باقی کاربران فعال کنید. ما در تحلیلگر امید از مدل Facebook برای انتشار نسخه جدید محصول الهام گرفتیم. ابتدا نسخه جدید را برای همکاران خود در داخل شرکت فعال میکنیم. پس از خوب بودن بازخورد ها برای ده درصد مشتریان، سپس برای ۳۰ درصد مشتریان و در مرحله آخر برای تمامی مشتریان نسخه جدید را ارائه میکنیم.
سیاست rollback همیشه بدترین حالت را در نظر داشته باشید. فرض کنید محصول را لانچ کردید و فهمیدید مشکلی دارد که می تواند میلیارد ها تومان ضرر به شما وارد کند. چه میکنید؟ سرور را خاموش می کنید !؟ دست به کد می شوید و در همان لحظه دیپلوی مجدد میکنید؟!( آنهم بدون تست !!!) خیر، راه درست، revert کردن سیستم به آخرین زمان stable ست! اگر از git و ci cd آن استفاده کنید، این کار با چند کلیک ساده انجام پذیر است. اما فرض کنید در ورژن جدید محصولتان تغییری در دیتابیس دادید یا کاری کردید که ورژن جدیدتان revertable نیست ! آنگاه چه میکنید!؟ + راه حل: در این شرایط هرگز دیپلوی نکنید! - پس چه کنیم؟ تا آخر عمر محصول فیچر نزنیم؟! + خیر، سیاست rollback بنویسید تا در صورت مشکل خوردن دیپلوی بتوانید محصول خود را revert کنید. سپس دیپلوی کنید! شاید برایتان جالب باشد اما ما برای هر ورژن محصول یک نسخه برای rollback طراحی می کنیم و سپس نسخه جدید را منتشر می کنیم !
اینها از جمله اقداماتی ست که تحلیلگر امید را به امن ترین سامانه معاملاتی کشور تبدیل کرده است ! امیدوارم با این توصیه ها شما نیز در فضایی پر از آرامش کد بزنید و دیپلوی کنید.