Automated Testing Overview & Best Practices

By: Randy Syring
Twitter: @RandySyring
...Software THAT WORKS! _images/level12-logo2.png

Introduction

_images/level12-logo.png

I'm the Chief Executive Developer at Level 12.

Level 12 is a web & database development firm that uses:

to make our customers really, really, happy.

Why it Matters to You

Net result: this works and is maintainable in the "real world"

Well, my "real world", YMMV

Some Numbers

Let's Talk

Audience Survey

I Don't Need No Stink'n Tests

_images/simple-form.png

I Don't...Need....ummm...help?

_images/complex-form.jpeg

Test Types Overview

Your definitions may differ.

Other Test Terms

Where To Begin?

Productive Testing

Test Centric Development (TCD)

TCD Guiding Principles

A Final Plea

You Can't Afford Not To

_images/roi-graph.png

No Automated Tests? Your World

_images/pisa.jpg

Dealing with Objectors

Tip #1: Easy Stuff First

Tip #1: Easy Stuff First

_images/roi-graph.png

Tip #2: Make Code Easier to Test

Code Testability Example

import requests

def get_project_bandwidth(project_name):
    url = 'https://pypi.python.org/pypi/{0}/json' \
        .format(project_name)
    resp = requests.get(url)

    data = json.loads(resp.text)
    total_bytes = 0
    for url in data['urls']:
        total_bytes += url['size'] * url['downloads']
    return total_bytes

Code Testability Example

def get_project_bandwidth(project_name):
    url = 'https://pypi.python.org/pypi/{0}/json' \
        .format(project_name)
    resp = requests.get(url)

    return calc_urls_bandwidth(resp.text)

def calc_urls_bandwidth(json):
    data = json.loads(json)
    total_bytes = 0
    for url in data['urls']:
        total_bytes += url['size'] * url['downloads']
    return total_bytes

Code Testability Example

def get_project_bandwidth(project_name):
    url = 'https://pypi.python.org/pypi/{0}/json' \
        .format(project_name)
    resp = requests.get(url)

    return calc_urls_bandwidth(resp.json)

def calc_urls_bandwidth(project_data):
    total_bytes = 0
    for url in project_data['urls']:
        total_bytes += url['size'] * url['downloads']
    return total_bytes

Tip #3: Easy Test Runs

Can't emphasize this enough, make it easy for people to run your tests!

$ git clone https://github.com/rsyring/bookorders example
$ cd example/
$ tox
[...snip...]
  py34: commands succeeded
  flake8: commands succeeded
  congratulations :)

Huge confidence booster!

Tip #3: Easy Test Runs

What are the challenges to doing this in your context?

Tip #4: Eat the Elephant

Focus on constant incremental improvements.

We have one simple rule: 'just increase code coverage by 1%'. We are constantly increasing code coverage by writing more test cases. Even if the increase is small, it is still a good thing to do.

Credit: http://jodd.org/beta.html

Don't get bogged down by the chaos, just start and then increase little by little.

Tip #5: Failing Tests Are Never OK!

Tip #6: Test Runs Should Be Fast

Tip #7: Know What You are [Not] Testing

Ask yourself regularily what you are trying to test

def contact_form(post_args):
    form = SomeForm(post_args)
    if form.is_completed():
        send_contact_email(post_args['name'],
            post_args['email'], post_args['body'])
    else:
        self.render(form.to_html())

Tip #8: Use Code Coverage Tools

_images/codecov-summary.png

Tip #8: Use Code Coverage Tools

_images/gh-codecov-comment.png

Tip #9:

_images/meme.jpg

Tip #9: Automate All The Things

Thanks For Attending

By: Randy Syring
Twitter: @RandySyring

ROI graph credit: Leonard Fingerman, http://www.slideshare.net/lfingerman/test-automation-best-prcatices-with-soa-test-approach