Slide 1

Slide 1 text

Behavior Driven Development An introduction to automated testing for web developers

Slide 2

Slide 2 text

Overview ● Testing: Why? and What? ● Test Driven Development ● Behavior Driven Development ○ Acceptance & Unit Tests ○ Cucumber ○ RSpec ● Continuous Testing ● General Tips

Slide 3

Slide 3 text

What is a test? An assertion about an application, system or object based on defined requirements

Slide 4

Slide 4 text

What is testing? Building a collection of automated assertions (tests) to describe the software system.

Slide 5

Slide 5 text

Why do we test? ● Confidence ● Less bugs in production ● Automate tedious, error-prone steps ● Maintainability ● Scalability

Slide 6

Slide 6 text

What should you test? All code you want to have confidence in “Every test you write is an expense... Every test you don’t write is a risk” - Kent Beck

Slide 7

Slide 7 text

What should you NOT test? ● Code that is already tested ○ In a framework such as Rails ○ At a different level (integration testing controllers) ● Exploratory code (spikes) ● Textual content that will likely change ● Poor requirements ● External Web Services (FakeWeb) http://rubyrogues.com/what-not-to-test/

Slide 8

Slide 8 text

Writing tests first to drive design Red, Green, Refactor: 1. Write a failing test (Red) 2. Write code to make test pass (Green) 3. Refactor code What is Test Driven Development?

Slide 9

Slide 9 text

"Changing the internal design of existing software without affecting external behavior" What is Refactoring?

Slide 10

Slide 10 text

Refactoring Example: Event has two attendees, "Pete" and "Bob" ASSERT event.all_emails INCLUDES [email protected], [email protected]

Slide 11

Slide 11 text

def all_emails emails = Array.new event.users.each do |user| emails << user.email end return email end def all_emails event.users.map(&:email) end Refactoring Example:

Slide 12

Slide 12 text

Why practice TDD? ● Shorter feedback cycles ● Discover unknowns up front ● Better design through repetative red, green, refactor cycles ● You can't write failing tests with passing code ● Existing code can be harder to test

Slide 13

Slide 13 text

● Focus on behavior rather than testing ● Think (behave) as the end user ● Collaboration betweeen developers and stakeholders ● Requirements => Acceptance + Unit Tests ● BDD is a mindset as much as a technique Behavior Driven Development 101

Slide 14

Slide 14 text

Describe What it does vs What it is Specifying behavior leads to better design: ● Simpler interfaces ● Encapsulation ● Loose coupling ● High Cohesion Focus on Behavior

Slide 15

Slide 15 text

OOP Terminology Interface - Public methods and properties (API) Encapsulation - Hiding object internals (data) Loose Coupling - No or little dependence on other classes High Cohesion - Classes designed around related functions

Slide 16

Slide 16 text

Stakeholder Collaboration Requirements + Communication = :) Encourages outside-in development

Slide 17

Slide 17 text

Acceptance Testing Integration tests + stakeholder collaboration Building the right system vs building the system right. ● Requirements ● Documentation ● Tests

Slide 18

Slide 18 text

Acceptance Testing Continued Example: Signing up as a new user User Story: As someone without a user account I want to create a new account So that I can sign into the application Acceptance Test: User signs up for account, receives email, and can log into account.

Slide 19

Slide 19 text

Acceptance + Unit Tests Top down / outside in development

Slide 20

Slide 20 text

Unit Testing Designing small units of behavior for individual classes. ● Isolate classes while testing ● Simplify interfaces ● Use mock objects (test doubles)

Slide 21

Slide 21 text

BDD In Use - Tools of the Trade Cucumber - Cross platform, acceptance testing Rspec - Ruby BDD platform, ideal for unit tests Jasmine - JS BDD

Slide 22

Slide 22 text

Write automated tests for simple or complex systems in plain english (Gherkin) Expands upon Agile user stories Ideal for acceptance testing & stakeholder collaboration

Slide 23

Slide 23 text

Anatomy of a Cucumber Feature Title + Narrative Background Steps Scenario Steps

Slide 24

Slide 24 text

Cucumber Step Definitions

Slide 25

Slide 25 text

Cucumber Tips ● Use implicit (declarative) steps vs explicit (imperative) steps ● Avoid sharing state between steps ● Changing tests while refactoring may indicate design problems (especially if requirements have not changed) ● Refactor! ● Think as the end user

Slide 26

Slide 26 text

RSpec - Ruby BDD Framework ● Concise (readable) tests ● Ideal for Unit testing

Slide 27

Slide 27 text

Rspec Examples

Slide 28

Slide 28 text

RSpec Tips ● Avoid date/time dependencies ● Avoid testing internal data/state ● Lots of mocks = bad. ● Be consistent! ● Refactor!

Slide 29

Slide 29 text

Continuous Testing ● Rapid (instant) feedback loops ● Validate decisions as soon as they are made ● Bugs have shorter lifespan ● Fail early ● Tools: ○ Guard, Autotest, Watchr ○ Spork

Slide 30

Slide 30 text

● Requires practice & discipline ● Look for code smells ○ Hard to test code ○ Refactoring code and tests together ● Always start with a failing test ● Blame design over tests General Testing Tips

Slide 31

Slide 31 text

Qualities of Successful Tests ● Independence (Isolation) ● Repeatable ● Clarity ● Conciseness

Slide 32

Slide 32 text

Testing Resources ● StackExchange: ○ http://programmers.stackexchange.com/questions/99735/tdd-is-it-just-about-unit-tests ○ http://programmers.stackexchange.com/questions/tagged/tdd ○ http://programmers.stackexchange.com/questions/tagged/bdd ● Books: ○ http://pragprog.com/categories/design (Everything) ● Wikipedia: ○ http://en.wikipedia.org/wiki/Behavior_Driven_Development ○ http://en.wikipedia.org/wiki/Test_Driven_Development ● Podcasts: ○ ○ http://rubyrogues.com/001-rr-testing-practices-and-tools/

Slide 33

Slide 33 text

Thanks! Peter Brown @beerlington github.com/beerlington Alan Peabody @alanpeabody github.com/alanpeabody