আর্টুরো ট্র্যাকে টেস্টিং

Exercism-এ আপনার আর্টুরো অনুশীলনীগুলো কীভাবে টেস্ট করবেন তা শিখুন


Arturo ট্র্যাক সব অনুশীলনীর টেস্টের জন্য Unitt 3.0.0 ইউনিট-টেস্টিং প্যাকেজ ব্যবহার করে। এই প্যাকেজটি এমন একটি টেস্টিং ফ্রেমওয়ার্ক দেয় যা আধুনিক RSpec-অনুপ্রাণিত এবং পুরনো XUnit-অনুপ্রাণিত, দুই ধরনের সিনট্যাক্সই সমর্থন করে। আপনার স্থানীয় অনুশীলনী ফোল্ডারের ভেতর থেকে arturo tester.art বা exercism test রান করলে প্রথমবারেই প্যাকেজটি ইন্টারনেট থেকে ইনস্টল হয়ে যাওয়া উচিত। অথবা arturo --package install unitt 3.0.0 রান করে আপনি Unitt ইনস্টল করতে পারেন। শুধু প্রথম টেস্টটিই রান করা হবে এবং তা আপনাকে রিপোর্ট করা হবে। সেই টেস্ট পাস হয়ে গেলে পরের টেস্টটি আনস্কিপ করুন এবং প্রতিটি টেস্ট পাস না হওয়া পর্যন্ত আবার টেস্ট রান করুন। RSpec আর XUnit, দুটি সেটআপেই কাজটি এতটুকুই: যথাক্রমে it.skip বা test.skip থেকে .skip মুছে ফেলুন। সব টেস্ট পাস হয়ে গেলে আপনার সমাধান সাবমিট করুন, তবে জেনে রাখুন টেস্ট রানার স্কিপ করা টেস্টগুলোসহ সব টেস্টই রান করে।

শুরু করা যাক

আপনার ডাউনলোড করা অনুশীলনী ফোল্ডারে কিছু ফাইল থাকবে, তবে এর মধ্যে এই তিনটি ফাইলই অপরিহার্য।

leap/
├── src/leap.art         # Your solution file
├── tests/test-leap.art  # Test cases for the exercise
└── tester.art           # Test runner entry point

arturo tester.art রান করলে Unitt সেটআপ হয়ে যাবে, তারপর tests/test-leap.art-এর ভেতরের টেস্টগুলো রান হবে। টেস্টগুলো src/leap.art ইমপোর্ট করবে, যেখানে আপনার সমাধান থাকে, আর তারপর নির্দিষ্ট কিছু ইনপুটের জন্য আপনার সমাধানের কী রিটার্ন করা উচিত সে বিষয়ে একের পর এক অ্যাসারশন করবে।

সমাধান ফাইল

isLeap?: function [year][
    panic "please implement the isLeap? function"
]

কোনো অনুশীলনী শুরু করার সময় আপনার সমাধান ফাইলে একটি টেমপ্লেট থাকে, যাতে প্রত্যাশিত কাঠামোর মূল রূপরেখা দেওয়া থাকে। Leap-এর এই উদাহরণে ফাইলটিতে প্রত্যাশিত isLeap? ফাংশনের একটি সাধারণ সংজ্ঞা আছে এবং বিশেষভাবে একটি panic আছে যা টেস্ট চালানো থামিয়ে দেয়। panic লাইনটি মুছে ফেলুন, তারপর isLeap?-এর জন্য আপনার ইমপ্লিমেন্টেশন লিখতে শুরু করুন।

RSpec টেস্ট স্ট্রাকচার

import.version:3.0.0 {unitt}!
import {src/leap}!

describe "Leap" [
    it "a year not divisible by 4 is a common year" [
        expects.be:'false? @[isLeap? 2015]
    ]

    it.skip "a year divisible by 4 and not divisible by 100 is a leap year" [
        expects.be:'true? @[isLeap? 1996]
    ]
]
  • describe এমন একগুচ্ছ টেস্ট কেস নির্ধারণ করে যা কোনো একটি সাধারণ বিষয় যাচাই করে। এগুলো নেস্ট করা যায়।
  • it এবং it.skip দুটিই একটি করে টেস্ট কেস নির্ধারণ করে, যেটি যথাক্রমে রান হয় বা স্কিপ হয়।
  • expects সেই অ্যাসারশনটি শুরু করে, যা একটি টেস্ট কেসের মূল অংশ। expects.be একটি প্রেডিকেট ফাংশন নেয়, যা দিয়ে অ্যাসারশনটি করা হয়।

expects.be:'false? @[isLeap? 2015]-এ টেস্ট স্যুটটি অ্যাসারশন করছে যে 2015 সালের জন্য isLeap? ফাংশনের false রিটার্ন করা উচিত। এটি লেখার আরেকটি উপায় হলো expects.be:'equal? @[false isLeapYear? 2015], যেখানে আমরা অ্যাসারশন করছি যে isLeapYear? 2015-এর রিটার্ন করা মান false-এর সমান। দুটি মান তুলনা করার এই দীর্ঘ রূপটিই Arturo ট্র্যাকে সবচেয়ে বেশি দেখা যায় এমন অ্যাসারশন। ব্লকে প্রত্যাশিত মানটি সবসময় ফলাফল মানের আগে থাকবে।

