midwestjs-2015-protractor



midwestjs-2015-protractor

0 1


midwestjs-2015-protractor

Presentation for MidwestJS 2015 overviewing the many merits of testing with Protractor

On Github willbuck / midwestjs-2015-protractor

Checking Your Angles & Angulars With

Protractor.js

Will Buck

Follow along with the slides @ tinyurl.com/wb-mjs-2015

Find the repo at @ tinyurl.com/wb-mjs-2015-code

- Don't forget your name, slick

A little about me

I like to play

- If you want to talk about sports or games I'm all ears - Or Florida (I'm a Disney buff)

I like MN

- Family (wife & daughter), - schools, - weather (yes even winter, cozy w/ cocoa) - Great tech community (co-organize AngularMN)

I like to code

- Standing desks rock, this is what I aspire to though - Full stack a little over 5 years now (primarily groovy) - TDD for most of that - Angular for > 2 - Open minded to try new tech but fall back to what I know to get things done - TRANSITION: But enough about me, let's talk about Protractor

Let's talk about E2E Testing

- Or perhaps I should say, let's talk a little about what Protractor does

What is E2E anyway?

- Different people will define it different ways, so let's clear up what I mean by it

No, not Easy E

E 2 E

- This isn't the movie Straight Outta Compton, though I am interested in seeing that

End-To-End Testing

Simulating the browser as the user will see it, integrations and all*

- caveat on integrations we'll talk about later

Why do we need End to End testing?

- So now that we've touched on what it is we're talking about, let's discuss why its important - We have unit tests (and we all write unit tests, right?), why do we need more tests?

Test what your

USERS

will see

- We can unit test until our fingers break, but ulitmately we're delivering software to users - It would be great to have a few tests that users can use our software in a useful way they'd expect - But there's so many other great reasons to learn E2E...

Smoke test builds

This is an easy win for a CI system!

- This saved a ton of back and fourth with our QA team - Empowered them to kick off builds - For those unfamiliar, we use the term smoke testing in software to mean that the build didn't cause anything to smoke - Where there's smoke there's a fire - Fun fact: the term smoke test is also used in mechanical engineering like the picture here to look for leaks

Automate boring stuff

Like time tracking entries (credit @jimthedev)

- Anything you don't like doing? Why not protractor?

But most importantly you

NEED IT

To Continuously Deliver

- By Continuously Deliver, I mean deploying code to customers whenever you check it in - This is a huge competitive advantage in speed to market - Also great for fostering a DevOps Culture - tests make Ops happy because then they don't get as many pages - tests are in easy to understand JS so easy for devs to write

Why not E2E?

- You may be saying to yourself 'This sounds so awesome, how am I not doing this already??' - I don't want you to walk away thinking E2E tests are a silver bullet - There are downsides as well, two big ones in particular you're likely to experience

They're Slow

- Like snail on a turtle's back slow - running a browser, clicking on things, simulating a user, these things take time

They're brittle

By adding up many little things, there are a multitude of reasons a test can break

- Brittle like peanut-brittle - Many of these reasons don't conceptually 'break' the functionality - But they certainly could cause your test as you wrote it to fail - Can also fail intermittently due to downtimes or hiccups in any of your potentially many integrations - We have some means of mitigating this, but they aren't perfect

How do we mitigate this?

Isolate the 5-10 tests that cover critical paths

Take care to test only core things after they're stable

- Small number of tests so devs can have a reasonably fast feedback loop - Can create suites if you still want heavier coverage - Testing only core stable features after they've solidified means they are unlikely to break easily - I'd recommend against TDD with E2E unless you've hardened a prototype of your user interaction pieces already

How do I only choose 5-10 core things?

Prioritize: what is most critical?

- This can be a good exercise in general to understanding "what provides the most value to me / my users" - For twitter, it's probably posting a text tweet, retrieving your following list's tweets, following a new user, and ads showing up - DMs, profile settings, lists, these are way less critical most likely

How do we accomplish this with Protractor?

tl:dr; check out the protractor home page

