Android Automation Testing Menggunakan Ruby, Appium, dan Cucumber Dengan Design Pattern POM

Apakah Ruby bisa digunakan untuk melakukan Android automation testing? Jawabannya bisa. Bagaimanakah caranya?

Di artikel ini dijelaskan dari A-Z bagaimana melakukan automation testing pada android dari instalasi sampai membuat report untuk automation testing.

Persiapan

1. Download dan Install

Download dan instal untuk setiap item di bawah ini:

ItemURL
VS Codehttps://code.visualstudio.com/download
Ruby[Windows]
https://rubyinstaller.org/

[Linux/MacOS]
Install GPG
– Linux: sudo apt install gnupg
– MacOS: disini
Install RVM: https://rvm.io/rvm/install
Install Ruby: https://rvm.io/rubies/installing
JDK 8https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
Node.jshttps://nodejs.org/dist/latest/
Android SDKhttps://developer.android.com/studio/archive
DeviceEmulator
Bisa diunduh dari AVD Manager di Android Studio, atau bisa menggunakan real device.

2. Instalasi Appium

Windows & Mac OS
  1. Jalankan terminal/command prompt.
  2. Ketik npm install -g appium
  3. Tekan Enter.
  4. Jika sudah selesai, untuk mengecek apakah Appium sudah berhasil diinstall atau belum, ketik appium -v. Jika muncul versi Appium, maka instalasi berhasil.
Linux
  1. Jalankan terminal/command prompt.
  2. Ketik sudo npm install -g appium --unsafe-perm=true --allow-root
  3. Tekan Enter.
  4. Jika sudah selesai, untuk mengecek apakah Appium sudah berhasil diinstall atau belum, ketik appium -v. Jika muncul versi Appium, maka instalasi berhasil.

3. Instalasi Gem

  1. Jalankan terminal/command prompt.
  2. Ketik gem install cucumber, tekan Enter.
  3. Ketik gem install gherkin, tekan Enter.
  4. Ketik gem install appium_lib, tekan Enter.
  5. Ketik gem install rspec, tekan Enter.
  6. Ketik gem install report_builder, tekan Enter.
  7. Untuk mengecek, ketik gem list, tekan Enter.

4. Environment Variable

Untuk pengaturan environment, dapat dilakukan dengan membaca artikel sebelumnya di sini.

Memulai Android Automation Testing

Kita akan menggunakan aplikasi More Locale 2 untuk automation testing-nya.

1. New Project

Untuk memulai membuat project, kita dapat membuat sebuah folder project dimana semua file automation disimpan di folder tersebut. Misal kita buat folder project dengan nama [Ruby] Android Automation Testing.

Setelah membuat folder project, berikutnya kita akan membuat project baru dengan langkah sebagai berikut:

  1. Jalankan terminal/command prompt.
  2. Masuk ke direktori project yang kita buat tadi.
  3. Ketik command cucumber --init
  4. Tekan Enter.
Display pada terminal setelah mengetikkan command cucumber –init
Struktur folder setelah mengetikkan command cucumber –init

Pada root folder project, tambahkan folder report dan ss. Folder report digunakan untuk menampung report yang di-generate secara otomatis dan folder ss digunakan untuk menampung screenshot dimana ditampilkan melalui report.

Juga tidak ketinggalan membuat folder yang digunakan untuk meletakkan file apk yang akan di-automation. Bisa membuat folder app di root project, kemudian copas file apk ke dalam folder app.

2. Menulis skenario dengan Gherkin

Tentang Gherkin, rekan pembaca dapat membaca artikel sebelumnya di sini.

Semua skenario disimpan di dalam folder features, sebagai berikut langkahnya:

Pada artikel ini, kita membuat 3 feature:
a. Add locale
b. Edit locale
c. Delete locale

  1. Dengan menggunakan editor VS Code, kita buat file baru.
  2. Tuliskan 3 feature di bawah.
  3. Jika sudah, simpan dengan ekstensi .feature

Add_Locale.feature

@Add_Locale
Feature: Add Locale

@Add_iso_locale
Scenario: Add locale from ISO list
Given user launch the AUT
Then User tap on option bar
Then User tap on Add Locale
Then User add label
And User add locale from ISO list

@Add_manual_locale
Scenario: Add manual locale
Given user launch the AUT
Then User tap on option bar
Then User tap on Add Locale
Then User add label
And User add manual locale

