ব্যবসার সরঞ্জাম

স্বয়ংক্রিয় পরীক্ষাগুলি মৌলিকভাবে কেবলমাত্র কোড যা কিছু ভুল হলে নিক্ষেপ করবে বা ত্রুটি সৃষ্টি করবে। বেশিরভাগ লাইব্রেরি বা টেস্টিং ফ্রেমওয়ার্কগুলি বিভিন্ন ধরণের আদিম প্রদান করে যা পরীক্ষাগুলিকে লিখতে সহজ করে তোলে।

পূর্ববর্তী বিভাগে উল্লিখিত হিসাবে, এই আদিম প্রায় সবসময় স্বাধীন পরীক্ষা সংজ্ঞায়িত করার একটি উপায় অন্তর্ভুক্ত করে ( পরীক্ষার ক্ষেত্রে বলা হয়) এবং দাবী প্রদানের জন্য। দাবী হল একটি ফলাফল পরীক্ষা করা এবং কিছু ভুল হলে একটি ত্রুটি নিক্ষেপ করা একত্রিত করার একটি উপায়, এবং এটিকে সমস্ত পরীক্ষার আদিম প্রাথমিক হিসাবে বিবেচনা করা যেতে পারে।

এই পৃষ্ঠাটি এই আদিম বিষয়গুলির একটি সাধারণ পদ্ধতির কভার করে৷ আপনার নির্বাচিত ফ্রেমওয়ার্ক সম্ভবত এই মত কিছু আছে, কিন্তু এটি একটি সঠিক রেফারেন্স নয়.

উদাহরণ স্বরূপ:

import { fibonacci, catalan } from '../src/math.js';
import { assert, test, suite } from 'a-made-up-testing-library';

suite('math tests', () => {
  test('fibonacci function', () => {
    // check expected fibonacci numbers against our known actual values
    // with an explanation if the values don't match
    assert.equal(fibonacci(0), 0, 'Invalid 0th fibonacci result');
    assert.equal(fibonacci(13), 233, 'Invalid 13th fibonacci result');
  });
  test('relationship between sequences', () => {
    // catalan numbers are greater than fibonacci numbers (but not equal)
    assert.isAbove(catalan(4), fibonacci(4));
  });
  test('bugfix: check bug #4141', () => {
    assert.isFinite(fibonacci(0)); // fibonacci(0) was returning NaN
  })
});

এই উদাহরণটি পরীক্ষার একটি গ্রুপ তৈরি করে (কখনও কখনও একটি স্যুট বলা হয়) যাকে "গণিত পরীক্ষা" বলা হয়, এবং তিনটি স্বাধীন পরীক্ষার ক্ষেত্রে সংজ্ঞায়িত করে যে প্রতিটিতে কিছু দাবি করা হয়। এই পরীক্ষার ক্ষেত্রে সাধারণত পৃথকভাবে সম্বোধন করা যেতে পারে বা চালানো যেতে পারে, উদাহরণস্বরূপ, আপনার পরীক্ষার রানারে একটি ফিল্টার পতাকা দ্বারা।

আদিম হিসাবে দাবী সাহায্যকারী

Vitest সহ বেশিরভাগ টেস্টিং ফ্রেমওয়ার্কের মধ্যে একটি assert অবজেক্টে অ্যাসার্টেশন হেল্পারদের একটি সংগ্রহ অন্তর্ভুক্ত থাকে যা আপনাকে কিছু প্রত্যাশার বিপরীতে দ্রুত রিটার্ন মান বা অন্যান্য অবস্থা পরীক্ষা করতে দেয়। যে প্রত্যাশা প্রায়ই "পরিচিত ভাল" মান. আগের উদাহরণে, আমরা জানি 13তম ফিবোনাচি সংখ্যাটি 233 হওয়া উচিত, তাই আমরা সরাসরি assert.equal ব্যবহার করে নিশ্চিত করতে পারি।