XUnit টেস্ট স্ট্রাকচার

suite "Leap" [
    test "a year not divisible by 4 is a common year" [
        result: isLeap? 2015
        assert -> false = result
    ]

    test.skip "a year divisible by 4 and not divisible by 100 is a leap year" [
        result: isLeap? 1996
        assert -> true = result
    ]
]

Unitt-এর v1-এ আসা XUnit-সদৃশ API-টি পুরনো সংস্করণের সাথে সামঞ্জস্য রাখার জন্য সমর্থিত, এবং কম নমনীয় অ্যাসারশন ছাড়া বাকি সব দিকেই এটি আধুনিক RSpec-সদৃশ API-এর সমতুল্য।

  • suite এমন একগুচ্ছ টেস্ট কেস নির্ধারণ করে যা কোনো একটি সাধারণ বিষয় যাচাই করে। এগুলো নেস্ট করা যায়।
  • test এবং test.skip দুটিই একটি করে টেস্ট কেস নির্ধারণ করে, যেটি যথাক্রমে রান হয় বা স্কিপ হয়।
  • assert সেই অ্যাসারশনটি শুরু করে, যা একটি টেস্ট কেসের মূল অংশ। এর পরে আসা ->-এর ডান দিকের এক্সপ্রেশনটি সত্য হতে হবে।

XUnit টেস্টে সাধারণত assert লাইনের আগেই ফলাফল এবং প্রয়োজনে প্রত্যাশিত মান নির্দেশকারী ভ্যারিয়েবলগুলো তৈরি করা হয়।

টেস্ট আউটপুট

আপনি RSpec API ব্যবহার করুন বা XUnit API, টেস্ট আউটপুট মোটামুটি একই রকম হবে। পার্থক্য শুধু প্রতিটি টেস্টের নামের নিচে যা ছাপা হয়, তাতেই। XUnit অ্যাসারশনটি রিপোর্ট করে প্রাপ্ত মানগুলো দিয়ে, তাই আপনি দেখবেন false = false। কিন্তু RSpec এটি রিপোর্ট করে false? false হিসেবে, কারণ আমরা expects-এর সাথে false? ফাংশনটি ব্যবহার করেছি।

শুরু থেকেই ধরুন: শুরুর ফাইলের panic যদি সরে না যায়, তাহলে Arturo একটি এরর রিপোর্ট করবে এবং কোনো টেস্টই মূল্যায়ন করবে না।

Uncaught error in tests/test-leap.art:
#[
        output: {
                
                ══╡ Program Error ╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ <script> ══
                
                  Please implement the isLeap? function
                
                
        }
        code: 1
]

panic সরিয়ে ফেললে Arturo একটি টেস্টের ভেতরে করা প্রতিটি অ্যাসারশনের অবস্থা রিপোর্ট করবে। এখন প্রথম টেস্টটি পাস করে, কিন্তু দ্বিতীয় টেস্টটি স্কিপ করা থাকে।

======== .unitt/tests/test-leap.art ========

Describe: Leap

    ✅ - assert that a year not divisible by 4 is a common year
         ✅: false? false

    ⏩ - assert that a year divisible by 4 and not divisible by 100 is a leap year
         skipped!


========== Summary ==========

⏏️   TOTAL: 2 assertions
✅  PASSED: 1 assertion
⏩ SKIPPED: 1 assertion
❌  FAILED: 0 assertion

========== ======= ==========

দ্বিতীয় টেস্টটি হাতে আনস্কিপ করার পর দুটি টেস্টই রান হবে। তবে বর্তমান isLeap? কোড ইমপ্লিমেন্টেশনটি কেবল false রিটার্ন করে, তাই দ্বিতীয় টেস্টটি তার অ্যাসারশনে ফেল করে।

======== .unitt/tests/test-leap.art ========

Describe: Leap

    ✅ - assert that a year not divisible by 4 is a common year
         ✅: false? false

    ❌ - assert that a year divisible by 4 and not divisible by 100 is a leap year
         ❌: true? false


========== Summary ==========

⏏️   TOTAL: 2 assertions
✅  PASSED: 1 assertion
⏩ SKIPPED: 0 assertion
❌  FAILED: 1 assertion

========== ======= ==========

আপনি আরও টেস্ট আনস্কিপ করলে এই প্রক্রিয়াটি এভাবেই চলতে থাকবে। সব টেস্ট পাস হয়ে গেলে আপনার অনুশীলনী শেষ, তখন সমাধানটি সাবমিট করতে পারেন। মনে রাখুন, টেস্ট রানার সব টেস্টই রান করবে, সেগুলো লোকালি স্কিপ করা থাকুক বা না থাকুক।