برنامه نویسی

سرو-پیکربندی آسان چند منظوره

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

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

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

راه حل های جایگزین:

به صورت دستی cypress.config.js را به روز کنیدبشر

کمترین بهینه ترین رویکرد به روزرسانی دستی است cypress.config.js هر بار که یک محیط متفاوت مورد نیاز است.

با نگاهی به یک فایل پیکربندی ساده در زیر ، برای یک محیط محلی ، کاربر نیاز به تغییر دارد baseUrl و هر دو متغیر خاص ENV فقط در صورت تمایل به اجرای مجدد محلی ، باید آنها را تغییر دهند. با افزایش این پرونده و تنظیمات و متغیرهای بیشتر در محیط ها متفاوت است ، به روز کردن دستی این پرونده هر بار نه تنها مالیات بلکه غیر عملی است.

const { defineConfig } = require('cypress')
require('dotenv').config({ path: '../.env' })

module.exports = defineConfig({
    e2e: {
        setupNodeEvents(on, config) {
            return require('./cypress/plugins/index')(on, config)
        },
        baseUrl: 'http://127.0.0.1:8009/',
    },
    env: {
        MY_USER: process.env.MY_LOCAL_USER,
        MY_PASSWORD: process.env.MY_LOCAL_PASSWORD,
    },
})
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

جوانب مثبت:

  • سریع برای یک راه حل یک بار

منفی ها:

  • ادغام تغییرات بر همه تأثیر می گذارد
  • تکراری و وقت گیر
  • اجرای CI/CD را محدود می کند

گزینه های خط فرمانبشر

رویکرد دیگر استفاده از CLI با غلبه بر هرگونه تنظیمات پیش فرض یا متغیرها با پارامترها است. این راه حل به کاربران امکان می دهد چندین فرمان اجرا را تعریف کنند ، هرکدام با غلبه خاصی برای آن محیط.

در مثال زیر ، دو دستور اسکریپت در package.json پرونده از آنجا که cypress.config.js پرونده برای محیط محلی پیکربندی شده است. cy:run فرمان نیازی به اصلاح هر چیزی ندارد. با این حال ، cy:run:dev فرمان هر دو را تحت الشعاع قرار می دهد baseUrl و متغیرهای محیطی با استفاده از --config وت --env گزینه ها

"cy:run": "cypress run",
"cy:run:dev": "cypress run --config baseUrl=https://myDevURL, --env MY_USER=some-dev-user,MY_PASSWORD=some-dev-password"
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

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

علاوه بر این ، توصیه نمی شود رازهای موجود در package.json بنابراین این رویکرد آنچه را که متغیرهای محیطی می توانند نادیده بگیرند محدود می کند.

جوانب مثبت:

  • برای تفاوت های کوچک محیطی مفید است
  • از سوئیچینگ سریع محیط پشتیبانی کنید
  • کتابچه راهنمای کاربر کمتر

منفی ها:

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

شرط آزمایش

در حالی که هر دو راه حل فوق برای اختلافات کوچک محیطی کار می کنند ، در مورد محیط هایی که بین آنها تفاوت زیادی دارند ، چه می شود؟

یک راه برای رسیدگی package.json دستورات و در عوض در یک محیط واحد عبور می کنند ، متغیر مانند ENVIRONMENT

"cy:run": "cypress run",
"cy:run:dev": "cypress run --env ENVIRONMENT=development",
"cy:run:qa": "cypress run --env ENVIRONMENT=qa",
"cy:run:uat": "cypress run --env ENVIRONMENT=uat",
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون منطق مشروط را می توان در مجموعه تست با انجام اجرا کرد Cypress.env('ENVIRONMENT') برای دسترسی به متغیر بیایید نگاهی به یک آزمایش اساسی در تلاش برای ورود به سیستم و تجزیه آن بیندازیم.

const getUrl = () => {
    switch (Cypress.env('ENVIRONMENT')) {
        case 'local':
            return 'http://127.0.0.1:8009/'
        case 'development':
            return 'my-dev-url/'
        case 'qa':
            return 'my-qa-url/'
        case 'uat':
            return 'my-uat-url/'
        default:
            break
    }
}
const setEnvVariables = () => {
    switch (Cypress.env.ENVIRONMENT) {
        case 'local':
            Cypress.env('MY_USER', 'some user')
            Cypress.env('MY_PASSWORD', 'some password')
        case 'development':
            Cypress.env('MY_USER', 'some dev user')
            Cypress.env('MY_PASSWORD', 'some dev password')
        case 'qa':
            Cypress.env('MY_USER', 'some qa user')
            Cypress.env('MY_PASSWORD', 'some qa password')
        case 'uat':
            Cypress.env('MY_USER', 'some uat user')
            Cypress.env('MY_PASSWORD', 'some uat password')
        default:
            break
    }
}