আপনি এমনও আশা করতে পারেন যে একটি মান একটি নির্দিষ্ট রূপ নেয়, বা অন্য মানের থেকে বড়, বা অন্য কিছু সম্পত্তি আছে। এই কোর্সটি সম্ভাব্য দাবী সহায়কদের সম্পূর্ণ পরিসরকে কভার করবে না , তবে পরীক্ষার কাঠামো সর্বদা কমপক্ষে নিম্নলিখিত মৌলিক পরীক্ষাগুলি প্রদান করে:

  • একটি 'সত্য' চেক, প্রায়শই 'ঠিক আছে' চেক হিসাবে বর্ণনা করা হয়, একটি শর্ত সত্য কিনা তা পরীক্ষা করে, আপনি কীভাবে একটি লিখতে পারেন তার সাথে মিলে যায় if এটি পরীক্ষা করে যে কিছু সফল বা সঠিক। এটি assert(...) বা assert.ok(...) হিসাবে প্রদান করা হয়, এবং একটি একক মান এবং একটি ঐচ্ছিক মন্তব্য নেয়।

  • একটি সমতা পরীক্ষা, যেমন গণিত পরীক্ষার উদাহরণে, যেখানে আপনি আশা করেন যে কোনো বস্তুর রিটার্ন মান বা অবস্থা একটি পরিচিত ভালো মানের সমান হবে। এগুলি আদিম সমতার জন্য (যেমন সংখ্যা এবং স্ট্রিংগুলির জন্য) বা রেফারেন্সিয়াল সমতা (এগুলি একই বস্তু)। হুডের নীচে, এগুলি একটি == বা === তুলনা সহ একটি 'সত্য' চেক।

    • জাভাস্ক্রিপ্ট আলগা ( == ) এবং কঠোর ( === ) সমতার মধ্যে পার্থক্য করে। বেশিরভাগ পরীক্ষার লাইব্রেরি আপনাকে যথাক্রমে assert.equal এবং assert.strictEqual পদ্ধতিগুলি প্রদান করে।
  • গভীর সমতা পরীক্ষা, যা বস্তু, অ্যারে এবং অন্যান্য জটিল ডেটা প্রকারের বিষয়বস্তু পরীক্ষা করার পাশাপাশি বস্তুগুলিকে তুলনা করার জন্য অভ্যন্তরীণ যুক্তির সাথে সমতা যাচাইকে প্রসারিত করে। এগুলি গুরুত্বপূর্ণ কারণ জাভাস্ক্রিপ্টে দুটি অবজেক্ট বা অ্যারের বিষয়বস্তুর তুলনা করার কোনও অন্তর্নির্মিত উপায় নেই। উদাহরণস্বরূপ, [1,2,3] == [1,2,3] সর্বদা মিথ্যা। টেস্ট ফ্রেমওয়ার্ক প্রায়ই deepEqual বা deepStrictEqual সাহায্যকারী অন্তর্ভুক্ত করে।

দাবী সহায়ক যারা দুটি মান তুলনা করে (শুধুমাত্র একটি 'সত্য' চেকের পরিবর্তে) সাধারণত দুটি বা তিনটি যুক্তি গ্রহণ করে:

  • প্রকৃত মান, পরীক্ষার অধীনে কোড থেকে তৈরি করা বা যাচাই করার জন্য রাষ্ট্রের বর্ণনা।
  • প্রত্যাশিত মান, সাধারণত হার্ড কোডেড (উদাহরণস্বরূপ, একটি আক্ষরিক সংখ্যা বা স্ট্রিং)।
  • কী প্রত্যাশিত বা কী ব্যর্থ হয়েছে তা বর্ণনা করে একটি ঐচ্ছিক মন্তব্য, যা এই লাইন ব্যর্থ হলে অন্তর্ভুক্ত করা হবে।

