یکپارچه سازی تست در ری اکت

28 اردیبهشت 1398
درسنامه درس 26 از سری آموزش react (ری اکت)
React-test

در این درس قصد داریم به آخرین بحث درباره تست یک برنامه بپردازیم و درباره نحوه یکپارچه سازی تست برنامه های ری اکتی صحبت کنیم.

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

یکپارچه سازی تست

در این درس هنگام نوشتن تست باید برنامه را در یک مرورگر اجرا کنیم تا بدین ترتیب بتوانیم تست مان را در یک حالت واقعی بررسی کنیم.

همچنین از یک سرور خودکار به نام Selenium استفاده خواهیم کرد. ابتدا آن را دانلود کرده و از یک فریمورک تست خودکار به نام Nightwatch بهره ببرید. در ادامه به توضیح این مباحث می پردازیم.

نصب

راحت ترین راه برای استفاده از selenium مراجعه به این وب سایت و دانلود آن است.

و در صورتی که از مک استفاده می کنید می توانید با استفاده از دستور زیر اقدام به نصب selenium کنید.

brew install selenium-server-standalone

در مرحله بعد باید با دستور زیر اقدام به نصب Nightwatch کنید. همان طور که می بینید با استفاده از کلمه کلیدی global، آن را به صورت سراسری نصب می کنیم.

npm install --global nightwatch

با انجام اینکار می توانید در هر مسیری که خواستید از Nightwatch به راحتی استفاده کنید. همچنین باید یک فایل پیکربندی به نام Nightwatch.json (یا Nightwatch.conf.js) در مسیر روت پروژه ایجاد کنید. در این فایل پیکربندی های پیش فرض پروژه را می نویسیم.

برای ساخت این فایل دستور زیر را در ترمینال وارد کنید.

touch nightwatch.json

سپس کدهای زیر را در این فایل قرار دهید:

{
  "src_folders" : ["tests"],
  "output_folder" : "reports",

  "selenium" : {
    "start_process" : false,
    "server_path" : "",
    "log_path" : "",
    "host" : "127.0.0.1",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "",
      "webdriver.ie.driver" : ""
    }
  },

  "test_settings" : {
    "default" : {
      "launch_url" : "http://localhost:3000",
      "selenium_port"  : 4444,
      "selenium_host"  : "localhost",
      "silent": true,
      "screenshots" : {
        "enabled" : false,
        "path" : ""
      },
      "desiredCapabilities": {
        "browserName": "chrome",
        "javascriptEnabled": true,
        "acceptSslCerts": true
      }
    },

    "chrome" : {
      "desiredCapabilities": {
        "browserName": "chrome",
        "javascriptEnabled": true,
        "acceptSslCerts": true
      }
    }
  }
}

Nightwatch تنظیمات زیادی برای پیکربندی دارد که ما قصد نداریم به تمام آنها بپردازیم. در این درس، تنها به تنظیمات پایه ای که برای یکپارچه کردن تست با برنامه نیاز است، می پردازیم.

نوشتن تست ها

تست های Nightwatch مان را در دایرکتوری tests می نویسیم. حال می خواهیم یک تست برای مدیریت چرخه احراز هویت بنویسیم. برای شروع یک فایل به نام auth-flow.js  در دایرکتوری test ایجاد می کنیم.

mkdir tests
touch tests/auth-flow.js

تست های Nightwatch را می توان به عنوان آبجکت export کرد که در این صورت کلید (key) این آبجکت ها، توضیحات تست و مقدار (value) آنها، یک تابع است که به مرورگر کلاینت ها ارجاع دارد.

برای مثال، در زیر چهار تست برای فایل test/auth-flow.js ایجاد می کنیم.

کدهای زیر را در فایل test/auth-flow.js قرار دهید.

module.exports = {
  'get to login page': (browser) => {},
  'logging in': (browser) => {},
  'logging out': (browser) => {},
  'close': (browser) => {},
}