- There's a few key pieces to keep track of - The protractor home page goes over all of this really nicely

Install protractor

npm install protractor

-g or --save-dev optional

- Probably good to -g if you intend to do this regularly

A Spec(ification) of what we're testing

How the page should behave

describe('angularjs homepage todo list', function() {
  it('should add a todo', function() {
    browser.get('https://angularjs.org');

    element(by.model('todoList.todoText')).sendKeys('write first protractor test');
    element(by.css('[value="add"]')).click();

    var todoList = element.all(by.repeater('todo in todoList.todos'));
    expect(todoList.count()).toEqual(3);
  });
});
- Comment on default anatomy here: - jasmine desc/it/expect, - protractor element/by - Default is Jasmine but Mocha/Chai, Cucumber, etc also options

A Page Object describing interesting elements

  • Forces us to define 'key pieces' of the page
  • Separates concerns to keep specs cleaner
  • Reduces repetition (Stay DRY y'all)
- Discourage checking random elements willy nilly

A Configuration

protractor.conf.js

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['todo-spec.js']
};
- Tons of options here, be sure to check the docs (which browsers to run, preparation functions, etc)

That's all!

# in one console
webdriver-manager update && webdriver-manager start
# in another
protractor protractor.conf.js
# Or have your conf do both! just omit seleniumAddress &
# Make sure you ran webdriver-manager update
- Really pretty easy to get started with - Mind the conference wifi running npm install if you're trying to follow along though ;) - TRANSITION: So, now that we know what we need to get started, lets check out how we test some web pages!

Sites Without Angular

YES, YOU CAN!

- You can test ANY website with Protractor, despite it being tailored for Angular - Any combination of css, html and js you can reach with a browser, you can write tests for - Some things are a little less ideal without angular, but overall I found it very useful

A little setup to do

In your conf:

exports.config = {  
  onPrepare: function() {
    global.isAngularSite = function(flag){
        browser.ignoreSynchronization = !flag;
    };
  }
};

Before all your tests:

beforeEach(function() {
  isAngularSite(false);
});
- Need this to avoid waiting for angular failures - If you don't have this, non-angular sites WILL fail

How do I even selector?

NOT with by.model, I'll tell you that

- Many examples show uses of by.model or by.binding or by.repeater - Regular websites don't have these angular-specific concepts - We'll be getting some sugar from protrator, but you'll essentially be doing webdriver w/ promises - What do I mean by that?

Get your $ on

by.css() and by.xpath() are your friends here

// from test-midwestjs.com/homepage.po.js
this.littleBirdie = element(by.css('div#logo div a:first-child'));
- If you're familiar with jquery you'll probably feel right at home with css selectors - Do note though, these can get busted inadvertantly by a CSS / HTML developer - It probably won't feel like they did anything wrong either - Often this is mitigated by using ids on critical elements: - This approach abstracts semantic meaning IMO but I haven't seen great alternatives - If you have, please tweet it out and share your knowledge :)

Let's see it in action!

MidwestJS Site

Using Protractor to test Angular Apps