Edit_Locale.feature

@Edit_Locale
Feature: Edit Locale

@Edit_iso_locale
Scenario: Edit locale from ISO list
Given user launch the AUT
Then User tap on a locale option
And User tap on Edit
Then User edit label
And User add locale from ISO list

@Edit_manual_locale
Scenario: Edit manual locale
Given user launch the AUT
Then User tap on a locale option
And User tap on Edit
Then User edit label
And User edit manual locale

Delete_Locale.feature

@Delete_Locale
Feature: Delete Locale

@Delete_locale
Scenario: Delete locale
Given user launch the AUT
Then User tap on a locale option
Then User tap on delete
Struktur folder setelah menambahkan 3 file .feature

3. Men-setup automation

Berikutnya kita akan mengatur automation-nya dengan mengisi di file env.rb dan membuat file hook.rb. Kemudian kita juga akan membuat helper dengan nama file screen_action.rb, dimana berisi method-method umum yang sering digunakan, misal scroll, screenshot, dsb.

env.rb

require 'appium_lib'
require 'rspec/expectations'

include RSpec::Matchers

capabilities = {
    caps:{
        deviceName: "emulator-5554",
        platformName: "Android",
        platformVersion: "7.0",
        #app: "(path apk)",
        appPackage: "jp.co.c_lis.ccl.morelocale",
        #appActivity: "jp.co.c_lis.ccl.morelocale.ui.MainActivity"
        appWaitActivity: "*",
        },
        appium_lib:{
            server_url: "http://0.0.0.0:4723/wd/hub",
            wait: 30
        }
    }

@driver = Appium::Driver.new(capabilities, true)
@touch = Appium::TouchAction.new(@driver)
Appium.promote_appium_methods Object