বিভিন্ন চেক তৈরি করার জন্য দাবীগুলিকে একত্রিত করা মোটামুটি সাধারণ অভ্যাস, কারণ এটি বিরল যে কেউ নিজেই আপনার সিস্টেমের অবস্থা সঠিকভাবে নিশ্চিত করতে পারে। উদাহরণ স্বরূপ:

  test('JWT parse', () => {
    const json = decodeJwt('eyJieSI6InNhbXRob3Ii…');

    assert.ok(json.payload.admin, 'user should be admin');
    assert.deepEqual(json.payload.groups, ['role:Admin', 'role:Submitter']);
    assert.equal(json.header.alg, 'RS265')
    assert.isAbove(json.payload.exp, +new Date(), 'expiry must be in future')
  });

Vitest তার দাবী সাহায্যকারী প্রদান করতে অভ্যন্তরীণভাবে Chai assertion লাইব্রেরি ব্যবহার করে, এবং আপনার কোডের সাথে কোন দাবী এবং সাহায্যকারীরা মানানসই হতে পারে তা দেখতে এটির রেফারেন্সটি দেখার জন্য এটি কার্যকর হতে পারে।

সাবলীল এবং BDD দাবী

কিছু বিকাশকারী একটি দাবী শৈলী পছন্দ করেন যেটিকে আচরণ-চালিত উন্নয়ন (BDD), বা সাবলীল -স্টাইল দাবী বলা যেতে পারে। এগুলিকে "প্রত্যাশা" সাহায্যকারীও বলা হয়, কারণ প্রত্যাশা পরীক্ষা করার এন্ট্রি পয়েন্ট হল expect() নামে একটি পদ্ধতি।

assert.ok বা assert.strictDeepEquals এর মতো সাধারণ পদ্ধতির কল হিসাবে লেখা দাবীগুলির মতো সাহায্যকারীরা একইভাবে আচরণ করবেন বলে আশা করুন, তবে কিছু বিকাশকারী তাদের পড়া সহজ বলে মনে করেন। একটি BDD দাবী নিম্নলিখিত মত পড়তে পারে:

// A failure here would generate "Expect result to be an array that does include 42"
const result = await possibleMeaningsOfLife();
expect(result).to.be.an('array').that.does.include(42);

// or a simpler form
expect(result).toBe('array').toContainEqual(42);

// the same in assert might be
assert.typeOf(result, 'array', 'Expected the result to be an array');
assert.include(result, 42, 'Expected the result to include 42');

এই ধরনের দাবী করার ধরন কাজ করে মেথড চেইনিং নামক একটি কৌশলের কারণে, যেখানে expect মাধ্যমে ফিরে আসা বস্তুটিকে আরও মেথড কলের সাথে ক্রমাগত চেইন করা যায়। আগের উদাহরণে to.be এবং that.does সহ কলের কিছু অংশের কোন কার্যকারিতা নেই এবং শুধুমাত্র কলটি পড়া সহজ করতে এবং পরীক্ষা ব্যর্থ হলে একটি স্বয়ংক্রিয় মন্তব্য তৈরি করার জন্য এটি অন্তর্ভুক্ত করা হয়েছে। (উল্লেখ্যভাবে, expect সাধারণত একটি ঐচ্ছিক মন্তব্য সমর্থন করে না, কারণ চেইনিংটি ব্যর্থতাকে স্পষ্টভাবে বর্ণনা করা উচিত।)

অনেক পরীক্ষার ফ্রেমওয়ার্ক ফ্লুয়েন্ট/বিডিডি এবং নিয়মিত দাবী উভয়কেই সমর্থন করে। Vitest, উদাহরণস্বরূপ , Chai এর উভয় পন্থা রপ্তানি করে এবং BDD-তে এর নিজস্ব কিছুটা সংক্ষিপ্ত পদ্ধতি রয়েছে। অন্য দিকে জেস্ট, ডিফল্টরূপে শুধুমাত্র একটি প্রত্যাশা পদ্ধতি অন্তর্ভুক্ত করে।

