Polyglot Automation - Miami - 2016

Post on 07-Jan-2017

145 views 2 download

transcript

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:pif 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" endend

Helperssimpler

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

Helpersa 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 endend

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 languagelearnxinyminutes.com

+ koans

+ practice solving common tasks

like exercism.io +

google.com

AfterwordsThere 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