describe('My Test Suite', () => {
    beforeEach(() => {
        setEnvVariables()
    })

    it('Basic Test', () => {
        // Visit
        cy.visit(getUrl())

        // Login
        cy.get('login-user-input').type(Cypress.env('MY_USER'))
        cy.get('login-password-input').type(Cypress.env('MY_PASSWORD'))
    })
})
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

با استفاده از منطق مشروط سوئیچ/مورد ، ما قادر به بررسی گذرگاه هستیم ENVIRONMENT گزینه و داده های URL صحیح و احراز هویت را در خود آزمون تنظیم کنید.

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

جوانب مثبت:

  • CLI را ساده می کند
  • اطلاعات خاص محیط را نزدیک به کد آزمون حرکت می دهد

منفی ها:

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

راه حل بهینه

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

اینگونه کار می کند

  • در cypress.config.js پرونده برای هر دو تنظیمات جهانی در همه محیط ها و همچنین تنظیمات فردی برای بیشترین استفاده از محیط (مانند محلی) تعریف شده است.
  • در dotenv از کتابخانه برای وارد کردن اسرار از محلی استفاده می شود .env پرونده این اسرار با استفاده از process.env.X نحو
const { defineConfig } = require('cypress')
require('dotenv').config({ path: '../.env' })

module.exports = defineConfig({
    e2e: {
        setupNodeEvents(on, config) {
            return require('./cypress/plugins/index')(on, config)
        },
        baseUrl: 'http://127.0.0.1:8009/',
    },
    env: {
        MY_USER: process.env.MY_LOCAL_USERNAME,
        MY_PASSWORD: process.env.MY_LOCAL_PASSWORD,
    },
})
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

  • بعد ، اضافی cypress.config.X.js ایجاد شده اند ، یکی برای هر محیط. این پرونده های پیکربندی فقط آنچه برای آن محیط متفاوت است را تعریف کنید، در حالی که تنظیمات باقیمانده با پخش از پایه به ارث می برند cypress.config.js پرونده

  • بنابراین در مثال زیر ، پایه cypress.config.js پرونده وارد می شود ، QA baseUrl و متغیرهای ورود به سیستم ناپدید می شوند و پیکربندی کلی با گسترش همه چیز به هم تعریف می شود.

const { defineConfig } = require('cypress')
const baseConfig = require('./cypress.config')

const e2eOverride = {
    baseUrl: 'https://my-qa-url.com/',
}
const envOverride = {
    MY_USER: process.env.MY_QA_USERNAME,
    MY_PASSWORD: process.env.MY_QA_PASSWORD,
}

module.exports = defineConfig({
    ...baseConfig,
    e2e: {
        ...baseConfig.e2e,
        ...e2eOverride,
    },
    env: {
        ...baseConfig.env,
        ...envOverride,
    },
})
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

  • سرانجام ، هر محیط دستور اجرای خود را دارد که در یک گزینه CLI واحد عبور می کند config-file
  • توجه کنید که cy:run دستور در یک پرونده پیکربندی عبور نمی کند ، به معنای پیش فرض cypress.config.js استفاده خواهد شد
"cy:run": "cypress run",
"cy:run:dev": "cypress run --config-file cypress.config.dev.js",
"cy:run:qa": "cypress run --config-file cypress.config.qa.js",
"cy:run:uat": "cypress run --config-file cypress.config.uat.js",
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

و همین است.

دویدن در برابر QA به سادگی اجرای آن است cy:run:qa یا cy:run:uat برای یک uat env در حالی که پایه است cy:run فرمان از آزمایش محلی پشتیبانی می کند. من همچنین توصیه می کنم env خاص ایجاد کنید cy:open دستورات استفاده از دونده آزمون در کنار دستورات RUN برای استفاده از CI ، CI/CD.

این الگوی نه تنها تمیز است بلکه اضافه کردن یک محیط جدید به آسانی ایجاد یک دستور جدید و فایل پیکربندی خاص ENV است. علاوه بر این ، اشکال زدایی یا اصلاح هر تنظیمات ساده است ، زیرا تغییرات سطح جهانی به راحتی در پرونده پیکربندی پایه پیچیده می شوند در حالی که تمام تغییرات خاص ENV به طور جداگانه اتفاق می افتد. وارد کردن اسرار مهم از .env پرونده ها نیز امکان پذیر است.

شرح تصویر

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

آزمایش مبارک!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا