SlideShare a Scribd company logo
1 of 45
Download to read offline
Polyglot Automation
@yashakaautomician.com 12.2016
Preface…
@yashaka
What Language?
Automation
=
Automating manual routine work
Automation
=>
QA 

???
Effective Automation
=>
QA
Polyglot Automation
=
Using Any Language to make it Effective
Effective Automation
*=
with Backend Language
Web UI
Why?
Developers can help with implementation
Easier for devs to use and support tests
Smaller Tech Stack. No Zoo at project :)
And…
Allows to use fast & efficient test data pre-setup!
Demo
Full coverage for TodoMVC:
Without “backend” preconditions: 22s
With “backend” preconditions: 17s
=> optimised for 23%
A remark
TodoMVC is very simple app with small light-weight
“preconditions” in tests
Real app will usually have much more “hard-weight”
preconditions
So the optimisation may be much bigger
But it’s hard,
no?
Hard to:
learn new language…
use statically typed Java/C# over dynamic Python/
Ruby…
?
No:p
No:p
if you use “easy tools” ;)
Examples
Tests
public class TodoMVCTest {



@Test

public void testFilterTasks(){

Tasks.visit();



Tasks.add("a", "b", "c");

Tasks.shouldBe("a", "b", "c");



Tasks.toggle("b");



Tasks.filterActive ();

Tasks.shouldBe("a", "c");



Tasks.filterCompleted ();

Tasks.shouldBe("b");

}

}
[TestFixture ()]

public class Test : BaseTest

{

[Test ()]

public void FilterTasks ()

{

Tasks.Visit ();



Tasks.Add ("a", "b", "c");

Tasks.ShouldBe ("a", "b", "c");



Tasks.Toggle ("b"); 



Tasks.FilterActive ();

Tasks.ShouldBe ("a", "c");



Tasks.FilterCompleted ();

Tasks.ShouldBe ("b");

}

}
class TestTodoMVC(BaseTest):



def test_filter_tasks(self):



tasks.visit()



tasks.add("a", "b", "c")

tasks.should_be("a", "b", "c")



tasks.toggle("b")



tasks.filter_active ()

tasks.should_be("a", "c")



tasks.filter_completed ()

tasks.should_be("b")
describe "todomvc" do


it "filters tasks" do

Tasks.open

Tasks.add "a", "b", "c"

Tasks.should_be "a", "b", "c"



Tasks.toggle "b"



Tasks.filter_active

Tasks.should_be "a", "c"



Tasks.filter_completed

Tasks.should_be "b"

end

end
Helpers
simpler
public class Tasks {



...

public static void visit() {


open("https: //todomvc4tasj.herokuapp.com/");

}



public static void filterActive(){


$(By.linkText("Active")).click();

}



public static void filterCompleted(){


$(By.linkText("Completed")).click();

}



public static void add(String ... taskTexts) {


for(String text: taskTexts){


$("#new-todo").setValue(text).pressEnter();

}

}
...

}
public static class Tasks

{

... 

public static void Visit()

{

Open("https: //todomvc4tasj.herokuapp.com/");

}



public static void FilterActive()

{

S(By.LinkText("Active")).Click();

}



public static void FilterCompleted()

{

S(By.LinkText("Completed")).Click();

}



public static void Add(params string [] taskTexts)

{

foreach(var text in taskTexts) 

{

S("#new-todo").SetValue(text).PressEnter();

}

}
...

}
…
def visit():



tools.visit("https: //todomvc4tasj.herokuapp.com/")





def filter_active():



s(by_link_text("Active")).click()





def filter_completed():



s(by_link_text("Completed")).click()





def add(*task_texts):



for text in task_texts:


s("#new-todo").set_value(text).press_enter()
module Tasks

extend Capybara ::DSL

def self.open


visit 'https: //todomvc4tasj.herokuapp.com'

end


def self.filter_active


find("a", text:"Active").click

end



def self.filter_completed