ফাইল জুড়ে গ্রুপ পরীক্ষা

পরীক্ষা লেখার সময়, আমরা ইতিমধ্যেই অন্তর্নিহিত গ্রুপিং প্রদান করার প্রবণতা রাখি—সমস্ত পরীক্ষাগুলি এক ফাইলে থাকার পরিবর্তে, একাধিক ফাইল জুড়ে পরীক্ষা লেখা সাধারণ। প্রকৃতপক্ষে, পরীক্ষার দৌড়বিদরা সাধারণত জানেন যে একটি ফাইল একটি পূর্বনির্ধারিত ফিল্টার বা রেগুলার এক্সপ্রেশনের কারণে পরীক্ষার জন্য-উদাহরণস্বরূপ, আপনার প্রকল্পের সমস্ত ফাইল অন্তর্ভুক্ত করে যা ".test.jsx" বা ".spec" এর মত একটি এক্সটেনশন দিয়ে শেষ হয় .ts" (."test" এবং ".spec" প্লাস বেশ কিছু বৈধ এক্সটেনশন)।

কম্পোনেন্ট পরীক্ষাগুলি নিম্নোক্ত ডিরেক্টরি কাঠামোর মতো, পরীক্ষার অধীনে উপাদানের একটি পিয়ার ফাইলে অবস্থিত হতে থাকে:

UserList.tsx এবং UserList.test.tsx সহ একটি ডিরেক্টরির ফাইলগুলির একটি তালিকা।
একটি উপাদান ফাইল এবং সম্পর্কিত পরীক্ষা ফাইল।

একইভাবে, ইউনিট পরীক্ষাগুলি পরীক্ষার অধীনে কোডের পাশে স্থাপন করা হয়। এন্ড-টু-এন্ড পরীক্ষা প্রতিটি তাদের নিজস্ব ফাইলে হতে পারে, এবং ইন্টিগ্রেশন পরীক্ষা এমনকি তাদের নিজস্ব অনন্য ফোল্ডারে স্থাপন করা যেতে পারে। এই কাঠামোগুলি সহায়ক হতে পারে যখন জটিল পরীক্ষার ক্ষেত্রে তাদের নিজস্ব নন-টেস্ট সমর্থন ফাইলের প্রয়োজন হয়, যেমন সমর্থন লাইব্রেরিগুলি শুধুমাত্র একটি পরীক্ষার জন্য প্রয়োজন।

ফাইলের মধ্যে গ্রুপ পরীক্ষা

পূর্বের উদাহরণে যেমন ব্যবহার করা হয়েছে, এটি একটি সাধারণ অভ্যাস যা একটি কল টু suite() এর মধ্যে পরীক্ষা করা যা আপনি test() দিয়ে সেট আপ করা পরীক্ষাগুলিকে গোষ্ঠীভুক্ত করে। স্যুটগুলি সাধারণত নিজেরাই পরীক্ষা করে না, তবে তারা পাস করা পদ্ধতিতে কল করে সম্পর্কিত পরীক্ষা বা লক্ষ্যগুলিকে গোষ্ঠীবদ্ধ করে কাঠামো সরবরাহ করতে সহায়তা করে। test() এর জন্য, পাস করা পদ্ধতিটি নিজেই পরীক্ষার ক্রিয়া বর্ণনা করে।

দাবীর মতো, গ্রুপিং টেস্টের সাথে ফ্লুয়েন্ট/বিডিডি-তে মোটামুটি আদর্শ সমতা রয়েছে। কিছু সাধারণ উদাহরণ নিম্নলিখিত কোডে তুলনা করা হয়:

// traditional/TDD
suite('math tests', () => {
  test('handle zero values', () => {
    assert.equal(fibonacci(0), 0);
  });
});

