Exercism-এ আপনার Python অনুশীলনীগুলো কীভাবে টেস্ট করবেন, তা শিখুন।
আমরা আমাদের ওয়েবসাইটের টেস্ট রানার হিসেবে pytest ব্যবহার করি।
Python ট্র্যাকের অনুশীলনীর টেস্ট যদি আপনার নিজের কম্পিউটারে ডাউনলোড করে চালাতে চান, তাহলে আপনার ডেভেলপমেন্ট মেশিনে pytest ইনস্টল করা লাগবে।
এর সঙ্গে নিচের pytest প্লাগইনগুলোও ইনস্টল করা উচিত:
আমরা কোড লিন্টিং প্রোগ্রাম pylint ব্যবহারেরও সুপারিশ করি, কারণ এটি আমাদের ওয়েবসাইটের স্বয়ংক্রিয় ফিডব্যাকের একটি অংশ এবং একটি খুবই দরকারি স্ট্যাটিক কোড অ্যানালাইসিস টুল হতে পারে।
ব্যবহারের সুবিধার জন্য pytest-এর pytest-pylint প্লাগইন আপনাকে কমান্ড লাইনে pytest-এর মাধ্যমে pylint রান করার সুযোগ দেবে।
Pylint-এর কনফিগারেশন কিছুটা বেশি মনে হতে পারে, তাই শুরু করার জন্য pylint.readthedocs.io-এর এই টিউটোরিয়ালটি সহায়ক হতে পারে, আর Real Python-এর Code Quality: Tools and Best Practices ওভারভিউটিও তাই।
বিল্ট-ইন Python ইউটিলিটি pip দিয়ে pytest ইনস্টল ও আপডেট করা যায়।
আরও টিপসের জন্য Brett Cannon-এর কাছে Python-এর জন্য প্যাকেজ ইনস্টল করার একটি চমৎকার দ্রুত-সহজ গাইড আছে, সঙ্গে রয়েছে কেন আপনার python -m pip ব্যবহার করা উচিত তার একটি দারুণ ব্যাখ্যা।
Python-এর কমান্ড লাইন আর্গুমেন্ট নিয়ে আরও জানতে Python ডকুমেন্টেশনে কমান্ড লাইন ও এনভায়রনমেন্ট দেখুন।
নোট: আপনার সিস্টেমে Python3 আর py Python-এর অ্যালিয়াস হতে পারে, নাও হতে পারে।
নিচের ইনস্টল কমান্ডগুলো সেই অনুযায়ী সামঞ্জস্য করে নিন।
কোনো ভার্চুয়াল এনভায়রনমেন্টে pytest ইনস্টল করতে চাইলে কমান্ড চালানোর আগে এনভায়রনমেন্টটি অ্যাক্টিভেট করা আছে কিনা নিশ্চিত করুন।
অন্যথায় pytest ইনস্টলেশনটি গ্লোবাল হয়ে যাবে।
PS C:\Users\foobar> py -m pip install pytest pytest-cache pytest-subtests pytest-pylint
Successfully installed pytest-8.3.3 ...
$ python3 -m pip install pytest pytest-cache pytest-subtests pytest-pylint
Successfully installed pytest-8.3.3 ...
ইনস্টলেশন সফল হয়েছে কিনা দেখতে:
$ python3 -m pytest --version
pytest 8.3.3
টেস্ট চালাতে, টার্মিনালে cd দিয়ে যে ফোল্ডারটিতে অনুশীলনীটি রাখা আছে সেখানে যান (নিচের <exercise-folder-location>-এর জায়গায় আপনার পাথ বসান)।
$ cd <exercise-folder-location>
<exercise-folder-location> বা অ্যাঙ্গেল ব্র্যাকেটের ভেতরের বেশিরভাগ জিনিস বোঝায় একটি প্লেসহোল্ডার মান।
একটি সাধারণ পাথ বা ফাইলের নাম লেখা উচিত কোনো ব্র্যাকেট ছাড়াই।
উদাহরণস্বরূপ: /Users/janedoe/exercism/python/exercises/concept/chaitanas-colossal-coaster (*nix সিস্টেমে), C:\Users\janedoe\exercism\python\exercises\practice\hello-world\ (Windows-এ), myFolder বা my_file.py।
আপনি যে ফাইলটি চালাতে চাইবেন তার নাম সাধারণত _test.py দিয়ে শেষ হয়।
এই ফাইলে অনুশীলনীর সলিউশনের টেস্ট থাকে, এবং সলিউশন আপলোড করলে ওয়েবসাইটে যে টেস্টগুলো চলে সেগুলোই এগুলো।
এরপর টার্মিনালে নিচের কমান্ডটি চালান, <exercise_test.py>-এর জায়গায় টেস্ট ফাইলের অবস্থান/নাম বসিয়ে:
$ python3 -m pytest -o markers=task <exercise_test.py>
==================== 7 passed in 0.08s ====================
উপরের কমান্ডে যদি pytest -o markers=task ব্যবহার না করেন, তাহলে আমাদের নতুন সিনট্যাক্স ব্যবহার করা কোনো টেস্ট চালালে "unknown markers" নিয়ে warnings আসতে পারে।
প্রতিবার টেস্ট চালানোর সময় pytest -o markers=task টাইপ করা এড়াতে আপনি একটি pytest.ini কনফিগারেশন ফাইল ব্যবহার করতে পারেন, যা Python ট্র্যাক ডিরেক্টরির টপ লেভেল থেকে ডাউনলোড করা যায়: pytest.ini।
আপনি নিচের বিষয়বস্তু দিয়ে নিজের pytest.ini ফাইলও তৈরি করতে পারেন:
[pytest]
markers =
task: A concept exercise task.
Exercism অনুশীলনীগুলোর রুট বা ওয়ার্কিং ডিরেক্টরিতে এই ফাইলটি রাখলে মার্কগুলো রেজিস্টার হবে এবং ওয়ার্নিংগুলো বন্ধ হবে।
pytest মার্ক সম্পর্কে আরও তথ্য পাবেন pytest ডকুমেন্টেশনে অ্যাট্রিবিউট দিয়ে টেস্ট ফাংশন চিহ্নিত করা-এ এবং pytest ডকুমেন্টেশনে কাস্টম মার্কার নিয়ে কাজ করা-এ।
pytest কনফিগারেশন কাস্টমাইজ করার আরও তথ্য পাবেন pytest ডকুমেন্টেশনে কনফিগারেশন ফাইল ফরম্যাট-এ
টেস্ট ফেইল করলে pytest প্রতিটি ফেইল করা টেস্টের টেক্সট, তার সঙ্গে প্রতিটির প্রত্যাশিত ও প্রকৃত return মান টার্মিনালে প্রিন্ট করে।
নিচে একটি ফেইল করা টেস্টের সাধারণ উদাহরণ:
$(my_venv) python3 -m pytest -o markers=task <exercise_test.py>
=================== FAILURES ====================
______________ name_of_failed_test ______________
# Test code inside of <exercise_test.py> that failed.
...
E TypeOfError: ReturnedValue != ExpectedValue
exercise_test.py:<line_of_failed_test>: TypeOfError
============ short test summary info ============
FAILED exercise_test.py::ExerciseTest::name_of_failed_test
========== 1 failed, 2 passed in 0.13s ==========
pytest আপনার স্ক্রিনে ঠিক কী ফেরত দেয় তা নিয়ে সত্যিই নির্দিষ্ট হতে চাইলে, এখানে কিছু কাজের কমান্ড-লাইন আর্গুমেন্ট আছে যা দিয়ে আপনি এর আচরণ কনফিগার করতে পারবেন।
-v]-v (verbose) ফ্ল্যাগ যোগ করলে টেস্ট ফেইলিউরের পাশাপাশি এনভায়রনমেন্ট তথ্য ও একটি টেস্ট সামারিও দেখতে পাবেন:
$(my_venv) python3 -m pytest -o markers=task -v exercises/<exercise_name>/<test_file_test.py>
======================================== test session starts ===========================================
platform darwin -- Python 3.9.0, pytest-6.2.5, -- /usr/local/envs/my_env/bin/python3
cachedir: .pytest_cache
metadata: {'Python': '3.9.0', 'Platform': 'macOS-10.14.6-x86_64-i386-64bit', 'Packages': {'pytest': '6.2.1'}, 'Plugins': {'subtests': '0.5.0', 'pylint': '0.18.0'}
rootdir: /Users/<user>/exercism/python, configfile: pytest.ini
plugins: subtests-0.5.0, pylint-0.18.0
collected 5 items
exercises/exercise-name/exercise_file_test.py::ExerciseNameTest::test_one FAILED [ 20%]
exercises/exercise-name/exercise_file_test.py::ExerciseNameTest::test_two FAILED
exercises/exercise-name/exercise_file_test.py::ExerciseNameTest::test_three PASSED [ 40%]
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_four FAILED
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_five PASSED [ 60%]
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_six FAILED
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_seven PASSED [ 80%]
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_eight FAILED
exercises/concept/exercise-name/exercise_file_test.py::ExerciseNameTest::test_nine PASSED [100%]
================================================ FAILURES ======================================================
# Failed tests are then individually printed out below
.......
-x]-x ফ্ল্যাগ ব্যবহার করলে টেস্ট স্বাভাবিকভাবেই চলবে, কিন্তু প্রথম টেস্ট ফেইল হওয়ার সঙ্গে সঙ্গেই টেস্ট রান থেমে যাবে।
একবারে একটি টাস্ক বা টেস্ট ফেইলিউর ডিবাগ করতে চাইলে এটি সহায়ক:
$(my_venv) python3 -m pytest -o markers=task -x exercises/<exercise_name>/<test_file_test.py>
=================== FAILURES ====================
_______________ example_test_foo ________________
...
...
============ short test summary info ============
FAILED example_test.py::ExampleTest::example_test_foo
!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!
========== 1 failed, 5 passed in 0.28s ==========
--ff]pytest-cache প্লাগইন মনে রাখে গতবার pytest চালানোর সময় কোন টেস্টগুলো ফেইল করেছিল, তাই --ff ফ্ল্যাগ ব্যবহার করলে pytest আগে পূর্বে ফেইল করা টেস্টগুলো চালাবে, তারপর বাকি টেস্টগুলো চালিয়ে যাবে।
কোনো এক নির্দিষ্ট টাস্ক বা ইনপুটের সেট নিয়ে অনেকগুলো ছোটখাটো সংশোধন করলে এটি আপনার টেস্টিং দ্রুত করে তুলতে পারে।
$(my_venv) python3 -m pytest -o markers=task --ff <example_file_test.py>
==================== 7 passed in 503s ====================
আপনার ডিবাগিং সহজ ও (সম্ভবত) দ্রুত করতে আমরা নিচের কমান্ডগুলো ব্যবহারের সুপারিশ করি:
প্রথমে আপনার ওয়ার্কিং ডিরেক্টরি বদলে যে অনুশীলনীটি টেস্ট করতে চান তার ডিরেক্টরিতে যান:
$(my_venv) cd path/to/exercise
এরপর, আগে ব্যাখ্যা করা -x ও --ff আর্গুমেন্টসহ টেস্টগুলো চালান:
$(my_venv) python3 -m pytest -o markers=task -x --ff <example_file_test.py>
এতে আপনার সলিউশন টেস্ট হবে।
pytest কোনো ফেইল করা টেস্টে পৌঁছালে প্রোগ্রামটি থেমে যাবে এবং কোন টেস্টটি ফেইল করেছে তা জানাবে।
আপনি সংশোধন করে আবার টেস্ট চালালে pytest প্রথমে আগের ফেইল করা টেস্টটি চালাবে, তারপর বাকি টেস্টগুলো চালিয়ে যাবে।
"প্রফেশনালের মতো ডিবাগ" করতে চাইলে pytest কমান্ডের পরে --pdb আর্গুমেন্ট ব্যবহার করতে পারেন, আর তাতে আপনি ঢুকে পড়বেন বিল্ট-ইন Python ডিবাগার PDB-তে।
$(my_venv) python3 -m pytest -o markers=task -x --ff --pdb <example_file_test.py>
=============== 4 passed in 0.15s ===============
কোনো টেস্ট ফেইল করলে PDB-তে ঢুকে পড়লে আপনি বর্তমান স্কোপ দেখতে দেখতে আপনার কোড ধাপে ধাপে এগোতে পারবেন, সেই সঙ্গে ভ্যারিয়েবলের মান ও বিভিন্ন ফাংশনের সিগনেচারও যাচাই করতে পারবেন।
PDB মডিউল সম্পর্কে আরও বিস্তারিত পাবেন PDB-এর Python ডকুমেন্টেশনে।
এর বাইরে, PDB নিয়ে pytest ডকুমেন্টেশন এবং Real Python-এর এই গাইড অত্যন্ত সহায়ক।
টেস্টিং ও কোড উন্নত করতে সহায়ক কিছু টুল দিয়ে আপনার IDE সম্প্রসারিত করতে চাইলে tools পেজটি দেখুন। সেখানে আমরা একাধিক IDE, এডিটর এবং লিন্টিং ও ডিবাগিংয়ের কিছু দরকারি এক্সটেনশন নিয়ে আলোচনা করেছি।
নোট: Windows-এ যদি আপনি PSF Installer দিয়ে Python ইনস্টল করে থাকেন, তাহলে কমান্ডটি হবে py, python3 নয়।
একটি মডিউল রান করতে প্রতিবার python3 -m টাইপ করা কিছুটা বিরক্তিকর লাগতে পারে।
এটি এড়াতে, আপনার Python ইনস্টলেশনের Scripts ফোল্ডারটি আপনার PATH-এ যোগ করতে পারেন।
Python কোথায় ইনস্টল করেছেন জানা না থাকলে টার্মিনালে নিচের কমান্ডটি চালান:
$ python3 -c "import os, sys; print(os.path.dirname(sys.executable))"
<python_directory>
রিটার্ন করা ডিরেক্টরিটিই হলো যেখানে আপনার বর্তমানে সক্রিয় Python সংস্করণ ইনস্টল করা আছে; এই অংশে এটিকে <python_directory> বলা হয়েছে।
Windows Start বোতামে ক্লিক করুন এবং Edit the system environment variables খুঁজে এন্টার চাপুন।
এরপর Environment Variables... চাপুন:

এরপর আপনার User variables-এ Path ভ্যারিয়েবলটি খুঁজে বের করুন, সেটি সিলেক্ট করুন এবং Edit...-এ ক্লিক করুন:

এরপর ছবিতে দেখানো মতো একটি নতুন লাইন যোগ করুন, <python_directory>-এর জায়গায় আপনার Python ইনস্টলেশনের ডিরেক্টরি বসিয়ে:

নিচেরটি bash শেলসহ বেশিরভাগ Linux ও MacOS ফ্লেভারে কাজ করার কথা।
Linux ডিস্ট্রো অনুযায়ী, আর fish বা zsh শেল ব্যবহার হচ্ছে কিনা তার ভিত্তিতে কমান্ড আলাদা হতে পারে।
python3 -c "import os, sys; print(os.path.dirname(sys.executable))"-এর আউটপুট দিয়ে <python_directory>-এর জায়গা পূরণ করুন
export PATH="$PATH:<python_directory>"