find("a", text:"Completed").click

end



def self.add *task_texts


task_texts.each do |text|


find("#new-todo").send_keys(text, :enter)

end

end



...

end
Helpers
a bit harder
public class Tasks {



public static ElementsCollection tasks = $$("#todo-list>li");



...


public static void toggle(String taskText) {


tasks.findBy(exactText(taskText)).find(".toggle").click();

}



public static void shouldBe(String ... taskTexts) {


tasks.filterBy(visible).shouldHave(exactTexts(taskTexts));

}

}
public static class Tasks

{

public static SCollection List = SS("#todo-list>li"); 



...



public static void Toggle (string taskText)

{

List.FindBy(Have.ExactText(taskText)).Find(".toggle").Click();

}



public static void ShouldBe(params string [] names)
{

List.FilterBy(Be.Visible).Should(Have.Texts(names));

}

}
tasks = ss("#todo-list>li")



...
def toggle(task_text):



tasks.findBy(exact_text(task_text)).find(".toggle").click()





def should_be(*task_texts):



tasks.filterBy(visible).should_have(exact_texts(*task_texts))
module Tasks

extend Capybara ::DSL



def self.tasks

all "#todo-list>li"

end


...

def self.toggle task_text


(tasks.findBy {|task| task.text == task_text}).find(".toggle").click

end



def self.should_be *task_texts


tasks.texts.should == task_texts

end

end
Easy?
Easy Tools?
Java: Selenide
Python: Selene is coming…
C#: NSelene is coming…
Ruby: Capybara
? JavaScript: Protractor
? PHP: Codeception
No ready Easy Tool for your
language?
Lack of knowledge?
=> ask project’s developers to write it for you
Brave?
=> implement it by your own
How to become polyglot
automation engineer?
Just learn ONE Language perfectly.
Then
Don’t be afraid to switch to other when it fits better
Learn next language
learnxinyminutes.com
+

koans
+
practice solving common tasks
like exercism.io
+
google.com
Afterwords
There are good practices in context,
but there are no best practices.
(c) Cem Kaner, James Bach
Q&A
github.com/yashaka
facebook/yashaka
twitter.com/yashaka
yashaka@gmail.com
automician.com
seleniumcourses.com
Thank you
@yashaka12.2016

More Related Content

Viewers also liked

Pivotal Failure - Lessons Learned from Lean Startup Machine DC
Pivotal Failure - Lessons Learned from Lean Startup Machine DCPivotal Failure - Lessons Learned from Lean Startup Machine DC
Pivotal Failure - Lessons Learned from Lean Startup Machine DC
Dave Haeffner
 
Agile testing for mere mortals
Agile testing for mere mortalsAgile testing for mere mortals
Agile testing for mere mortals
Dave Haeffner
 
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшeQA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QAFest
 

Viewers also liked (19)

Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015Polyglot automation - QA Fest - 2015
Polyglot automation - QA Fest - 2015
 
Write Selenide in Python 15 min
Write Selenide in Python 15 minWrite Selenide in Python 15 min
Write Selenide in Python 15 min
 
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
 
Automation is Easy! (python version)
Automation is Easy! (python version)Automation is Easy! (python version)
Automation is Easy! (python version)
 
Better Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component PatternBetter Page Object Handling with Loadable Component Pattern
Better Page Object Handling with Loadable Component Pattern
 
Pivotal Failure - Lessons Learned from Lean Startup Machine DC
Pivotal Failure - Lessons Learned from Lean Startup Machine DCPivotal Failure - Lessons Learned from Lean Startup Machine DC
Pivotal Failure - Lessons Learned from Lean Startup Machine DC
 
Selenium
SeleniumSelenium
Selenium
 
Continuous Testing Meets the Classroom at Code.org
Continuous Testing Meets the Classroom at Code.orgContinuous Testing Meets the Classroom at Code.org
Continuous Testing Meets the Classroom at Code.org
 
