Starting an UI Automation in Appium is not a tough task. You just need to locate elements, perform actions on it.
A small Appium test script maintenance looks easy,but ut with time test
suite will grow into multiple test scripts. As you add more and more lines to your code, things
become tough to maintain.The chief problem with script maintenance is that
if 10 different scripts are using the same mobile element, with any change
in that element, you need to change all 10 scripts. This is time
consuming and error prone.
A better approach to test scripts
maintenance is to create a separate class file which would find mobile
elements, fill them or verify them which can be reused in all the
scripts using that element. In future, if there is a change in the web
element, we need to make the change in just 1 class file and not 10
different test scripts.This approach is called Page Object Model(POM). It helps make the code more readable, maintainable, and reusable.
Video Tutorial -
What is POM?
1. Page Object Model is a design pattern.
2. Under this model, for each mobile app screen , there should be corresponding page class.
3. This Page class will find the MobileElements of that mobile screen page and also contains Page methods which perform operations on those MobileElements .
4. Name of these methods should be given as per the task they are performing, i.e., if a loader is waiting for the login page to appear, POM method name can be waitForLoginScreenDisplay().
Advantages of POM
1.Page Object Model defines that operations and test scenario flows in the UI should be separated from verification. This concept makes code cleaner and easier to understand.
2.The Second benefit is the object repository is kept independent of test cases, so we can use the same object repository for a different purpose and with different tools. For example, we can integrate POM with TestNG/JUnit for functional Testing and at the same time with JBehave/Cucumber for acceptance testing.
3.Code becomes reusable and optimized .
How to Use POM?
Core Class for Desired Capabilities related setup -
This class we can use to write core setup related code which is common for executing each Appium test case.
Driver class -
This class to instantiate driver object.
package com.example.anuja.appiumapplication; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Properties; import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DesiredCapabilities; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import io.appium.java_client.AppiumDriver; import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.remote.MobileCapabilityType; /** * Created by Anuja on 6/2/2017. */ public class BaseSetup { private DesiredCapabilities capabilities = new DesiredCapabilities(); private static AndroidDriver androidDriver = null; private String appiumPort; private String serverIp; @BeforeClass public void setup(){ initDriver(); } public AndroidDriver getDriver() { return androidDriver; } private void initDriver(){ System.out.println("Inside initDriver method"); DesiredCapabilities cap = new DesiredCapabilities(); cap.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Android device"); cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, "4000"); cap.setCapability(MobileCapabilityType.APP, "c://apks//listviewsample.apk"); cap.setCapability("noReset", true); String serverUrl = "http://" + serverIp + ":" + appiumPort + "/wd/hub"; try { System.out.println("Argument to driver object : " + serverUrl); androidDriver = new AndroidDriver(new URL(serverUrl), capabilities); } catch (NullPointerException | MalformedURLException ex) { throw new RuntimeException("appium driver could not be initialised for device "); } System.out.println("Driver in initdriver is : "+androidDriver); } @AfterClass public void tearDown(){ androidDriver.quit(); } }
This class to instantiate driver object.
import io.appium.java_client.android.AndroidDriver; /** * Created by Anuja on 6/2/2017. */ public class Driver extends BaseSetup{ protected AndroidDriver driver; public Driver() { this.driver = super.getDriver(); } }
This is how our page class looks.
import org.openqa.selenium.WebElement; import org.openqa.selenium.support.CacheLookup; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; import org.testng.Assert; /** * Created by Anuja on 5/17/2017. */ public class LoginPage extends Driver{ PageObjects loginPage; String userName = ""; String passWord = ""; public LoginPage() { super(); loginPage = new PageObjects(); PageFactory.initElements(driver, loginPage); } public boolean validateLoginpage(){ boolean elements = false; if(loginPage.userNameFld.isDisplayed()){ if(loginPage.passwordField.isDisplayed()){ if(loginPage.checkBox.isDisplayed()){ if(loginPage.loginBtn.isDisplayed()){ elements = true; } } } } else{ elements = false; } return elements; } public boolean testLoginWithoutCredentials() { boolean loginStatus = false; loginPage.loginBtn.click(); if (loginPage.inputError.getText().equalsIgnoreCase("Username is mandatory")) { loginStatus = true; } loginPage.userNameFld.sendKeys(userName); loginPage.loginBtn.click(); if (loginPage.inputError.getText().equalsIgnoreCase("Password is mandatory")) { loginStatus = true; } return loginStatus; } class PageObjects { @CacheLookup @FindBy(id = "et_username") public WebElement userNameFld; @CacheLookup @FindBy(id = "et_password") public WebElement passwordField; @CacheLookup @FindBy(id = "btnSignin") public WebElement loginBtn; @CacheLookup @FindBy(name = "Invalid ID or password.") public WebElement inputError; @CacheLookup @FindBy(id = "checkBox") public WebElement checkBox; } }
Test Case class for writing login page test cases -
This is how our test case is going to look.
import org.junit.Test; /** * Created by Anuja on 5/17/2017. */ public class LoginTests { @Test public void testLogin() { LoginPage loginPage = new LoginPage(); if(loginPage.validateLoginpage() == true){ loginPage.testLoginWithoutCredentials(); System.out.println("pass"); } else{ System.out.println("Validation failed"); } } }
I hope you like this post. do share your queries and feedback in comment section below and please follow me on social media for latest post updates.
could you make video for it.
ReplyDeleteyes its in my task .. List soon it will be up on youtube channel.
DeleteDo subscribe to get notifications :-)
ok thx xD
DeleteMachine Learning Projects for Final Year machine learning projects for final year
DeleteDeep Learning Projects assist final year students with improving your applied Deep Learning skills rapidly while allowing you to investigate an intriguing point. Furthermore, you can include Deep Learning projects for final year into your portfolio, making it simpler to get a vocation, discover cool profession openings, and Deep Learning Projects for Final Year even arrange a more significant compensation.
Python Training in Chennai Python Training in Chennai Angular Training Project Centers in Chennai
Hi... Can you please tell me how to run the above example
ReplyDeleteHI Can you make a video on running the example
ReplyDeletecan you please send a link for the listviewsample.apk
ReplyDeleteMore interesting articles here :Generation Enggelmundus Internet Marketing Tool here :Zeageat IM
ReplyDeleteHi,
ReplyDeleteI'm receiving an error "Method setup() should be static". How do you avoid this issue?
Thanks
Thank you so much for sharing this worth able content with us. The concept taken here will be useful for my future programs and i will surely implement them in my study. Keep blogging article like this.
ReplyDeleteselenium training in bangalore|
Hi Anuja,
ReplyDeleteI tried your solution but getnull pointer exception because of the driver doesn't initialized at all.
while debugging, the "Driver" class get into the getDriver method from "Base" class
but it's never get into the setup method to call the initDriver for driver initialized so how the driver will be initialized?
Thanks!
I have changes like ..
Deletepublic AndroidDriver getDriver() {
initDriver();
return androidDriver;
}
But looking for a correct fix.
I am using @Androidfindby but the test won't initialize the pages in intellijea. Any reason for this ?
ReplyDeleteNot even possible for this solution to work as you can't even access non-static methods from a static method. @BeforeClass depends on a static method. Classic one.
ReplyDeleteVery Nice Blog Updation Keep Updating !!
ReplyDeletevery informative blog
ReplyDeleteSoftware Testing Training In Chennai
nice post..
ReplyDeleteselenium training centers in BTM
best software testing training institutes in BTM with placements
automation testing courses in BTM
selenium testing course in BTM
software testing institutes in btm
selenium training in btm
best selenium training in btm
selenium course in btm
Good information
ReplyDeleteselenium training centers in Marathahalli
best software testing training institutes in Marathahalli with placements
automation testing courses in Marathahalli
selenium testing course in Marathahalli
software testing institutes in Marathahalli
selenium training in Marathahalli
best selenium training in Marathahalli
selenium course in Marathahalli
Hi,
ReplyDeleteThe question is: After each test, should I quit the driver and then before each test initialize it again?
This take quite some time.
If I'm just closing after each test and launching the app before each test works faster but not if I have test from different classes
If No need to close driver after every test. How do we achieve it? Can you please share the testng.xml file?
Awaiting for your response!
Thanks!!
Hi, I have a query ,
ReplyDeleteWhy are you using Driver.java Class to access the driver object ?
Why can't we make driver as proctected member in BaseSetup class and use that Android driver ?
Please change Desired capabilities like this
ReplyDeleteprivate DesiredCapabilities capabilities
private static AndroidDriver androidDriver = null;
and also inside the initDriver()
remove this DesiredCapabilities cap = new DesiredCapabilities();
and replace with cap = new DesiredCapabilities();
3rd change in the try block
androidDriver = new AndroidDriver(new URL(serverUrl), capabilities); - Change capabilities to cap.
it will work
IIT JEE Coaching in Patna | IIT JEE Institute in Patna | NEET Coaching in Patna | Medical Coaching in Patna | JEE Mains, JEE Advance Coaching in Patna | Europa Classes
ReplyDeleteJEE Mains, JEE Advance Coaching in Patna
Hot offers on Amazon]
Tips on technology
Anushka Sen
tipsontechnology
ReplyDeletelearn every time new tips on technology
Hey my audience, in this website we’ll post about many tips on technology. many tips on hacking, education and many entertainment niche. i’ll post somethin Tips on technology
g special for you, Everyday
So check out it from here
sale all product in hindi
ReplyDeleteHindisales provide you most productive Offers notification for you. If you Want to buy any products for you. Just check offers on that products in hindisales and check it out from here
Hot offers on Amazon]
Hi where we need to pass Server IP and Port number
ReplyDeleteThanks for Sharing This Article.It is very so much valuable content. I hope these Commenting lists will help to my website
ReplyDeletetop workday online training