Keterangan:

  • deviceName diperoleh dengan menggunakan command adb devices pada terminal/command prompt.
  • platformVersion dapat dilihat pada Setting > About Phone.
  • appPackage dapat dilihat di bagian package melalui inspector, bagaimana caranya, dapat membaca artikel sebelumnya di sini.
  • appWaitActivity activity pertama yang dipanggil untuk dijalankan. Bisa ditanyakan pada developer, atau kita bisa isi dengan tanda asterik (*).
    Jika menggunakan option appWaitActivity dan error, maka bisa mencoba menggunakan option appActivity, tetapi kita harus tau nama activity yang di-run pertama kali, bisa bertanya pada developer, atau mencari sendiri dengan menggunakan adb logcat pada terminal saat run app-nya.
  • Option app kita set jika kita memiliki file apk, namun jika app kita install dari Google Play Store, tidak perlu menggunakan option app. Di artikel ini, aplikasi More Locale 2 di-install dari Google Play Store, karena itu option app di-disable dengan simbol pagar (#).
  • Untuk mendapatkan file More Locale 2, dapat diunduh di Google Play Store.

hook.rb

Before do
    $driver.start_driver    
end

After do
    $driver.driver_quit
end

Keterangan:

  • Statement di dalam method Before akan dijalankan sebelum step definition dijalankan.
  • Statement di dalam method After akan dijalankan setelah step definition dijalankan.

screen_action.rb

def screenshot(name)
    $driver.screenshot("ss/#{name}.png")
    attach("ss/#{name}.png","image/png")
end

4. Membuat pages

Karena menggunakan design pattern POM, maka kita perlu membuat pages. Untuk konsep design pattern POM dapat membaca artikel sebelumnya di sini.

Folder pages dibuat di dalam folder features.

Berdasarkan skenario di atas, kita memerlukan 3 pages: Home screen, Form Locale screen, Iso screen.

Untuk mendapatkan nama-nama element, dapat membaca artikel sebelumnya di sini.

HomePage.rb

$homepage_option_bar_btn = "//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]/android.widget.FrameLayout[1]/android.view.ViewGroup[1]/androidx.appcompat.widget.LinearLayoutCompat[1]/android.widget.ImageView[1]"
$homepage_custom_locale_btn = "jp.co.c_lis.ccl.morelocale:id/custom_locale"
$homepage_current_locale = "jp.co.c_lis.ccl.morelocale:id/current_locale_display"
$homepage_title_bar = "//*[@text='MoreLocale 2']"
$homepage_locale_labels = "jp.co.c_lis.ccl.morelocale:id/label"
$homepage_add_locale_btn = "//*[@text='Add Locale']"
$homepage_lisences_btn = "//*[@text='Open Source Licenses']"
$homepage_about_btn = "//*[@text='About']"
$homepage_locale_more_btn = "jp.co.c_lis.ccl.morelocale:id/more"
$homepage_locale_more_edit_btn = "//*[@text='Edit']"
$homepage_locale_more_delete_btn = "//*[@text='Delete']"


def getTitleBarHome()
    sleep(1)
    title_bar = $driver.find_element(:xpath,$homepage_title_bar).text
    log("Title Bar: #{title_bar}")
end

def getCurrentLocaleHome()
    sleep(1)
    current_locale = $driver.find_element(:id,$homepage_current_locale).text
    log("Current Locale: #{current_locale}")
end

def tapOptionBarHome()
    sleep(1)
    $driver.find_element(:xpath,$homepage_option_bar_btn).click
end

def tapCustomLocaleHome()
    sleep(1)
    $driver.find_element(:id,$homepage_custom_locale_btn).click
end

def tapAddLocaleHome()
    sleep(1)
    $driver.find_element(:xpath,$homepage_add_locale_btn).click
end

def tapLisencesHome()
    sleep(1)
    $driver.find_element(:id,$homepage_lisences_btn).click
end

def tapAboutHome()
    sleep(1)
    $driver.find_element(:id,$homepage_about_btn).click
end

def tapLocaleMoreEditHome()
    sleep(1)
    $driver.find_element(:id,$homepage_locale_more_btn).click
    $driver.find_element(:xpath,$homepage_locale_more_edit_btn).click
end

def tapLocaleMoreDeleteHome()
    sleep(1)
    $driver.find_element(:id,$homepage_locale_more_btn).click
    $driver.find_element(:xpath,$homepage_locale_more_delete_btn).click
end

FormLocalePage.rb

$formlocale_input_label = "jp.co.c_lis.ccl.morelocale:id/input_label"
$formlocale_input_language = "jp.co.c_lis.ccl.morelocale:id/input_language"
$formlocale_input_country = "jp.co.c_lis.ccl.morelocale:id/input_country"
$formlocale_input_variant = "jp.co.c_lis.ccl.morelocale:id/input_variant"
$formlocale_iso639_btn = "jp.co.c_lis.ccl.morelocale:id/button_iso639"
$formlocale_iso3166_btn = "jp.co.c_lis.ccl.morelocale:id/button_iso3166"
$formlocale_cancel_btn = "android:id/button2"
$formlocale_add_btn = "android:id/button1"
$formlocale_add_locale_title = "jp.co.c_lis.ccl.morelocale:id/alertTitle"


def getTitleFormLocale()
    sleep(1)
    title = $driver.find_element(:id,$formlocale_add_locale_title).text
    log("Title: #{title}")
end

def inputLabelFormLocale(label)
    sleep(1)
    log(label)
    $driver.find_element(:id,$formlocale_input_label).clear
    $driver.find_element(:id,$formlocale_input_label).send_keys(label)
end

def inputLanguageFormLocale(lang)
    sleep(1)
    $driver.find_element(:id,$formlocale_input_language).clear
    $driver.find_element(:id,$formlocale_input_language).send_keys(lang)
end

def inputCountryFormLocale(country)
    sleep(1)
    $driver.find_element(:id,$formlocale_input_country).clear
    $driver.find_element(:id,$formlocale_input_country).send_keys(country)
end

def inputVariantFormLocale(variant)
    sleep(1)
    $driver.find_element(:id,$formlocale_input_variant).clear
    $driver.find_element(:id,$formlocale_input_variant).send_keys(variant)
end

def tapIso639FormLocale()
    sleep(1)
    $driver.find_element(:id,$formlocale_iso639_btn).click
end

def tapIso3166FormLocale()
    sleep(1)
    $driver.find_element(:id,$formlocale_iso3166_btn).click
end

def tapCancelFormLocale()
    sleep(1)
    $driver.find_element(:id,$formlocale_cancel_btn).click
end

def tapAddFormLocale()
    sleep(1)
    $driver.find_element(:id,$formlocale_add_btn).click
end

IsoPage.rb

isopage_iso_title = "jp.co.c_lis.ccl.morelocale:id/alertTitle"
isopage_labels = "jp.co.c_lis.ccl.morelocale:id/label"

def getTitleIso()
    sleep(1)
    title = $driver.find_element(:id,$isopage_iso_title).text
    log("Title: #{title}")
end

def tapLangListIso()
    sleep(1)
    $driver.find_element(:id,$isopage_labels).click
end

5. Mendefinisikan step

Step inilah yang nantinya akan melakukan interaksi-interaksi seperti yang dilakukan secara manual oleh tangan manusia. Di dalam step definition, kode-kode automation dituliskan.

File steps diletakkan di dalam folder step_definitions.

AddLocaleStep.rb

Given('user launch the AUT') do
  getTitleBarHome()
  screenshot("TitleHome")
  end
  
  Then('User tap on option bar') do
    tapOptionBarHome()
    screenshot("TapOptionBarHome")
  end
  
  Then('User tap on Add Locale') do
    tapAddLocaleHome()
    screenshot("TapAddLocale")
  end
  
  Then('User add label {string}') do |string|
    getTitleFormLocale()
    inputLabelFormLocale(string)
    screenshot("AddLabel")
  end
  
  Then('User add locale from ISO list') do
    tapIso639FormLocale()
    getTitleIso()
    tapLangListIso()
    tapIso3166FormLocale()
    getTitleIso()
    tapLangListIso()
    tapAddFormLocale()
  end
  
  Then('User add manual locale lang {string} and country {string}') do |string, string2|
    inputLanguageFormLocale(string)
    inputCountryFormLocale(string2)
    tapAddFormLocale()
  end

DeleteLocaleStep.rb

  Then('User tap on a locale option and delete') do
    tapLocaleMoreDeleteHome()
  end

EditLocaleStep.rb

Then('User tap on a locale option and edit') do
    tapLocaleMoreEditHome()
  end
  
  Then('User edit label {string}') do |string|
    inputLabelFormLocale(string)
  end
  
  Then('User edit manual locale lang {string} country {string}') do |string, string2|
    inputLanguageFormLocale(string)
    inputCountryFormLocale(string2)
    tapAddFormLocale()
  end

6. Membuat kode untuk men-generate report

Ketikkan kode di bawah berikut, dimana akan digunakan untuk membuat report automation secara otomatis dalam bentuk file HTML.

Simpan file tersebut ke root folder project.

report_builder.rb

require 'report_builder'

time = Time.now.getutc
ReportBuilder.configure do |config|
 config.json_path = 'report.json'
 config.report_path = 'report/report'
 config.report_types = [:html]
 config.report_tabs = %w[Overview Features Scenarios Errors]
 config.report_title = 'More Locale 2'
 config.compress_images = false
 config.additional_info = { 'Project name' => 'More Locale 2', 'Platform' => 'Android', 'Report generated' => time }
end
ReportBuilder.build_report

7. Menjalankan automation Android

  1. Jalankan terminal/command prompt.
  2. Ketikkan command appium & untuk menjalankan Appium.
  3. Jalankan terminal/command prompt di window yang berbeda.
  4. Masuk ke direktori project yang kita buat tadi.
  5. Untuk menjalankan:
AksiCommandContoh
Menjalankan semua scenariocucumber1. cucumber
2. tekan Enter (tunggu hingga automation selesai dijalankan)
Menjalankan scenario tertentucucumber -t @namascenario1. cucumber -t @Add_iso_locale
2. tekan Enter (tunggu hingga automation selesai dijalankan)
Menjalankan scenario sekaligus membuat reportcucumber -f pretty --expand -f json -o report.json1. cucumber -f pretty --expand -f json -o report.json
2. tekan Enter (tunggu hingga automation selesai dijalankan)
3. ruby report_builder.rb

Report akan ter-generate secara otomatis dan tersimpan di dalam folder Report.

8. Screenshot contoh report

Pada saat artikel ini ditulis, berikut versi yang digunakan:

  • gem appium_lib versi 11.1.0
  • gem report_builder versi 1.9
  • gem gherkin versi 9.0.0
  • gem cucumber versi 5.2.0
  • gem rspec versi 3.10.0
  • Ruby versi 2.5.8p224
  • Appium versi 1.19.1

Referensi

Leave a comment