এ পর্যন্ত সবকিছু ঠিকঠাক মত চলছে, কিন্তু এখন পর্যন্ত আমরা শুধুমাত্র একটি টেস্ট নিয়ে কাজ করছি। বাস্তবে ওয়েব অ্যাপের বিশাল দুনিয়ায় শত শত হাজার হাজার টেস্ট কেস আছে এবং অবশ্যই আমরা প্রত্যেকটি আলাদা আলাদা করে রান করাতে যাব না। এই মুহূর্তে আমাদের টেস্ট খোঁজা এবং এক্সিকিউট করার জন্য প্রয়োজন টেস্ট রানার ব্যবহার করা এবং এই নিবন্ধে আমরা সেটিই দেখব।
টেস্ট রানার
টেস্ট রানার প্রকৃত টেস্টিং ফ্রেমওয়ার্কের জন্য বেশ ভালো সুযোগ দেয়। টেস্ট রানারের কাজ হল টেস্ট ডিজাইন করা, অ্যাট্রিবিউটের সাথে টেস্ট ট্যাগ করা (annotations) এবং রিপোরটিং ও অঞ্জাঞ্জ ফিচারের সুযোগ দেয়। বেশ কিছু সংখ্যক পাইথন টেস্ট রানার আছে কিন্তু এই ক্ষেত্রে আমরা পাইথনের নিজস্ব unittest ব্যবহার করব কারণ এটি সহজ , ফলপ্রসূ এবং পাইথন প্যাকেজের সাথেই পাওয়া যায়, আলাদা করে কিছু ইন্সটল করার প্রয়োজন হয় না।
সাধারণত আপনি আপনার টেস্ট ৩টি স্ট্যান্ডার্ড সেকশনের মধ্যে ব্রেক করে ফেলেন; setUp()
, টেস্ট এবং tearDown()
, টেস্ট রানার সেট-আপের জন্য যথোপযুক্ত।
setUp()
এবং tearDown()
ম্যাথোড প্রতি টেস্টের জন্য আলাদা করে অটোমেটিক্যালি রান করানো হয় এবং এতে আছেঃ
- টেস্ট রান করানোর আগেই সেট-আপ করতে হবে, যেমন স্ক্রিন আনলক করা এবং ওপেন অ্যাপ কিল করা।
- টেস্ট রান করানোর পর শীতলীকরণ ধাপগুলো অনুসরণ করতে হবে, যেমন Marionette সেশন সমাপ্ত করা।
আপনার আসল টেস্ট রান করানোর জন্য যেসব কোড দরকার তা হল সেট-আপের টেস্ট পার্টটি। এখন দেখা যাক কীভাবে আমরা দ্বিতীয় ও চতুর্থ অংশে করা বিল্ড আপে এটি প্রয়োগ করি।
টেস্ট রান করা_যুক্ত করা_contact.py unittest এর সাথে
unittest ব্যবহার করার জন্য প্রথমে আমাদের unittest ইম্পোরট করা দরকারঃ আপনার অন্যান্য ইম্পোরট লাইনের মধ্যে নিচেরটি যুক্ত করুনঃ
import unittest
এরপর আমাদের TestContacts
ক্লাসের মধ্যে unittest পাস করে নিন এবং নিচের লাইনের মধ্যে আপনার class
আপডেট করে নিনঃ
class TestContacts(unittest.TestCase):
এরপর আমরা নিচেরটি মুছে ফেলবঃ
def __init__(self): self.test_add_contacts()
টেস্টটিকে ইনিশিয়ালাইজ করলে তা unittest দ্বারা নিয়ন্ত্রিত হবে, তাই আমাদের এটি নিয়ন্ত্রণ করা লাগবে না। আপনার কোডের নিচে কোডের, নিচেরটি রিপ্লেস করেঃ
if __name__ == '__main__': TestContacts()
এটি দিয়েঃ
if __name__ == '__main__': unittest.main()
এবার আমরা তৈরি করব setUp(self)
: TestContacts
হল আমাদের ক্লাসের মধ্যে ব্যবহৃত ম্যাথড এবং নিচের ধাপগুলো এর ভেতরে রাখুনঃ
- ম্যারিওনেট ইনিশিয়েট করে ম্যারিওনেট সেশন ওপেন করা
- স্ক্রিন আনলক করুন
- সব ওপেন অ্যাপ কিল করুন
- কন্ট্যাক্ট অ্যাপ লোড করুন
ম্যাথডটি দেখতে এমন হওয়া উচিতঃ
def setUp(self): # Create the client for this session. Assuming you're using the default port on a Marionette instance running locally self.marionette = Marionette() self.marionette.start_session() # Unlock the screen self.unlock_screen() # kill all open apps self.kill_all() # Switch context to the homescreen iframe and tap on the contacts icon time.sleep(2) home_frame = self.marionette.find_element('css selector', 'div.homescreen iframe') self.marionette.switch_to_frame(home_frame)
এখন tearDown(self):
ম্যাথোড তৈরি করা। এই ক্ষেত্রে আমাদের Marionette সেশন সমাপ্ত করার জন্য কোড যুক্ত করা প্রয়োজন। ম্যাথোডটি এমন হওয়া উচিতঃ
def tearDown(self): # Close the Marionette session now that the test is finished self.marionette.delete_session()
এখন ঠিক আগের মত করেই টেস্টটি রান করানোর চেষ্টা করুতি।আপনি খেয়াল করে থাকবেন যে এখন আপনি passes এবং failures এর জন্য রিপোর্ট পাচ্ছেন। unittest বা py.test এর মত টেস্ট রানার ব্যবহার করার সুবিধা এটি।
নোটঃ: যদি আপনি কোথাও আটকে গিয়ে থাকেন তবে আপনার সাহায্যার্থে প্রচুর unittest গাইড রয়েছে ইন্টারনেটে। আমাদের পরামর্শ https://selenium-python.readthedocs.org/en/latest/getting-started.html এবং https://assertselenium.com/2013/10/07/getting-started-with-python-webdriver/. এগুলো পাইথন এবং ওয়েবড্রাইভারের জন্য, কিন্তু এখন পর্যন্ত সেগুলো ব্যবহারযোগ্য নয়।
রেফারেন্স কোড
উদাহরণ হিসাবে, এই ধাপেও আমাদের ফাইনাল কোডটি নিচের মত দেখাবেঃ
import time from marionette import Marionette from marionette_driver import Wait import unittest class TestContacts(unittest.TestCase): def unlock_screen(self): self.marionette.execute_script('window.wrappedJSObject.lockScreen.unlock();') def kill_all(self): self.marionette.switch_to_frame() self.marionette.execute_async_script(""" // Kills all running apps, except the homescreen. function killAll() { let manager = window.wrappedJSObject.AppWindowManager; let apps = manager.getApps(); for (let id in apps) { let origin = apps[id].origin; if (origin.indexOf('homescreen') == -1) { manager.kill(origin); } } }; killAll(); // return true so execute_async_script knows the script is complete marionetteScriptFinished(true); """) def setUp(self): # Create the client for this session. Assuming you're using the default port on a Marionette instance running locally self.marionette = Marionette() self.marionette.start_session() # Unlock the screen self.unlock_screen() # kill all open apps self.kill_all() # Switch context to the homescreen iframe and tap on the contacts icon time.sleep(2) home_frame = self.marionette.find_element('css selector', 'div.homescreen iframe') self.marionette.switch_to_frame(home_frame) def test_add_contacts(self): contacts_icon = self.marionette.find_element('css selector', "#footer li[aria-label='Contacts']") contacts_icon.tap() # Switch context back to the base frame self.marionette.switch_to_frame() Wait(self.marionette).until(lambda m: m.find_element('css selector', "iframe[data-url*='contacts']").is_displayed()) # Switch context to the contacts app contacts_frame = self.marionette.find_element('css selector', "iframe[data-url*='contacts']") self.marionette.switch_to_frame(contacts_frame) # Tap [+] to add a new Contact self.marionette.find_element('id', 'add-contact-button').tap() Wait(self.marionette).until(lambda m: m.find_element('id', 'save-button').location['y']== 0) # Type name into the fields self.marionette.find_element('id', 'givenName').send_keys('John') self.marionette.find_element('id', 'familyName').send_keys('Doe') # Tap done self.marionette.find_element('id', 'save-button').tap() Wait(self.marionette).until(lambda m: not m.find_element('id', 'save-button').is_displayed()) def tearDown(self): # Close the Marionette session now that the test is finished self.marionette.delete_session() if __name__ == '__main__': unittest.main()