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

মোবাইল অ্যাপ টেস্টিং এর জন্য যে টুলগুলো ব্যবহার করা হয়, Appium তার মধ্যে অন্যতম জনপ্রিয় একটি ওপেন সোর্স টুল। এটা মূলত Node.js দিয়ে লেখা একটি HTTP সার্ভার, যা Android mobile, iOS mobile এবং Windows Desktop প্লাটফর্মের নেটিভ, হাইব্রিড এবং ওয়েব অ্যাপ স্বয়ংক্রিয় করতে পারে। Appium একটি Cross-Platform System যা একই API এবং একই স্ক্রিপ্ট দিয়ে বিভিন্ন প্লাটফর্মের জন্য টেস্ট রান করতে পারে। আরেকভাবে বলতে গেলে, একই কোড বিভিন্ন টেস্টসুইটে ব্যবহার করা যায়।

Appium যেভাবে কাজ করে

Appium প্রধানত Client-Server Architecture অনুসরণ করে, যেখানে Selenium WebDiver এবং ল্যাঙ্গুয়েজ স্পেসিফিক Client Library ব্যবহার করে Appium Server এ HTTP রিকুয়েস্ট পাঠানো হয়, Appium Server রিকুয়েস্টগুলো ভেন্ডর হতে প্রদত্ত ফ্রেমওয়ার্ক এর সাহায্যে পারফর্ম করে।

  • প্রথমে Appium client এবং Appium server কানেক্টেড হয় এবং JSON Wire Protocol এর মাধ্যমে নিজেদের মধ্যে যোগাযোগ স্থাপন করে
  • কানেক্টেড হবার পর Apppium Server সেই Client এর জন্য একটা অটোমেশন Session তৈরি করে
  • Session তৈরি করার সময় Server Client এর Desired Capabilities চেক করে। Desired Capabilities হল JSON object এ encode করা keys এবং values, যেটা session তৈরির সময় client কিসের উপর টেস্ট করতে চাচ্ছে তার ব্যাপারে server কে কিছু তথ্য প্রদান করে
  • Server তারপর একটি Vendor Provided Framework এর সাথে কানেক্টেড হয় (Android এর ক্ষেত্রে যেমন UIAutomator, iOS এর ক্ষেত্রে UIAutomation ইত্যাদি)
  • তারপর Framework টি bootstrap.jar এর সাথে client প্রদত্ত টেস্টগুলো অ্যাপে পারফর্ম করার জন্য যোগাযোগ স্থাপন করে। Appium যখন একটি session শুরু করে তখন এটি সিমুলেটর/ইমুলেটর/রিয়াল ডিভাইসে বিল্ট-ইন UIAutomator কমান্ড ব্যবহার করে Automation Script টি রান করার জন্য bootstrap.jar(Android এর ক্ষেত্রে) বা boostrap.js(iOS এর ক্ষেত্রে) নামক একটি ফাইল Push করে
  • Command Execution শেষ হলে এটি server কে উক্ত Executed Command এর লগের বিস্তারিত একটা মেসেজ পাঠায়

কীভাবে ইন্সটল করবো?

সেটাপ এর জন্য আমি Manjaro(Arch Based Linux Distribution) ব্যবহার করবো।

  • প্রথমে OpenJDK ইন্সটল করতে হবে। এর জন্য শুরুতেই এর পাকেজ Available কিনা এবং কোথায় ও কী নামে নামে আছে তা সার্চ করে দেখে নিয়ে পরে ইন্সটল করা হয়েছে
pacman -Ss openjdk
sudo  pacman -Ss extra/jdk8-openjdk
  • Appium এর জন্য PATH এ JAVA_HOME ভেরিয়েবল ডিক্লেয়ার করতে হয়
# .bashrc ফাইল ওপেন করে তাতে JAVA_HOME এবং PATH ডিক্লেরার করতে হবে
vim .bashrc
     export JAVA_HOME="/usr/lib/jvm/java-8-openjdk"
     export PATH="$PATH:$JAVA_HOME/bin"
  • তারপর চেক করে দেখে নিতে হবে হোম থেকে জাভা এক্সেস করা যাচ্ছে কিনা
java -version

যদি নিচের মত আউটপুট না আসে তার মানে হলো ইন্সটল ঠিক মতো হয়নি।

openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~18.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

  • এরপর Apache Ant ইন্সটল করতে হবে। ইন্সটল এর জন্য [এই লিঙ্ক](https://www-us.apache.org/dist/ant/binaries/) থেকে লেটেস্ট ভার্সনটি নামিয়ে Extract করে সুবিধামত একটা লোকেশান এ রেখে পাথ অ্যাড করে দিতে হবে। আমি লোকেশান হিসেবে  /usr/local/bin/ ব্যবহার করেছি
wget https://www-us.apache.org/dist//ant/binaries/apache-ant-1.10.7-bin.tar.gz
tar xvzf apache-ant-1.10.7-bin.tar.gz
sudo mv apache-ant-1.10.7-bin.tar.gz /usr/local/bin/ant/

এবং .bashrc ফাইলেঃ

export ANT_HOME="/usr/local/bin/ant"
export PATH="$PATH:$ANT_HOME/bin

ইন্সটল চেক করে দেখার জন্যঃ

ant  -version

আউটপুটঃ

Apache Ant(TM) version 1.10.7 compiled on September 1 2019

এরপর ant ডিরেক্টরিতে গিয়ে লিখুনঃ

ant -f fetch.xml -Ddest=system
  • এরপর Apache Maven ইন্সটল করতে হবে। ইন্সটল এর জন্য [এই লিঙ্ক](https://www-us.apache.org/dist/ant/binaries/) থেকে লেটেস্ট ভার্সনটি নামিয়ে Extract করে সুবিধামত একটা লোকেশানে রেখে পাথ অ্যাড করে দিতে হবে। একইভাবে আমি লোকেশান হিসেবে  /usr/local/bin/ ব্যবহার করেছি।
wget https://www-us.apache.org/dist/maven/maven-3/3.6.2/binaries/apache-maven-3.6.2-bin.tar.gz
tar xvzf apache-maven-3.6.2-bin.tar.gz
sudo mv apache-maven-3.6.2-bin.tar.gz /usr/local/bin/apache-maven-3.6.2/

এবং .bashrc ফাইলেঃ

export MAVEN_HOME="/usr/local/bin/apache-maven-3.6.2"
export PATH="$PATH:$MAVEN_HOME/bin"

ইন্সটল চেক করে দেখার জন্যঃ

mvn  -v
  • তারপর RVM ইন্সটল করার জন্য প্রথমে mpapis public key (https://keybase.io/mpapis) ইন্সটল করতে হবে। তারপর,
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

এরপর RUBY দিয়ে RVM ইন্সটল করতে হবে

\curl -sSL https://get.rvm.io | bash -s stable --ruby
source /home/rahul/.rvm/scripts/rvm

ইন্সটল হয়ে গেলে RubyGems এবং Bundler আপডেট দিতে হবে

gem update --system
gem install -no-rdoc-no-ri bundler
gem update
gem cleanup
  • এবার node.js ইন্সটল করতে হবে, এর জন্য প্রথমে LinuxBrew ইন্সটল করতে হবে
pacman -Syu # পুরো সিস্টেম একবার আপডেট এর জন্য 
pacman -S base-devel
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"

এরপর .bashrc তেঃ

export  PATH=”/home/linuxbrew/.linuxbrew/bin”

তারপর নিচের কমান্ডটি চালিয়ে দেখতে হবে LinuxBrew ইন্সটলে কোন সমস্যা হয়েছে কিনা

brew  doctor

LinuxBrew ইন্সটল হয়ে গেলে এবার node.js ইন্সটল করব

brew install node
  • এরপর GRUNT ইন্সটল করতে হবে
npm install -g grunt grunt-cli
  • এরপর Appium ইন্সটল এর জন্যঃ
npm install -g appium
npm install wd
npm install -g appium-doctor

Appium ঠিকমত ইন্সটল হয়েছে কিনা তা দেখার জন্যঃ

Appium-doctor

Appium সার্ভার স্টার্ট করতেঃ

appium

Android অ্যাপ টেস্টের জন্য লেটেস্ট Android SDK ইন্সটল করতে হবে। আমি এর জন্য Android Studio ব্যবহার করেছি।  ইন্সটল হয়ে যাবার পর SDK ফোল্ডারের লোকেশান অনুযায়ী  .bashrc ফাইলে পাথ অ্যাড করতে হবে।

export ANDROID_HOME="$HOME/Android/Sdk"
export PATH="$PATH:$ANDROID_HOME/tools"
export PATH="$PATH:$ANDROID_HOME/platform-tools"

কোন কোন Android Image ইতোমধ্যে সিস্টেমে আভাইলেবেল আছে তা দেখার জন্য

android list targets

টেস্টিং অটোমেশন উদাহরণ

মোবাইল অ্যাপ টেস্টিং অটোমেশনের উদাহারণ হিসেবে একটি android ডিভাইসে কীভাবে অ্যাপ টেস্ট অটোমেট করব তা দেখাবো।

Appium একাধিক ল্যাঙ্গুয়েজ (e.g Ruby, Python, Java, Javascript, PHP, C# ইত্যাদি) সাপোর্ট করে, আমি স্ক্রিপ্ট লিখতে Python ব্যবহার করবো। এর জন্য Appium-Python-Client environment সেটাপ দিতে হবে।

pip install Appium-Python-Client

এবার অটোমেশন স্ক্রিপ্ট লিখা শুরু করা যাক। প্রথমে বেসিক মডিউলগুলো import করতে হবে।

from appium import webdriver
from appium.webdriver.common.mobileby import MobileBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os, time
import unittest

এরপর সেটাপ মডিউলে কোন অ্যাপ কোন ডিভাইসে বা কোন ইমুলেটরে সেটাপ করবো তার তথ্যগুলো দিতে হবে।

class TestBMFBonAppium(unittest.TestCase):
    def setUp(self):
            # আগে থেকে অ্যাপটি ডিভাইসে ইন্সটল থাকলে তা আনইন্সটল করে দেবো  
        os.system("adb -d uninstall com.example.bmfb")
        # ইমুলেটরের ক্ষেত্রে adb -e uninstall com.example.bmfb
        desired_caps = {}
        desired_caps["platformName"] = "Android"
        desired_caps["platformVersion"] = "6.0"
        desired_caps["app"] = os.getcwd()+ '/app_files/' + "BMFB.apk" 
        desired_caps["appPackage"] = "com.example.bmfb"
        desired_caps["deviceName"] = "Huawei Y6 II"
        desired_caps["name"] = "BMFB App testing"
        desired_caps["appiumVersion"] = "1.15.1"
        self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)

এরপর টেস্ট এর স্ক্রিপ্ট লেখা শুরু করবো। বেসিক কিছু অপারেশনের একটা স্ক্রিপ্ট দেওয়া আছে। স্ক্রিপ্ট এর বিস্তারিত জানতে এখানে (https://selenium-python.readthedocs.io/) দেখতে পারেন।


    def test_bmfb(self):
        os.system("adb -d shell am start com.example.bfmb/.MainActivity")
        # ইমুলেটরের ক্ষেত্রে adb -e shell am start com.example.bfmb/.MainActivity
        time.sleep(2)
        print("App Installed on device Successfully!!\n")
        print("T1: We will check for the text 'Search Items Here' ")
        t1 = self.driver.find_element_by_id("search_header")
        self.assertEqual(t1.text,"Search Items Here")
        print("T1 passed: Text Matched!!\n")
        print("T2: Enter text 'Test Automation on Appium' \n")
        t2 = self.driver.find_element_by_id("search_input")
        t2.send_keys("Test Automation on Appium\n")
        self.driver.hide_keyboard()
        print("T2 passed: Text Entered Successfully!!\n")
        time.sleep(2)
        print("T3: Open the Navigation Drawer\n")
        self.driver.find_element_by_accessibility_id("Open navigation drawer").click()
        print("T3 passed")
        time.sleep(2)

if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(TestBMFBonAppium)
    unittest.TextTestRunner(verbosity=2).run(suite)

এখন id বের করার জন্য কোড দেখাটা মাঝেমধ্যে বেশ সময়সাপেক্ষ হয়। এক্ষেত্রে UIAutomatorViewer টুল বাবহার করে কাজটি সহজ করা যায়।

UIAutomatorViewer টুল অন করার জন্যঃ

cd Android/sdk/tools/bin/
./uiautomatorviewer

এরপর স্ক্রিপ্ট চালানোর জন্যঃ

python3 automationscript.py

স্ক্রিপ্ট চালানোর আগে অবশ্যই খেয়াল করতে হবে যে অটোমেটেড টেস্টের জন্য ডিভাইস কিংবা ইমুলেটর ঠিকমত কানেক্টেড আছে কিনা এবং Appium server অন আছে কিনা।

ডিভাইস কিংবা ইমুলেটরের কানেকশান  চেক করতেঃ

adb devices

কানেক্টেড ডিভাইসের ধরণ অনুযায়ী এমন একটা আউটপুট দেখতে পাবো যদি ঠিকমত কানেক্টেড থাকেঃ

List of devices attached
LHTDU16727003504	device

উপরের স্ক্রিপ্টটি যে Android প্রোজেক্টটির উপর ভিত্তি করে লিখা হয়েছে তা দিয়ে দিলাম, চাইলে এটি দিয়ে  টেস্ট রান করে দেখতে পারেন।
লিঙ্ক: https://gitlab.com/rahul108sk/bmfb_android_demo

সবাইকে অনেক ধনব্যাদ!