// Fluent/BDD
describe('math tests', () => {
  it('should handle zero values', () => {
    expect(fibonacci(0)).toBe(0);
  });
})

বেশিরভাগ ফ্রেমওয়ার্কে, suite এবং describe একইভাবে আচরণ করে, যেমন করে test এবং it , assertions লিখতে expect এবং assert ব্যবহার করার মধ্যে বৃহত্তর পার্থক্যের বিপরীতে।

অন্যান্য সরঞ্জামগুলিতে স্যুট এবং পরীক্ষার ব্যবস্থা করার জন্য সূক্ষ্মভাবে ভিন্ন পদ্ধতি রয়েছে। উদাহরণ স্বরূপ, Node.js-এর বিল্ট-ইন টেস্ট রানার পরোক্ষভাবে একটি পরীক্ষার শ্রেণিবিন্যাস তৈরি করতে test() এ নেস্টিং কল সমর্থন করে। যাইহোক, Vitest শুধুমাত্র suite() ব্যবহার করে এই ধরনের নেস্টিংয়ের অনুমতি দেয় এবং অন্য test() এর ভিতরে সংজ্ঞায়িত test() চালাবে না।

দাবীর মতই, মনে রাখবেন যে আপনার টেক স্ট্যাক যে গ্রুপিং পদ্ধতিগুলি প্রদান করে তার সঠিক সংমিশ্রণটি ততটা গুরুত্বপূর্ণ নয় ৷ এই কোর্সটি সেগুলিকে বিমূর্ত আকারে কভার করবে, তবে আপনার পছন্দের সরঞ্জামগুলিতে তারা কীভাবে প্রযোজ্য তা আপনাকে খুঁজে বের করতে হবে।

জীবনচক্র পদ্ধতি

আপনার পরীক্ষাগুলিকে গোষ্ঠীবদ্ধ করার একটি কারণ, এমনকি একটি ফাইলের মধ্যে শীর্ষ স্তরে অন্তর্নিহিতভাবে, সেটআপ এবং টিয়ারডাউন পদ্ধতিগুলি প্রদান করা যা প্রতিটি পরীক্ষার জন্য বা একবার পরীক্ষার জন্য চলে। বেশিরভাগ ফ্রেমওয়ার্ক চারটি পদ্ধতি প্রদান করে:

প্রতিটি `পরীক্ষা()` বা `এটি()` এর জন্য একবার স্যুটের জন্য
টেস্ট রানের আগে `প্রত্যেক আগে()` `সকলের আগে()`
টেস্ট রানের পর `পরে প্রতিটি()` `আফটারঅল()`

উদাহরণস্বরূপ, আপনি প্রতিটি পরীক্ষার আগে একটি ভার্চুয়াল ব্যবহারকারী ডাটাবেস প্রস্তুত করতে চাইতে পারেন এবং পরে এটি সাফ করতে পারেন:

suite('user test', () => {
  beforeEach(() => {
    insertFakeUser('bob@example.com', 'hunter2');
  });
  afterEach(() => {
    clearAllUsers();
  });

  test('bob can login', async () => { … });
  test('alice can message bob', async () => { … });
});

এটি আপনার পরীক্ষা সহজ করতে দরকারী হতে পারে. আপনি প্রতিটি পরীক্ষায় এটির নকল না করে সাধারণ সেটআপ এবং টিয়ারডাউন কোড শেয়ার করতে পারেন। অতিরিক্তভাবে, যদি সেটআপ এবং টিয়ারডাউন কোড নিজেই একটি ত্রুটি ছুঁড়ে দেয়, তবে এটি কাঠামোগত সমস্যাগুলি নির্দেশ করতে পারে যা পরীক্ষাগুলি ব্যর্থ হওয়াকে জড়িত করে না।

সাধারণ উপদেশ

এই আদিম সম্পর্কে চিন্তা করার সময় মনে রাখার জন্য এখানে কয়েকটি টিপস রয়েছে।

