<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های علی سوران</title>
        <link>https://virgool.io/feed/@souran</link>
        <description>توسعه‌دهنده فرانت‌اند، مدافع نرم‌افزار آزاد و طرفدار GNU/Linux</description>
        <language>fa</language>
        <pubDate>2026-06-16 16:14:27</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/41611/avatar/V9Iavr.png?height=120&amp;width=120</url>
            <title>علی سوران</title>
            <link>https://virgool.io/@souran</link>
        </image>

                    <item>
                <title>تست‌نویسی در ری‌اکت به سبک Kent C. Dodds: رفتار رو تست کن، نه جزئیات رو!</title>
                <link>https://virgool.io/@souran/%D8%AA%D8%B3%D8%AA-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%AF%D8%B1-%D8%B1%DB%8C-%D8%A7%DA%A9%D8%AA-%D8%A8%D9%87-%D8%B3%D8%A8%DA%A9-kent-c-dodds-%D8%B1%D9%81%D8%AA%D8%A7%D8%B1-%D8%B1%D9%88-%D8%AA%D8%B3%D8%AA-%DA%A9%D9%86-%D9%86%D9%87-%D8%AC%D8%B2%D8%A6%DB%8C%D8%A7%D8%AA-%D8%B1%D9%88-rgsfrdcubt8e</link>
                <description>خلاصه:اگه تستی می‌نویسی که با یه تغییر نام متغیر (state) می‌شکنه، یعنی داری اشتباه می‌زنی.کاربر اصلاً براش مهم نیست کامپوننت تو با useState نوشته شده یا useReducer. اون فقط دکمه و متن رو می‌بینه.قانون طلایی: تست‌های تو باید دقیقاً مثل یک کاربر واقعی با نرم‌افزار رفتار کنن (کلیک کنن، تایپ کنن، ببینن)، نه مثل یک برنامه نویس که کد رو می‌خونه!فرض کن یه کامپوننت خیلی ساده برای بخش FAQ سایتت نوشتی. وظیفه‌ش مشخصه: یه سری سوال و جواب که با کلیک روی هر کدوم، باز و بسته می‌شن. برای مدیریت این باز و بسته شدن، یه state تعریف کردی به اسم isOpen. منطق ساده‌ست: هر کلیک، مقدار isOpen رو برعکس می‌کنه.بعد از پیاده‌سازی، مثل یه دولوپر حرفه‌ای شروع می‌کنی به نوشتن تست. سعی می‌کنی مو به موی چیزی که نوشتی رو تست کنی:&quot;آیا isOpen اولش false هست؟&quot;&quot;آیا بعد از کلیک isOpen میشه true؟&quot;همه چیز عالیه. ۱۰۰٪ Coverage. تست‌ها رو اجرا می‌کنی و دیدن اون تیک‌های سبز پشت سر هم، حس قدرت بهت میده. کامیت میکنی و به خودت که انقدر تمیز کد زدی و تست نوشتی افتخار میکنی!یک ماه می‌گذره... توی یه تسک جدید، قراره یه فیچر اضافه کنی: توی متن یکی از آیتم‌ها، یه &quot;مودال&quot; هم باز بشه که توضیحاتی درباره پرایسینگ داشته باشه. میری سراغ کد قدیمی که برای FAQ نوشته بودی. چشمت می‌خوره به isOpen. با خودت میگی: «این اسم الان دیگه مبهمه. اگه مودال هم باز بشه، دوتا isOpenداریم.»یاد اون قانون معروف &quot;Boy Scout Rule&quot; میفتی:You should always leave code a little cleaner than you found it!«کد رو همیشه تمیزتر از چیزی که تحویل گرفتی، تحویل بده.»پس تصمیم می‌گیری یه ری‌فکتور ریز انجام بدی:اسم isOpen رو می‌کنی isItemOpenیه استیت جدید میاری به اسم isModalOpenکد تمیز شد، منطق همونه، همه چی کار می‌کنه. با خوشحالی git push می‌کنی. می‌ری توی پنل CI/CD و منتظری سبز بشه تا دیپلوی کنی... اما یه لیست بلندبالا از ضربدرهای قرمز برای کامپوننت FAQ!مگه قرار نبود تست‌ها محافظ کد باشن؟ چرا مزاحم کد شدن؟با خودت میگی:‌ مگه منطق برنامه عوض شده؟ مگه باگ توی برنامه هست؟ کاربر هنوزم کلیک می‌کنه و آیتم باز میشه. پس چرا تست فیل شد؟جوابی که باید داد اینه: تو داشتی &quot;پیاده‌سازی&quot; رو تست می‌کردی، نه &quot;رفتار&quot; رو.تست تو انتظار داشت یه متغیر به اسم isOpen داشته باشی ولی وقتی تو اسم متغیر رو عوض کردی، تست گیج شد. این یعنی تست تو به جای اینکه محافظ کد باشه، شده مزاحم کد.یعنی چی؟ بذار با یه مثال توضیح بدم.بیا فرض کنیم تو یه جعبه‌ی شفاف داری که تمام قطعات داخلیش پیداست. روی این جعبه یه کلید تعبیه شده و قراره با زدنش، لامپی که بالای جعبه‌ست روشن بشه. داخل جعبه یه عالمه سیم‌کشی پیچیده هست: یه سیم آبی به مدار سمت چپ وصله، یه سیم قرمز به منبع تغذیه رفته و یه سیم سیاه هم به خود کلید وصل شده.تو میای برای اطمینان از سالم بودن دستگاه، همچین تستی می‌نویسی:test(&#039;circuit internals check&#039;, () =&gt; {
  const box = new ElectronicBox();

  expect(box.internalWires.blue).toBeConnectedTo(&#039;circuit-A&#039;);
  expect(box.internalWires.red).toBeConnectedTo(&#039;power-source&#039;);
  expect(box.internalWires.black).toBeConnectedTo(&#039;switch&#039;);
  
  expect(box.lightBulb).toBe(&#039;on&#039;);
});همه چیز عالیه و تست ها پاس میشه. بعد از یه مدت، یه مهندس برق میاد و تصمیم می‌گیره سیستم داخلی رو بهینه‌تر کنه. اون تمام سیم‌های رنگی رو با یه مدار جدید و مدرن جایگزین می‌کنه. دستگاه الان بهتر و سریع‌تر کار می‌کنه و لامپ هم با زدن کلید روشن میشه.اما اتفاقی که میفته اینه: تست‌های از کار افتادن! چرا؟ چون تو داشتی &quot;پیاده‌سازی&quot; رو تست می‌کردی، نه &quot;رفتار&quot; (روشن شدن لامپ).داستان اینه که کاربر نهایی اصلاً براش مهم نیست اون تو سیم آبیه یا زرد، یا اصلاً سیمی وجود داره یا نه؛ اون فقط می‌خواد وقتی کلید رو زد، لامپ روشن بشه. در واقع پیاده‌سازی تو مشکلی نداره، فقط تستت داره False Negative میده!در واقع تست درست برای این رفتار باید به شکل زیر باشه:test(&#039;light turns on when switch is pressed&#039;, () =&gt; {
  const box = new ElectronicBox();

  user.press(box.switch);

  expect(box.lightBulb).toBe(&#039;on&#039;);
});تو این روش، مهندس برق می‌تونه کل محتویات جعبه رو برداره و جاش یه همستر بذاره که با دویدن روی یه گردونه برق تولید می‌کنه! تا زمانی که با زدن کلید لامپ روشن بشه، تست تو سبز می‌مونه. این یعنی تست در خدمت کد توعه، نه مزاحم اون. در واقع با این مدل تست‌نویسی، تو کاری که انجام می‌دی اینه که داری رفتار یه کاربر رو تست می‌کنی. حتی اگه تمام کدی که با React زدی رو بریزی دور و اون رو به Vue تبدیل کنی، باز هم تست‌های تو دارن کار می‌کنن چون بر مبنای &quot;رفتار کاربر&quot; نوشته شدن.اگه تستت شکست و مجبوری بری تو کد پیاده‌سازی (implementation) نگاه کنی که بفهمی چرا شکست، یعنی تستت اشتباه نوشته شده!حالا دقیقاً باید چه نوع تستی بنویسم؟احتمالاً شنیدید که میگن باید Unit Test زیاد بنویسید، Integration کمتر و E2E خیلی کمتر (هرم تست).اما وقتی با رویکرد &quot;تست رفتار&quot; جلو میریم، معادلات عوض میشه. ما دیگه هرم تست رو می‌ذاریم کنار و میریم سراغ جام تست (Testing Trophy; Kent C. Dodds). تو این مفهوم مدرن، بخش Integration بزرگترین و مهم‌ترین سهم رو تو استراتژی تست‌نویسی داره. به جای اینکه خودمون رو توی باتلاق هزاران Unit Test ریز غرق کنیم یا درگیر تست‌های E2E کند بشیم، تمرکز اصلی رو میذاریم روی تست‌هایی که تعامل بخش‌های مختلف رو چک می‌کنن.حالا هدف از این همه توضیحات چیه؟ اعتماد به نفس! تست‌نویسی نباید باعث بشه از تغییر دادن کد بترسی. برعکس، تست‌ها باید بهت این قدرت رو بدن که کد رو زیر و رو کنی، ری‌فکتور کنی و فیچر جدید بزنی، در حالی که مطمئنی &quot;تجربه کاربر&quot; هیچ تغییری نکرده. این یعنی تست در خدمت تو، نه تو در خدمت تست.حالا که ذهنیت‌مون رو از &quot;تست کد&quot; به &quot;تست رفتار&quot; تغییر دادیم، توی قسمت‌های بعدی دست به کد می‌شیم و میریم سراغ ابزارهای تست‌نویسی تا یاد بگیریم چطور توی دنیای واقعیِ React این کار رو انجام بدیم.امیدوارم این مقاله کمک کرده باشه که تست‌نویسی براتون ساده‌تر و شیرین‌تر بشه.</description>
                <category>علی سوران</category>
                <author>علی سوران</author>
                <pubDate>Wed, 19 Nov 2025 12:13:44 +0330</pubDate>
            </item>
                    <item>
                <title>دانلود و نصب محصولات ادوبی روی مک M1</title>
                <link>https://virgool.io/@souran/install-adobe-products-on-macbook-hc2nhhueazca</link>
                <description>ربط زیادی به داستان نداره همینجوری گذاشتم برای کاور. :))اگه شما هم بعد از خریدن مک بوک M1 با دردسرهای نصب محصولات شرکت Adobe به صورت کرکی (چقدر بده که کرکی استفاده می‌کنیم ?) رو به رو شدید یا آخر جستجوهاتون به سایت‌هایی رسیدید که محصولات یه شرکت دیگه رو (که تازه اونم یه نفر دیگه کرک کرده) با مبالغ بالا دارن میفروشن، تا آخر این مقاله رو بخونید تا بتونید آخرین نسخه‌های ادوب رو خیلی راحت و بدون دردسر نصب کنید.خب اول مقاله یکم شبیه این آیا میدانید‌ها شد و سلام ندادیم.سلام حالتون خوبه؟توضیحات اضافی زیاد نمیدم و سریع میریم سراغ نصب ملزومات چون قطعا وقتی تا اینجا اومدید، مشکل نصب رو دارید.اول از همه به لینک زیر برید و برنامه‌ی Adobe Zii رو نصب کنید:https://macdrop.net/adobe-zii-2021-v6-1-7/ تو این سایت یه لیستی از برنامه‌ها و ورژنشون هست که حتما تو مراحل بعدی باید به ورژنی که قراره نصب کنید توجه کنید.خب بعد از دانلود و نصب Adobe Zii (باهاش کار داریم بعدا) کار بعدی اینه که ترمینال خودتونو باز کنید و این قطعه کد رو وارد کنید و اینتر رو بزنید (شیلترفکن رو فعال کرده باشید حتما):/bin/bash -c &amp;quot$(curl -fsSL https://gist.githubusercontent.com/thpryrchn/c0ea1b6793117b00494af5f05959d526/raw/install.sh)&amp;quotبعد از چند دقیقه با این پیغام مواجه می‌شید:Done! You can now start /Applications/Adobe Packager.command to beginبعد از این که برنامه مورد نظر ما نصب شد به پوشه‌ی Applications میریم و برنامه‌ی Adobe Packager.command رو اجرا کنید.Adobe Packager.commandبعد از نصب و اجرا باید لیستی از محصولات ادوب به شکل زیر به شما نمایش داده بشه:لیست محصولات ادوبتو این مرحله، از داخل لیست محصولات باید کد کنار اسم محصولتون رو برای نصب وارد کنید.مثلا برای فتوشاپ: PHPSتو مرحله‌ی بعدی باید اول برید به سایتی که اول براتون معرفی کردم (صفحه‌ی دانلود Adobe Zii) و از اونجا تو لیست محصولات ورژن محصولی رو که Adobe Zii ساپورت میکنه رو پیدا کنید و اینجا وارد کنید.برای مثال فتوشاپ ورژن ۲۲.۴.۳ ساپورت میشه.لیست ورژن‌های فتوشاپبعد از این که ورژن رو وارد کردید سوال بعدی زبان فتوشاپ هستش که با زدن اینتر (بدون وارد کردن چیزی) زبان انگلیسی انتخاب میشه.لیست زبان‌های فتوشاپ تو مرحله‌ی بعدی محل دانلود فایل نصبی رو از شما میخواد که شما هرجایی که مد نظرتون بود رو میتونید انتخاب کنید و بعد منتظر بمونید تا فایل دانلود بشه.فایل نصبی باید به صورت زیر باشه و با محصولات دیگه‌ای که قبلا دانلود میکردید احتمالا فرق داره:فایل نصبی فتوشاپبا دبل کلیک کردن اجرا میشه و با زدن گزینه‌ی install نصب شروع میشه و تا پایان و پیغام موفقیت آمیز بودن نصب باید صبر کنید.آخرین مرحله کرک کردن محصول به وسیله‌ی Adobe Zii هستش:Adobe Ziiبرای کرک کردن محصول وارد پوشه‌ی Application بشید و پوشه‌ی محصول خودتون رو باز کنید:پوشه‌ی فتوشاپو با درگ اند دراپ به صورت زیر فایل محصول رو کرک کنید:کرک کردن فتوشاپخب حالا میتونید برنامه رو به راحتی اجرا کنید اما اگه برای محصولی (رو CPU M1) به مشکل خوردید و برنامه کرش کرد باید از پوشه‌ی Applications وارد پوشه‌ی محصولتون بشید، روش کلیک راست کنید و Get Info رو بزنید و تیک گزینه‌ی Open using Rosetta رو بزنید تا برنامه براتون بدون مشکل اجرا بشه.Get Info Adobe Lightroom Classicامیدوارم تونسته باشم کمکی برای نصب محصولات ادوبی بهتون کرده باشم.اگه سوالی بود تو بخش نظرات (اگه سوادم رسید) جواب میدم بهتون.</description>
                <category>علی سوران</category>
                <author>علی سوران</author>
                <pubDate>Sat, 28 Aug 2021 14:51:39 +0430</pubDate>
            </item>
            </channel>
</rss>