Web testing with Selenium
Web testing with SeleniumWeb testing with Selenium
Web testing with Selenium
 
Agile testing for mere mortals
Agile testing for mere mortalsAgile testing for mere mortals
Agile testing for mere mortals
 
How To Use Selenium Successfully
How To Use Selenium SuccessfullyHow To Use Selenium Successfully
How To Use Selenium Successfully
 
Full Stack Testing Done Well
Full Stack Testing Done WellFull Stack Testing Done Well
Full Stack Testing Done Well
 
The Testable Web
The Testable WebThe Testable Web
The Testable Web
 
Selenium Basics
Selenium BasicsSelenium Basics
Selenium Basics
 
Cross Platform Appium Tests: How To
Cross Platform Appium Tests: How ToCross Platform Appium Tests: How To
Cross Platform Appium Tests: How To
 
Getting Started with Selenium
Getting Started with SeleniumGetting Started with Selenium
Getting Started with Selenium
 
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшeQA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
QA Fes 2016. Алексей Виноградов. Page Objects: лучше проще, да лучшe
 
Bdd lessons-learned
Bdd lessons-learnedBdd lessons-learned
Bdd lessons-learned
 
Selenium Users Anonymous
Selenium Users AnonymousSelenium Users Anonymous
Selenium Users Anonymous
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Recently uploaded (20)

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 

