Overview ● Testing: Why? and What? ● Test Driven Development ● Behavior Driven Development ○ Acceptance & Unit Tests ○ Cucumber ○ RSpec ● Continuous Testing ● General Tips
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/
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?
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
● 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
Describe What it does vs What it is Specifying behavior leads to better design: ● Simpler interfaces ● Encapsulation ● Loose coupling ● High Cohesion Focus on Behavior
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
Acceptance Testing Integration tests + stakeholder collaboration Building the right system vs building the system right. ● Requirements ● Documentation ● Tests
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.
Unit Testing Designing small units of behavior for individual classes. ● Isolate classes while testing ● Simplify interfaces ● Use mock objects (test doubles)
Write automated tests for simple or complex systems in plain english (Gherkin) Expands upon Agile user stories Ideal for acceptance testing & stakeholder collaboration
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
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
● 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