আদিম একটি গাইড

মনে রাখবেন যে এখানকার টুল এবং আদিম, এবং পরবর্তী কয়েকটি পৃষ্ঠায়, Vitest, বা Jest, বা Mocha, বা Web Test Runner, বা অন্য কোন নির্দিষ্ট কাঠামোর সাথে হুবহু মিলবে না। যদিও আমরা Vitest কে একটি সাধারণ নির্দেশিকা হিসাবে ব্যবহার করেছি, সেগুলিকে আপনার পছন্দের কাঠামোতে ম্যাপ করতে ভুলবেন না৷

মিশ্রিত করুন এবং প্রয়োজন হিসাবে দাবী মিলান

পরীক্ষাগুলি মৌলিকভাবে কোড যা ত্রুটি নিক্ষেপ করতে পারে। প্রতিটি রানার একটি আদিম, সম্ভাব্য test() প্রদান করবে, যা স্বতন্ত্র পরীক্ষার ক্ষেত্রে বর্ণনা করবে।

কিন্তু যদি সেই রানার assert() , expect() এবং assertion helpers প্রদান করে, তাহলে মনে রাখবেন যে এই অংশটি সুবিধার বিষয়ে আরও বেশি এবং আপনার প্রয়োজন হলে আপনি এটি এড়িয়ে যেতে পারেন। আপনি যেকোন কোড চালাতে পারেন যা অন্য অ্যাসারশন লাইব্রেরি সহ একটি ত্রুটি ছুঁড়তে পারে, অথবা একটি ভাল-পুরনো-ফ্যাশন if স্টেটমেন্ট সহ।

IDE সেটআপ একটি জীবন রক্ষাকারী হতে পারে

আপনার আইডিই, VSCode-এর মতো, আপনার নির্বাচিত টেস্ট টুলিং-এ স্বয়ংসম্পূর্ণতা এবং ডকুমেন্টেশনের অ্যাক্সেস রয়েছে তা নিশ্চিত করা আপনাকে আরও উত্পাদনশীল করে তুলতে পারে। উদাহরণ স্বরূপ, Chai assertion লাইব্রেরীতে assert টিরও বেশি পদ্ধতি আছে এবং সঠিক একটির জন্য ডকুমেন্টেশন ইনলাইনে দেখানো সুবিধাজনক হতে পারে।

এটি কিছু পরীক্ষার ফ্রেমওয়ার্কের জন্য বিশেষভাবে গুরুত্বপূর্ণ হতে পারে যেগুলি তাদের পরীক্ষার পদ্ধতিগুলির সাথে বিশ্বব্যাপী নামস্থানকে পপুলেট করে। এটি একটি সূক্ষ্ম পার্থক্য, তবে প্রায়শই টেস্টিং লাইব্রেরিগুলিকে আমদানি না করে ব্যবহার করা সম্ভব যদি সেগুলি স্বয়ংক্রিয়ভাবে গ্লোবাল নেমস্পেসে যুক্ত হয়:

// some.test.js
test('using test as a global', () => { … });

আমরা সাহায্যকারীদের আমদানি করার সুপারিশ করি যদিও তারা স্বয়ংক্রিয়ভাবে সমর্থিত হয়, কারণ এটি আপনার IDE-কে এই পদ্ধতিগুলি সন্ধান করার একটি পরিষ্কার উপায় দেয়। (প্রতিক্রিয়া তৈরি করার সময় আপনি এই সমস্যাটি অনুভব করতে পারেন, কারণ কিছু কোডবেসে একটি জাদুকরী React গ্লোবাল থাকে, তবে কিছুতে নেই এবং এটিকে প্রতিক্রিয়া ব্যবহার করে সমস্ত ফাইলে আমদানি করতে হবে।)

// some.test.js
import { test } from 'vitest';
test('using test as an import', () => { … });