SlideShare a Scribd company logo
Breaking free from .staticAbuse()
in test automation frameworks
Hello!
I am Abhijeet Vaikar
● Software Quality Engineer since 6 years and 7
months with a focus on Test Automation
● Quality Engineer @ Carousell
● https://www.linkedin.com/in/abhijeetvaikar/
Southeast Asia's largest and fastest
growing mobile marketplace,
and a highly-rated iPhone & Android app
that makes selling as simple as taking a
photo and buying as simple as chat.
https://www.carousell.com
What are we here for?
● Why we should avoid abusing static methods in
automation frameworks
● What we can do about it.
● How we can use Dependency Injection
frameworks to simplify automation scripts.
Why
we should avoid abusing static in automation frameworks
Does this look familiar?
protected void grabScreenshot(){
ScreenshotUtil.captureScreenshot(currentSuiteScreenshotsDirector
yPath);
}
AppiumUtil.scrollDown();
User user = UserService.getUser(expectedUserKey);
Does this look familiar?
itemName =
TestDataService.extract(itemName);
private static
AndroidDriver<WebElement> driver;
So what’s wrong with that?
Concurrency issues
All static objects are shared between threads. Imagine the race condition issues with
parallel test executions.
private static WebDriver driver;
private static HashMap<String, String> testResultsMap;
Thread 1
Thread 2 Thread 3
Expect something :)
Get something else :’(
Design
Code becomes procedural instead of object oriented.
public class LoginTest {
@Test(priority = 0)
public void loginfail() {
LoginPage.goTo("http://127.0.0.1:8080/login");
LoginPage.loginAs("wrong username", "wrongpassword");
boolean didLoginFail = LoginPage.loginErrorDisplayed();
Assert.assertTrue(didLoginFail == true, "Bad login was successful");
if (didLoginFail){
LoginPage.getLoginErrorMessage();
}
}
@Test(priority = 1)
public void loginsuccess() {
LoginPage.loginAs("correct_username", "correctpass");
boolean didLoginFail = LoginPage.loginErrorDisplayed();
Assert.assertTrue(didLoginFail == false, "Valid Login was unsuccessful");
}
Mutable state
Static objects if kept mutable leaves their values open to change by other code.
/** Contains all the constant system property names */
public final class SystemPropertyConstants {
public static String loginEndPoint = "/api/login/";
}
// In some other code
SystemPropertyConstants.loginEndPoint = "/api/logout/";
What
Can we do about it?
“Make the framework smart so that the
test code can be short and simple.
Test code must be so concise that it
doesn't matter which language is used to
run it”
- Martin Schneider ( Java Ninja @
Carousell )
For concurrency issues
public static ThreadLocal<WebDriver> driver;
driver =
new ThreadLocal<WebDriver>() {
@Override
protected WebDriver initialValue() {
return new FirefoxDriver(); // You
can use other driver based on your requirement.
}
};
OR use Dependency Injection with non-static object
Design
Use Object-Oriented programming concepts (abstraction, encapsulation, inheritance, polymorphism) to make your
test code maintainable.
new AuthPage().login("username","password");
SellingPage sellingPage = new HomePage().startSelling();
sellingPage
.setCategory(Category.EVERYTHING_ELSE)
.setItemDetails("Carousell Test Item",ConditionType.NEW,"Test Description")
.setPrice("10.12")
.setDealDetails(DealType.MEETUP,"Lets meetup at 5 PM")
.listIt();
AND enhance them using Dependency Injection
Mutable state
To avoid static objects being overwritten by other code, declare them final
/** Contains all the constant system property names */
public final class SystemPropertyConstants {
public static final String loginEndPoint = "/api/login/";
}
What is
Dependency
Injection????
Dependency Injection
Dependency Non-Injection
public class Employee {
private Address address;
public Employee() {
address = new Address();
}
}
Employee employee = new Employee(new address);
Employee employee = new Employee();
employee.setAddress(new Address());
SellingPage sellingPage = new SellingPage(driver);
// Injecting driver dependency in pageobjects
@BeforeMethod
public void setUp(ITestContext testContext){
...
}
// DI used by TestNG
Dependency Injection using a framework
● Use a DI framework instead of managing dependencies manually.
● DI frameworks: Spring, Google Guice, PicoContainer, Dagger
● These frameworks use IoC (Inversion of Control) container in which all the
dependencies are registered, initialized and managed.
● IoC (Inversion of Control) - “Don’t call us, we call you”
● Once the dependencies are instantiated, the container injects them using
approaches like:
○ Constructor injection
○ Setter method injection
○ Field injection
Benefits of Dependency Injection
● Single Responsibility Principle
● Clean, Readable code
● Isolated components which become easy for testing as dependencies can be
mocked without modifying depending class.
How
we can use Dependency Injection frameworks to simplify automation scripts.
22
Spring Dependency Injection
Spring IoC Container
(where all the magic
happens!)
Configuration in Java
class or XML
Read dependency and configuration details
Create dependency
objects and inject them
POJOs/ Java
Classes part of your
application
code/test code
Usable system with
all dependencies
available
@Component @Configuration
@Autowired @Bean
Applied to fields, setter methods, and
constructors. The @Autowired annotation
injects object dependency implicitly.
Used as config for
Spring. Can have
methods to instantiate
and configure the
dependencies
Marks the Java class
as a bean or
component (i.e., you
want Spring to
manage this class
instance)
Applied to fields, setter methods, and
constructors. The @Autowired annotation
injects object dependency implicitly.
Commonly used annotations in Spring
Used for conditional
loading of classes
based on usecase
(environment,
platform etc)
@Profile
@Test()
public void testNewListingAppearsInSearch() throws Exception {
new WelcomePage(driver).beginSignUpOrLoginWithEmail();
new AuthPage(driver).login("username","password");
new
HomePage(driver).startSellingWithPhotoFromCamera();
new CameraPage(driver).capturePhoto();
new CameraPhotoPreviewEditPage(driver).moveForward();
}
}
● Driver is a dependency for PageObjects.
● PageObjects are a dependency for the test class
(Is it necessary to create new instance of pageobject every time?)
public class WelcomePage extends BasePage {
private WebDriver driver;
WelcomePage(WebDriver driver){
super(driver);
this.driver = driver;
}
. . . .
}
@Configuration
@ComponentScan(basePackages = "com.carousell")
public class SpringContext {
@Autowired
private TestConfiguration configuration;
private WebDriver driver;
@Bean
public WebDriver getWebDriver() {
if(configuration.isWeb()){
driver = new ChromeDriver();
}
else if(configuration.isAndroid() {
driver = new AndroidDriver();
}
else if(configuration.isIOS()) {
driver = new IOSDriver();
}
return driver;
}
Create a configuration class for Spring to manage dependencies
public class WelcomePage extends BasePage {
@Autowired
private WebDriver driver;
//You can move this to BasePage too
. . . .
}
29
@Component
public class WelcomePage extends BasePage {
@Autowired
private WebDriver driver;
//You can move this to BasePage too
. . . .
}
@Autowired
WelcomePage welcomePage;
@Autowired
AuthPage authPage;
. . . . .
@Test()
public void testNewListingAppearsInSearch() throws Exception {
welcomPage.beginSignUpOrLoginWithEmail();
authPage.login("username","password");
homePage.startSellingWithPhotoFromCamera();
cameraPage.capturePhoto();
cameraPhotoPreviewEditPage.moveForward();
//Use references directly as they are already injected with instance by
Spring
}
public abstract class WelcomePage
extends BasePage {
}
@Component
@Profile(Platform.ANDROID)
public class AndroidWelcomePage
extends WelcomePage {
}
@Component
@Profile(Platform.IOS)
public class IOSWelcomePage
extends WelcomePage {
}
spring.profiles.active=ANDROID - Initializes AndroidWelcomePage and injects into an
Autowired variable.
Sounds good. Where can I find real
world implementation of such
framework?
Check out https://www.justtestlah.qa/
Python: dependency_injector, Spring Python
Ruby: sinject, dry-container
C#: Spring.Net , Castle Windsor, Unity, Autofac
Javascript: BottleJS, InversifyJS, DI-Ninja
Thank you. Questions?
Reference
Inversion of Control and Dependency Injection
https://martinfowler.com/bliki/InversionOfControl.html
https://martinfowler.com/articles/injection.html
https://www.baeldung.com/inversion-control-and-dependency-injection-in-spring
https://dzone.com/articles/a-guide-to-spring-framework-annotations
https://stackoverflow.com/questions/52720198/how-does-spring-profile-work-with-inheritance
Static methods and variables
https://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil
https://stackoverflow.com/questions/2671496/java-when-to-use-static-methods
https://stackoverflow.com/questions/4002201/why-arent-static-methods-considered-good-oo-practice
https://softwareengineering.stackexchange.com/questions/336701/static-services-and-testability
Use of Dependency Injection in automation frameworks
www.justtestlah.qa by Martin Schneider
https://peterkedemo.wordpress.com/2013/03/30/writing-good-selenium-tests-with-page-objects-and-spring/

More Related Content

What's hot

UI Testing Automation
UI Testing AutomationUI Testing Automation
UI Testing AutomationAgileEngine
 
Selenium web driver
Selenium web driverSelenium web driver
Selenium web driver
Roman Savitskiy
 
Automated Smoke Tests with Protractor
Automated Smoke Tests with ProtractorAutomated Smoke Tests with Protractor
Automated Smoke Tests with Protractor
🌱 Dale Spoonemore
 
Test automation - Building effective solutions
Test automation - Building effective solutionsTest automation - Building effective solutions
Test automation - Building effective solutions
Artem Nagornyi
 
Introduction to Selenium
Introduction to SeleniumIntroduction to Selenium
Introduction to Selenium
rohitnayak
 
Protractor Testing Automation Tool Framework / Jasmine Reporters
Protractor Testing Automation Tool Framework / Jasmine ReportersProtractor Testing Automation Tool Framework / Jasmine Reporters
Protractor Testing Automation Tool Framework / Jasmine Reporters
Haitham Refaat
 
Acceptance & Functional Testing with Codeception - Devspace 2015
Acceptance & Functional Testing with Codeception - Devspace 2015 Acceptance & Functional Testing with Codeception - Devspace 2015
Acceptance & Functional Testing with Codeception - Devspace 2015
Joe Ferguson
 
PHP Unit Testing in Yii
PHP Unit Testing in YiiPHP Unit Testing in Yii
PHP Unit Testing in Yii
IlPeach
 
Testing Web Applications
Testing Web ApplicationsTesting Web Applications
Testing Web Applications
Seth McLaughlin
 
Mobile Testing with Selenium 2 by Jason Huggins
Mobile Testing with Selenium 2 by Jason HugginsMobile Testing with Selenium 2 by Jason Huggins
Mobile Testing with Selenium 2 by Jason Huggins
Sauce Labs
 
Join the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.jsJoin the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.js
Seth McLaughlin
 
Testing android apps with espresso
Testing android apps with espressoTesting android apps with espresso
Testing android apps with espresso
Édipo Souza
 
Front-End Testing: Demystified
Front-End Testing: DemystifiedFront-End Testing: Demystified
Front-End Testing: Demystified
Seth McLaughlin
 
Selenium Basics Tutorial
Selenium Basics TutorialSelenium Basics Tutorial
Selenium Basics Tutorial
Clever Moe
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
Mek Srunyu Stittri
 
Codeception introduction and use in Yii
Codeception introduction and use in YiiCodeception introduction and use in Yii
Codeception introduction and use in Yii
IlPeach
 
WinAppDriver - Windows Store Apps Test Automation
WinAppDriver - Windows Store Apps Test AutomationWinAppDriver - Windows Store Apps Test Automation
WinAppDriver - Windows Store Apps Test Automation
Jeremy Kao
 
An overview of selenium webdriver
An overview of selenium webdriverAn overview of selenium webdriver
An overview of selenium webdriver
Anuraj S.L
 

What's hot (20)

UI Testing Automation
UI Testing AutomationUI Testing Automation
UI Testing Automation
 
Selenium web driver
Selenium web driverSelenium web driver
Selenium web driver
 
Automated Smoke Tests with Protractor
Automated Smoke Tests with ProtractorAutomated Smoke Tests with Protractor
Automated Smoke Tests with Protractor
 
Test automation - Building effective solutions
Test automation - Building effective solutionsTest automation - Building effective solutions
Test automation - Building effective solutions
 
Introduction to Selenium
Introduction to SeleniumIntroduction to Selenium
Introduction to Selenium
 
Protractor Testing Automation Tool Framework / Jasmine Reporters
Protractor Testing Automation Tool Framework / Jasmine ReportersProtractor Testing Automation Tool Framework / Jasmine Reporters
Protractor Testing Automation Tool Framework / Jasmine Reporters
 
Automation Testing by Selenium Web Driver
Automation Testing by Selenium Web DriverAutomation Testing by Selenium Web Driver
Automation Testing by Selenium Web Driver
 
Codeception
CodeceptionCodeception
Codeception
 
Acceptance & Functional Testing with Codeception - Devspace 2015
Acceptance & Functional Testing with Codeception - Devspace 2015 Acceptance & Functional Testing with Codeception - Devspace 2015
Acceptance & Functional Testing with Codeception - Devspace 2015
 
PHP Unit Testing in Yii
PHP Unit Testing in YiiPHP Unit Testing in Yii
PHP Unit Testing in Yii
 
Testing Web Applications
Testing Web ApplicationsTesting Web Applications
Testing Web Applications
 
Mobile Testing with Selenium 2 by Jason Huggins
Mobile Testing with Selenium 2 by Jason HugginsMobile Testing with Selenium 2 by Jason Huggins
Mobile Testing with Selenium 2 by Jason Huggins
 
Join the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.jsJoin the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.js
 
Testing android apps with espresso
Testing android apps with espressoTesting android apps with espresso
Testing android apps with espresso
 
Front-End Testing: Demystified
Front-End Testing: DemystifiedFront-End Testing: Demystified
Front-End Testing: Demystified
 
Selenium Basics Tutorial
Selenium Basics TutorialSelenium Basics Tutorial
Selenium Basics Tutorial
 
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 -  Fullstack end-to-end Test Automation with node.jsForwardJS 2017 -  Fullstack end-to-end Test Automation with node.js
ForwardJS 2017 - Fullstack end-to-end Test Automation with node.js
 
Codeception introduction and use in Yii
Codeception introduction and use in YiiCodeception introduction and use in Yii
Codeception introduction and use in Yii
 
WinAppDriver - Windows Store Apps Test Automation
WinAppDriver - Windows Store Apps Test AutomationWinAppDriver - Windows Store Apps Test Automation
WinAppDriver - Windows Store Apps Test Automation
 
An overview of selenium webdriver
An overview of selenium webdriverAn overview of selenium webdriver
An overview of selenium webdriver
 

Similar to Breaking free from static abuse in test automation frameworks and using Spring DI

Using Page Objects
Using Page ObjectsUsing Page Objects
Using Page Objects
Getch88
 
Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJS
Knoldus Inc.
 
Protractor framework architecture with example
Protractor framework architecture with exampleProtractor framework architecture with example
Protractor framework architecture with example
shadabgilani
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
Gunnar Hillert
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
Purbarun Chakrabarti
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's NewTed Pennings
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CN
jojule
 
Test automation
Test  automationTest  automation
Test automation
Kaushik Banerjee
 
Mastering Test Automation: How To Use Selenium Successfully
Mastering Test Automation: How To Use Selenium SuccessfullyMastering Test Automation: How To Use Selenium Successfully
Mastering Test Automation: How To Use Selenium Successfully
SpringPeople
 
Human Talks - StencilJS
Human Talks - StencilJSHuman Talks - StencilJS
Human Talks - StencilJS
Alexandre Koelsch
 
Hybrid App using WordPress
Hybrid App using WordPressHybrid App using WordPress
Hybrid App using WordPress
Haim Michael
 
Test strategy for web development
Test strategy for web developmentTest strategy for web development
Test strategy for web developmentalice yang
 
Frontend training
Frontend trainingFrontend training
Frontend training
Adrian Caetano
 
Spring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUGSpring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUG
Ted Pennings
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
Eliran Eliassy
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
ciklum_ods
 
The Role of Python in SPAs (Single-Page Applications)
The Role of Python in SPAs (Single-Page Applications)The Role of Python in SPAs (Single-Page Applications)
The Role of Python in SPAs (Single-Page Applications)
David Gibbons
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
goodfriday
 
Intro to Laravel 4
Intro to Laravel 4Intro to Laravel 4
Intro to Laravel 4
Singapore PHP User Group
 

Similar to Breaking free from static abuse in test automation frameworks and using Spring DI (20)

Using Page Objects
Using Page ObjectsUsing Page Objects
Using Page Objects
 
Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJS
 
Protractor framework architecture with example
Protractor framework architecture with exampleProtractor framework architecture with example
Protractor framework architecture with example
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's New
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CN
 
Test automation
Test  automationTest  automation
Test automation
 
Mastering Test Automation: How To Use Selenium Successfully
Mastering Test Automation: How To Use Selenium SuccessfullyMastering Test Automation: How To Use Selenium Successfully
Mastering Test Automation: How To Use Selenium Successfully
 
Human Talks - StencilJS
Human Talks - StencilJSHuman Talks - StencilJS
Human Talks - StencilJS
 
Hybrid App using WordPress
Hybrid App using WordPressHybrid App using WordPress
Hybrid App using WordPress
 
70562 (1)
70562 (1)70562 (1)
70562 (1)
 
Test strategy for web development
Test strategy for web developmentTest strategy for web development
Test strategy for web development
 
Frontend training
Frontend trainingFrontend training
Frontend training
 
Spring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUGSpring MVC Intro / Gore - Nov NHJUG
Spring MVC Intro / Gore - Nov NHJUG
 
Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics Angular server side rendering - Strategies & Technics
Angular server side rendering - Strategies & Technics
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
The Role of Python in SPAs (Single-Page Applications)
The Role of Python in SPAs (Single-Page Applications)The Role of Python in SPAs (Single-Page Applications)
The Role of Python in SPAs (Single-Page Applications)
 
Developing ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller PatternDeveloping ASP.NET Applications Using the Model View Controller Pattern
Developing ASP.NET Applications Using the Model View Controller Pattern
 
Intro to Laravel 4
Intro to Laravel 4Intro to Laravel 4
Intro to Laravel 4
 

More from Abhijeet Vaikar

Unit testing (Exploring the other side as a tester)
Unit testing (Exploring the other side as a tester)Unit testing (Exploring the other side as a tester)
Unit testing (Exploring the other side as a tester)
Abhijeet Vaikar
 
End-end tests as first class citizens - SeleniumConf 2020
End-end tests as first class citizens - SeleniumConf 2020End-end tests as first class citizens - SeleniumConf 2020
End-end tests as first class citizens - SeleniumConf 2020
Abhijeet Vaikar
 
Good practices for debugging Selenium and Appium tests
Good practices for debugging Selenium and Appium testsGood practices for debugging Selenium and Appium tests
Good practices for debugging Selenium and Appium tests
Abhijeet Vaikar
 
Upgrading Mobile Tester's Weapons with Advanced Debugging
Upgrading Mobile Tester's Weapons with Advanced DebuggingUpgrading Mobile Tester's Weapons with Advanced Debugging
Upgrading Mobile Tester's Weapons with Advanced Debugging
Abhijeet Vaikar
 
Mongo DB 102
Mongo DB 102Mongo DB 102
Mongo DB 102
Abhijeet Vaikar
 
MongoDB 101
MongoDB 101MongoDB 101
MongoDB 101
Abhijeet Vaikar
 

More from Abhijeet Vaikar (6)

Unit testing (Exploring the other side as a tester)
Unit testing (Exploring the other side as a tester)Unit testing (Exploring the other side as a tester)
Unit testing (Exploring the other side as a tester)
 
End-end tests as first class citizens - SeleniumConf 2020
End-end tests as first class citizens - SeleniumConf 2020End-end tests as first class citizens - SeleniumConf 2020
End-end tests as first class citizens - SeleniumConf 2020
 
Good practices for debugging Selenium and Appium tests
Good practices for debugging Selenium and Appium testsGood practices for debugging Selenium and Appium tests
Good practices for debugging Selenium and Appium tests
 
Upgrading Mobile Tester's Weapons with Advanced Debugging
Upgrading Mobile Tester's Weapons with Advanced DebuggingUpgrading Mobile Tester's Weapons with Advanced Debugging
Upgrading Mobile Tester's Weapons with Advanced Debugging
 
Mongo DB 102
Mongo DB 102Mongo DB 102
Mongo DB 102
 
MongoDB 101
MongoDB 101MongoDB 101
MongoDB 101
 

Recently uploaded

A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
Neo4j
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
Shane Coughlan
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 

Recently uploaded (20)

A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
GraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph TechnologyGraphSummit Paris - The art of the possible with Graph Technology
GraphSummit Paris - The art of the possible with Graph Technology
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 
openEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain SecurityopenEuler Case Study - The Journey to Supply Chain Security
openEuler Case Study - The Journey to Supply Chain Security
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 

Breaking free from static abuse in test automation frameworks and using Spring DI

  • 1. Breaking free from .staticAbuse() in test automation frameworks
  • 2. Hello! I am Abhijeet Vaikar ● Software Quality Engineer since 6 years and 7 months with a focus on Test Automation ● Quality Engineer @ Carousell ● https://www.linkedin.com/in/abhijeetvaikar/
  • 3. Southeast Asia's largest and fastest growing mobile marketplace, and a highly-rated iPhone & Android app that makes selling as simple as taking a photo and buying as simple as chat. https://www.carousell.com
  • 4. What are we here for? ● Why we should avoid abusing static methods in automation frameworks ● What we can do about it. ● How we can use Dependency Injection frameworks to simplify automation scripts.
  • 5. Why we should avoid abusing static in automation frameworks
  • 6.
  • 7. Does this look familiar? protected void grabScreenshot(){ ScreenshotUtil.captureScreenshot(currentSuiteScreenshotsDirector yPath); } AppiumUtil.scrollDown(); User user = UserService.getUser(expectedUserKey);
  • 8. Does this look familiar? itemName = TestDataService.extract(itemName); private static AndroidDriver<WebElement> driver;
  • 9. So what’s wrong with that?
  • 10. Concurrency issues All static objects are shared between threads. Imagine the race condition issues with parallel test executions. private static WebDriver driver; private static HashMap<String, String> testResultsMap; Thread 1 Thread 2 Thread 3 Expect something :) Get something else :’(
  • 11. Design Code becomes procedural instead of object oriented. public class LoginTest { @Test(priority = 0) public void loginfail() { LoginPage.goTo("http://127.0.0.1:8080/login"); LoginPage.loginAs("wrong username", "wrongpassword"); boolean didLoginFail = LoginPage.loginErrorDisplayed(); Assert.assertTrue(didLoginFail == true, "Bad login was successful"); if (didLoginFail){ LoginPage.getLoginErrorMessage(); } } @Test(priority = 1) public void loginsuccess() { LoginPage.loginAs("correct_username", "correctpass"); boolean didLoginFail = LoginPage.loginErrorDisplayed(); Assert.assertTrue(didLoginFail == false, "Valid Login was unsuccessful"); }
  • 12. Mutable state Static objects if kept mutable leaves their values open to change by other code. /** Contains all the constant system property names */ public final class SystemPropertyConstants { public static String loginEndPoint = "/api/login/"; } // In some other code SystemPropertyConstants.loginEndPoint = "/api/logout/";
  • 13. What Can we do about it?
  • 14. “Make the framework smart so that the test code can be short and simple. Test code must be so concise that it doesn't matter which language is used to run it” - Martin Schneider ( Java Ninja @ Carousell )
  • 15. For concurrency issues public static ThreadLocal<WebDriver> driver; driver = new ThreadLocal<WebDriver>() { @Override protected WebDriver initialValue() { return new FirefoxDriver(); // You can use other driver based on your requirement. } }; OR use Dependency Injection with non-static object
  • 16. Design Use Object-Oriented programming concepts (abstraction, encapsulation, inheritance, polymorphism) to make your test code maintainable. new AuthPage().login("username","password"); SellingPage sellingPage = new HomePage().startSelling(); sellingPage .setCategory(Category.EVERYTHING_ELSE) .setItemDetails("Carousell Test Item",ConditionType.NEW,"Test Description") .setPrice("10.12") .setDealDetails(DealType.MEETUP,"Lets meetup at 5 PM") .listIt(); AND enhance them using Dependency Injection
  • 17. Mutable state To avoid static objects being overwritten by other code, declare them final /** Contains all the constant system property names */ public final class SystemPropertyConstants { public static final String loginEndPoint = "/api/login/"; }
  • 18. What is Dependency Injection???? Dependency Injection Dependency Non-Injection public class Employee { private Address address; public Employee() { address = new Address(); } } Employee employee = new Employee(new address); Employee employee = new Employee(); employee.setAddress(new Address());
  • 19. SellingPage sellingPage = new SellingPage(driver); // Injecting driver dependency in pageobjects @BeforeMethod public void setUp(ITestContext testContext){ ... } // DI used by TestNG
  • 20. Dependency Injection using a framework ● Use a DI framework instead of managing dependencies manually. ● DI frameworks: Spring, Google Guice, PicoContainer, Dagger ● These frameworks use IoC (Inversion of Control) container in which all the dependencies are registered, initialized and managed. ● IoC (Inversion of Control) - “Don’t call us, we call you” ● Once the dependencies are instantiated, the container injects them using approaches like: ○ Constructor injection ○ Setter method injection ○ Field injection
  • 21. Benefits of Dependency Injection ● Single Responsibility Principle ● Clean, Readable code ● Isolated components which become easy for testing as dependencies can be mocked without modifying depending class.
  • 22. How we can use Dependency Injection frameworks to simplify automation scripts. 22
  • 23. Spring Dependency Injection Spring IoC Container (where all the magic happens!) Configuration in Java class or XML Read dependency and configuration details Create dependency objects and inject them POJOs/ Java Classes part of your application code/test code Usable system with all dependencies available
  • 24. @Component @Configuration @Autowired @Bean Applied to fields, setter methods, and constructors. The @Autowired annotation injects object dependency implicitly. Used as config for Spring. Can have methods to instantiate and configure the dependencies Marks the Java class as a bean or component (i.e., you want Spring to manage this class instance) Applied to fields, setter methods, and constructors. The @Autowired annotation injects object dependency implicitly. Commonly used annotations in Spring Used for conditional loading of classes based on usecase (environment, platform etc) @Profile
  • 25. @Test() public void testNewListingAppearsInSearch() throws Exception { new WelcomePage(driver).beginSignUpOrLoginWithEmail(); new AuthPage(driver).login("username","password"); new HomePage(driver).startSellingWithPhotoFromCamera(); new CameraPage(driver).capturePhoto(); new CameraPhotoPreviewEditPage(driver).moveForward(); } } ● Driver is a dependency for PageObjects. ● PageObjects are a dependency for the test class (Is it necessary to create new instance of pageobject every time?)
  • 26. public class WelcomePage extends BasePage { private WebDriver driver; WelcomePage(WebDriver driver){ super(driver); this.driver = driver; } . . . . }
  • 27. @Configuration @ComponentScan(basePackages = "com.carousell") public class SpringContext { @Autowired private TestConfiguration configuration; private WebDriver driver; @Bean public WebDriver getWebDriver() { if(configuration.isWeb()){ driver = new ChromeDriver(); } else if(configuration.isAndroid() { driver = new AndroidDriver(); } else if(configuration.isIOS()) { driver = new IOSDriver(); } return driver; } Create a configuration class for Spring to manage dependencies
  • 28. public class WelcomePage extends BasePage { @Autowired private WebDriver driver; //You can move this to BasePage too . . . . }
  • 29. 29 @Component public class WelcomePage extends BasePage { @Autowired private WebDriver driver; //You can move this to BasePage too . . . . }
  • 30. @Autowired WelcomePage welcomePage; @Autowired AuthPage authPage; . . . . . @Test() public void testNewListingAppearsInSearch() throws Exception { welcomPage.beginSignUpOrLoginWithEmail(); authPage.login("username","password"); homePage.startSellingWithPhotoFromCamera(); cameraPage.capturePhoto(); cameraPhotoPreviewEditPage.moveForward(); //Use references directly as they are already injected with instance by Spring }
  • 31. public abstract class WelcomePage extends BasePage { } @Component @Profile(Platform.ANDROID) public class AndroidWelcomePage extends WelcomePage { } @Component @Profile(Platform.IOS) public class IOSWelcomePage extends WelcomePage { } spring.profiles.active=ANDROID - Initializes AndroidWelcomePage and injects into an Autowired variable.
  • 32. Sounds good. Where can I find real world implementation of such framework? Check out https://www.justtestlah.qa/
  • 33. Python: dependency_injector, Spring Python Ruby: sinject, dry-container C#: Spring.Net , Castle Windsor, Unity, Autofac Javascript: BottleJS, InversifyJS, DI-Ninja
  • 35. Reference Inversion of Control and Dependency Injection https://martinfowler.com/bliki/InversionOfControl.html https://martinfowler.com/articles/injection.html https://www.baeldung.com/inversion-control-and-dependency-injection-in-spring https://dzone.com/articles/a-guide-to-spring-framework-annotations https://stackoverflow.com/questions/52720198/how-does-spring-profile-work-with-inheritance Static methods and variables https://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil https://stackoverflow.com/questions/2671496/java-when-to-use-static-methods https://stackoverflow.com/questions/4002201/why-arent-static-methods-considered-good-oo-practice https://softwareengineering.stackexchange.com/questions/336701/static-services-and-testability Use of Dependency Injection in automation frameworks www.justtestlah.qa by Martin Schneider https://peterkedemo.wordpress.com/2013/03/30/writing-good-selenium-tests-with-page-objects-and-spring/

Editor's Notes

  1. Static objects represent global state and scope-less.
  2. this is just the tip of the iceberg that Spring offers. It's grown to become much more than a framework, Spring is actually an entire application development ecosystem. We only use spring-core to get the Spring container. Whether or not to use Spring in a testing framework depends on multiple factors, for example what other functionality is needed (for example, Spring has a good way of accessing web services). You could mention that Spring is not the most lightweight solution but one that's been around for many years and quite well maintained. Also chances are that engineers have experience with it (plus the experience they gain by using it is more valuable than e.g. just knowing Cucumber DI).