Polyglot Automation - Miami - 2016

  • 7. Polyglot Automation = Using Any Language to make it Effective
  • 10. Developers can help with implementation Easier for devs to use and support tests Smaller Tech Stack. No Zoo at project :) And…
  • 11. Allows to use fast & efficient test data pre-setup!
  • 12. Demo
  • 13.
  • 14. Full coverage for TodoMVC: Without “backend” preconditions: 22s With “backend” preconditions: 17s => optimised for 23%
  • 15. A remark TodoMVC is very simple app with small light-weight “preconditions” in tests Real app will usually have much more “hard-weight” preconditions So the optimisation may be much bigger
  • 17. Hard to: learn new language… use statically typed Java/C# over dynamic Python/ Ruby… ?
  • 18. No:p
  • 19. No:p if you use “easy tools” ;)
  • 21.
  • 22. Tests
  • 23. public class TodoMVCTest {
 
 @Test
 public void testFilterTasks(){
 Tasks.visit();
 
 Tasks.add("a", "b", "c");
 Tasks.shouldBe("a", "b", "c");
 
 Tasks.toggle("b");
 
 Tasks.filterActive ();
 Tasks.shouldBe("a", "c");
 
 Tasks.filterCompleted ();
 Tasks.shouldBe("b");
 }
 }
  • 24. [TestFixture ()]
 public class Test : BaseTest
 {
 [Test ()]
 public void FilterTasks ()
 {
 Tasks.Visit ();
 
 Tasks.Add ("a", "b", "c");
 Tasks.ShouldBe ("a", "b", "c");
 
 Tasks.Toggle ("b"); 
 
 Tasks.FilterActive ();
 Tasks.ShouldBe ("a", "c");
 
 Tasks.FilterCompleted ();
 Tasks.ShouldBe ("b");
 }
 }
  • 25. class TestTodoMVC(BaseTest):
 
 def test_filter_tasks(self):
 
 tasks.visit()
 
 tasks.add("a", "b", "c")
 tasks.should_be("a", "b", "c")
 
 tasks.toggle("b")
 
 tasks.filter_active ()
 tasks.should_be("a", "c")
 
 tasks.filter_completed ()
 tasks.should_be("b")
  • 26. describe "todomvc" do 
 it "filters tasks" do
 Tasks.open
 Tasks.add "a", "b", "c"
 Tasks.should_be "a", "b", "c"
 
 Tasks.toggle "b"
 
 Tasks.filter_active
 Tasks.should_be "a", "c"
 
 Tasks.filter_completed
 Tasks.should_be "b"
 end
 end
  • 28. public class Tasks {
 
 ...
 public static void visit() { 
 open("https: //todomvc4tasj.herokuapp.com/");
 }
 
 public static void filterActive(){ 
 $(By.linkText("Active")).click();
 }
 
 public static void filterCompleted(){ 
 $(By.linkText("Completed")).click();
 }
 
 public static void add(String ... taskTexts) { 
 for(String text: taskTexts){ 
 $("#new-todo").setValue(text).pressEnter();
 }
 } ...
 }
  • 29. public static class Tasks
 {
 ... 
 public static void Visit()
 {
 Open("https: //todomvc4tasj.herokuapp.com/");
 }
 
 public static void FilterActive()
 {
 S(By.LinkText("Active")).Click();
 }
 
 public static void FilterCompleted()
 {
 S(By.LinkText("Completed")).Click();
 }
 
 public static void Add(params string [] taskTexts)
 {
 foreach(var text in taskTexts) 
 {
 S("#new-todo").SetValue(text).PressEnter();
 }
 } ...
 }
  • 30. … def visit():
 
 tools.visit("https: //todomvc4tasj.herokuapp.com/")
 
 
 def filter_active():
 
 s(by_link_text("Active")).click()
 
 
 def filter_completed():
 
 s(by_link_text("Completed")).click()
 
 
 def add(*task_texts):
 
 for text in task_texts: 
 s("#new-todo").set_value(text).press_enter()
  • 31. module Tasks
 extend Capybara ::DSL
 def self.open 
 visit 'https: //todomvc4tasj.herokuapp.com'
 end 
 def self.filter_active 
 find("a", text:"Active").click
 end
 
 def self.filter_completed 
 find("a", text:"Completed").click
 end
 
 def self.add *task_texts 
 task_texts.each do |text| 
 find("#new-todo").send_keys(text, :enter)
 end
 end
 
 ...
 end
  • 33. public class Tasks {
 
 public static ElementsCollection tasks = $$("#todo-list>li");
 
 ... 
 public static void toggle(String taskText) { 
 tasks.findBy(exactText(taskText)).find(".toggle").click();
 }
 
 public static void shouldBe(String ... taskTexts) { 
 tasks.filterBy(visible).shouldHave(exactTexts(taskTexts));
 }
 }
  • 34. public static class Tasks
 {
 public static SCollection List = SS("#todo-list>li"); 
 
 ...
 
 public static void Toggle (string taskText)
 {
 List.FindBy(Have.ExactText(taskText)).Find(".toggle").Click();
 }
 
 public static void ShouldBe(params string [] names) {
 List.FilterBy(Be.Visible).Should(Have.Texts(names));
 }
 }
  • 35. tasks = ss("#todo-list>li")
 
 ... def toggle(task_text):
 
 tasks.findBy(exact_text(task_text)).find(".toggle").click()
 
 
 def should_be(*task_texts):
 
 tasks.filterBy(visible).should_have(exact_texts(*task_texts))
  • 36. module Tasks
 extend Capybara ::DSL
 
 def self.tasks
 all "#todo-list>li"
 end 
 ...
 def self.toggle task_text 
 (tasks.findBy {|task| task.text == task_text}).find(".toggle").click
 end
 
 def self.should_be *task_texts 
 tasks.texts.should == task_texts
 end
 end
  • 37. Easy?
  • 39. Java: Selenide Python: Selene is coming… C#: NSelene is coming… Ruby: Capybara ? JavaScript: Protractor ? PHP: Codeception
  • 40. No ready Easy Tool for your language? Lack of knowledge? => ask project’s developers to write it for you Brave? => implement it by your own
  • 41. How to become polyglot automation engineer? Just learn ONE Language perfectly. Then Don’t be afraid to switch to other when it fits better
  • 42. Learn next language learnxinyminutes.com +
 koans + practice solving common tasks like exercism.io + google.com
  • 43. Afterwords There are good practices in context, but there are no best practices. (c) Cem Kaner, James Bach
  • 44. Q&A