(a.k.a. the tool's primary aim)

- We've seen that we can test non-angular apps and that can be useful, but - This is what we're really meant to do with the tool

Tests Become More Robust

Less likely to change than CSS selectors

// from test-prizeotron/main.po.js
this.apiKeyInput = element(by.model('api.key'));
this.remainingBadge = element(by.binding('rsvps.length'));
this.attendeeList = element(by.repeater('rsvps'))
- Since we're binding directly to our variable names, we can separate any CSS styling / element layout concerns from our testing bindings - We even have projects like Ramon Victor's gulp-protractor-qa - That project will do static analysis on all your element selectors and warn you early which are busted

Mocking out HTTP calls

- This is the caveat I mentioned earlier - Note that this is kind of losing our full E2E definition - Users will see the REAL site with REAL API calls

Let's see Protractor testing Angular in action!

The Amazing Prize-o-tron

Angular 2 Prize-o-tron rewrite!

Join us here!

Some Gotchas

Here are some of the things I bumped into as I learned that got me stuck on occasion. Hopefully they will prove useful for you

Promises

This helps explain

- Control flow is part of the picture - Read this: https://github.com/angular/protractor/blob/master/docs/control-flow.md

Console Errors

Can get missed. Try this

afterEach(function () {
  browser.manage().logs().get('browser').then(function (browserLog) {
    expect(browserLog.length).toEqual(0);
  });
});

Source: Egghead.io

- Helps catch errors your tests can be missing

Caution: by.buttonText is very choosy!

Try by.partialButtonText

this.importButton = element(by.partialButtonText('Import')); // Iffy

or by.css with the ng-click attribute

this.importButton = element(by.css('[ng-click="importNames()"]'))
// note that it might be data-ng-click
- Pick a strategy and stick to it, be clear across your team - Prefer the users perspective (text) or prgrammers (ng-click)

What if I get stuck?

protractor --elementExplorer
# Then browser.get('http://mywebsite.com')
# Then element(by.css('div#mySelector')).getText() or whatever you want to do with the element

Protractor Debugging Tips Page

What About Continuous Integration & Delivery?

What do you control?

npm install protractor # do this globally ONCE if you have control
./node_modules/protractor/bin/webdriver-manager update
./node_modules/protractor/bin/protractor snapci.conf.js --suite midwestjs
- If you DO have control, having protractor

It helps to have reports

onPrepare: function(){
    jasmine.getEnv().addReporter(new HtmlReporter({
        baseDirectory: './target/test-results/screenshots'
    }));
},
"devDependencies": {
    "protractor": "^2.1.0",
    "protractor-html-screenshot-reporter": "0.0.20"
}

Lets see it in action!

I used snapci.com

- Keep this brief, watch the clock

Other Related Tools

- Some things that can help with Protractor or use Protractor

Sauce Labs

Browser options you don't have to manage!

- Tons of browsers supported - Means you don't have to manage the browser runtime envs (good bye Windows server / fleet of mobile devices?) - Useful if you're like us, have to support IE8, and don't want to deal with keeping an IE8 capable machine alive - (We don't actually use them, but I think it'd help us)

BENCHPRESS

DO YOU EVEN LIFT??

- For MACRO level benchmarking / performance testing - I don't know a ton about it, but I do have a folder in this repo capable of tinkering with it - Use case: getting an idea of where your site is at & then setting build thresholds that you don't make it worse - And now for a bit of a thriller ending to the talk...

I have a confession

I've only been doing this for two months

- Hopefully you weren't expecting expertise - Now some of you might think...

You're Crazy Man

- Call for proposals ended several months before I'd written any Protractor at all - Isn't that a bad idea

What was your angle thinking you'd do this talk then?

- Hurf durf angle jokes

I was daring myself to Learn

- I wanted to prove something to myself, and to the community

I wanted to prove that...

  • I could learn things I'm interested in, with my spare time
  • E2E testing can provide a lot of value
  • E2E testing doesn't have to be as hard as it's been in the past
  • You don't have to be an 'expert' to give a conference talk
- I know this is off topic but I think it's important to say

NO ONE

Should have to be afraid to share what they learn

- Two second rant here, but you're my captive audience XD - This should be a welcoming community - But harassment really happens and that sucks - I have a lot of priviledge as a large straight white guy who got on the job training from really smart people - People of marginalized groups need to feel welcome - Regardless of race, gender, religion or sexual orientation - We have a lot to learn from diverse perspectives - It will help us make better software - So what can you do to help this happen?

Speak up & amplify voices

- It may seem hard to solve the big problem that is discrimination and uncivil behavior - But these are two small ways you can help change our culture - Be welcoming of new ideas - Speak up when you see someone being inappropriate or close-minded - Amplify the voices of those with diverse perspectives that you respect and admire

I hope this provided some value to someone

If it did, I'm cool

Thank You for listening!

Resources

Link to resources.md in this repo's github

- Pretty much all the links I used are in here

Any Questions?

Please let there be some, you can have a sticker for asking one

- If you want to be 10 years old like me and collect super cool stickers