هر کدام از این توابعی که در آبجکت ها قرار دارند، یک نمونه از browser را به عنوان پارامتر دریافت می کنند که این نمونه browser در حقیقت به عنوان رابط بین تست ها و درایور وب selenium عمل می کند.

سپس می توانیم تنظیمات مختلفی را روی متغیر browser اجرا کنیم.

حال با نوشتن اولین تست با این قابلیت آشنا می شویم. قصد داریم Nightwatch را طوری تنظیم کنیم تا یک صفحه را اجرا کرده و سپس روی لینک login در نوار منو کلیک کند. برای انجام اینکار باید مراحل زیر را انجام دهیم:

  • ابتدا با فراخوانی متد ()url روی browser آدرس مورد نظرمان را دریافت می کنیم.
  • صبر می کنیم تا صفحه بعد از مدتی لود شود.
  • سپس لینک login را یافته و روی آن کلیک می کنیم.

برای شروع با استفاده از متغیر browser آدرسی که در فایل پیکربندی تنظیم کرده ایم را لود می کنیم (در این مثال آدرس http://localhost:3000 است).

module.exports = {
  'get to login page': (browser) => {
    browser
      // Load the page at the launch URL
      .url(browser.launchUrl)
      // wait for page to load
      .waitForElementVisible('.navbar', 1000)
      // click on the login link
      .click('a[href="#/login"]')

    browser.assert.urlContains('login');
  },
  'logging in': (browser) => {},
  'logging out': (browser) => {},
  'close': (browser) => {},
}

قبل از ادامه کار، ابتدا این تست را اجرا می کنیم تا از صحت تنظیمات آن مطمئن شویم. برای اینکار باید سه پنجره ترمینال را باز کنیم.

در پنجره ترمینال اولی، باید selenium را اجرا کنیم. اگر فایل jar. را دانلود کرده اید، با دستور زیر آن را اجرا کنید.

java -jar selenium-server-standalone-{VERSION}.jar

اما اگر با homebrew آنرا دانلود کرده اید، با دستور زیر آن را اجرا کنید:

selenium-server
اجرای selenium-server
اجرای selenium-server

در پنجره دومی، باید برنامه تان را اجرا کنید. توجه داشته باشید که browserیی که قصد اجرای آن را داریم، باید با وب سایت مان کار کند، بنابراین نیاز است که یک نمونه از برنامه مان را در حال اجرا داشته باشیم. برای اینکار با دستور زیر برنامه را اجرا می کنیم.

npm start
اجرای برنامه
اجرای برنامه

در پنجره سومی، با استفاده از دستور Nightwatch اولین تست خود را اجرا خواهیم کرد:

nightwatch

اجرای Nightwatch

هنگام اجرای دستور Nightwatch، پنجره مرورگر chrome بالا می آید، سپس برنامه به طور خودکار وارد سایت شده و روی لینک login کلیک می کند.

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

بعد از اینکه مرحله اول اجرا شد، مرورگر باید به صفحه login مراجعه کند. در دومین مرحله این پروسه، باید مراحل زیر را انجام دهیم:

  • باید فیلد input مربوط به ایمیل را یافته و یک مقدار ایمیل معتبر را به آن نسبت بدهیم
  • سپس روی دکمه submit / login کلیک کنیم
  • صبر می کنیم تا صفحه لود شود (شبیه کاری که در مرحله قبلی انجام دادیم)
  • باید مطمئن شویم متن صفحه برابر با چیزی است که انتظارش را داریم
  • از طرف دیگر باید دقت کنیم که آدرس url همان چیزی است که انتظارش را داریم

برای انجام کارهای فوق، کدهای زیر را می نویسیم:

module.exports = {
  'get to login page': (browser) => {
    browser
      .url(browser.launchUrl)
      .waitForElementVisible('.navbar', 1000)
      .click('a[href="#/login"]')

    browser.assert.urlContains('login');
  },
  'logging in': (browser) => {
    browser
      // set the input email to a valid email
      .setValue('input[type=email]', 'ari@fullstack.io')
      // submit the form
      .click('input[type=submit]')
      // wait for the page to load
      .waitForElementVisible('.navbar', 1000)
      // Get the text of the h1 tag
      .getText('.content h1', function(comp) {
        this.assert.equal(comp.value, 'Welcome home!')
      })

    browser.assert.urlContains(browser.launchUrl)
  },
  'logging out': (browser) => {},
  'close': (browser) => {},
}

تست را مجدداً اجرا کنید ( در پنجره ترمینال سوم)

nightwatch
اجرای یک تست در Nightwatch
اجرای یک تست در Nightwatch

همین مراحل را می توانیم برای خروج از سایت (logging out) هم بنویسیم. برای log out کردن یک کاربر باید مراحل زیر را انجام دهیم:

  • لینک log out را یافته و روی آن کلیک کنیم
  • صبر می کنیم تا محتوای صفحه بعدی لود شود (که یک دکمه با عنوان "?are you sure" نمایش داده می شود)
  • روی "I'm sure" کلیک کرده تا log out شویم
  • مجددا صبر می کنیم تا صفحه لود شود
  • باید مطمئن می شویم که متن تگ h1 برابر چیزی است که انتظار آن را داریم
  • و باید مطمئن شویم که دکمه login در صفحه نمایش داده می شود

برای پیاده کردن این مراحل، کدهای زیر را می نویسیم:

module.exports = {
  'get to login page': (browser) => {
    browser
      .url(browser.launchUrl)
      .waitForElementVisible('.navbar', 1000)
      .click('a[href="#/login"]')

    browser.assert.urlContains('login');
  },
  'logging in': (browser) => {
    browser
      .setValue('input[type=email]', 'ari@fullstack.io')
      .click('input[type=submit]')
      .waitForElementVisible('.navbar', 1000)
      .getText('.content h1', function(comp) {
        this.assert.equal(comp.value, 'Welcome home!')
      })

    browser.assert.urlContains(browser.launchUrl)
  },
  'logging out': (browser) => {
    browser
      // Find and click on the logout link
      .click('a[href="#/logout"]')
      // Wait for the content to load
      .waitForElementVisible('.content button', 1000)
      // Click on the button to logout
      .click('button')
      // We'll wait for the next content to load
      .waitForElementVisible('h1', 1000)
      // Get the text of the h1 tag
      .getText('h1', function(res) {
        this.assert.equal(res.value, 'Welcome home!')
      })
      // Make sure the Login button shows now
      .waitForElementVisible('a[href="#/login"]', 1000);
  },
  'close': (browser) => {},
}

همان طور که می بینید، هنگامی که تست کامل شد، مرورگر کروم به طور خودکار بسته نمی شود، و اینکار به این دلیل است که ما به selenium نگفتیم که به session خاتمه دهد. برای انجام اینکار باید متد ()end را روی آبجکت browser اجرا کرده تا ارتباط قطع شود:

{
  // ...
  'close': (browser) => browser.end()
}

حال تست های فوق را به طور کامل اجرا می کنیم تا از صحت کارکرد آن مطمئن شویم:

nightwatch
اجرای برنامه با Nightwatch
اجرای برنامه با Nightwatch

در صورتی که قصد داشتید اطلاعات بیشتری درباره selenium داشته باشید می توانید به آموزش رایگانی که در وب سایت https://www.guru99.com/selenium-tutorial.html قرار دارد مراجعه کنید. در این وب سایت آموزش های خوب و کاربردی برای کار با Selenium وجود دارد.

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

حال می توانیم مطمئن شویم که برنامه مان برای انتشار آماده شده است.

اما هنوز به مرحله انتشار یک وب سایت نپرداختیم. در درس آینده به انتشار یک برنامه در محیط ابری یا کلود می پردازیم.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش react (ری اکت) توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.