Download presentation
Presentation is loading. Please wait.
1
Developer Testing Tricks
Brian Takita, Pivotal Labs
2
Abstract This presentation will go over a number of testing technologies and methodologies that will increase the odds of success for Rails projects. The goals of the talk is to, present a set of testing related situations and experience in solving a number of issues, raise the audiences' awareness over effective ways of communicating through tests, and emphasize skills and courage to solve testing issues.
3
Reasons to Test Executable specifications
TDD – Make your design better Verification - Keep your code safe Support experimentation and refactoring Empirical software development
4
Focus of Tests Method Manual Automated Audience Customer Developer
Scope Unit Functional Integration
5
Granularity of Tests Happy Path Testing Edge Case Testing
6
Happy Path Testing Tests the piece of functionality in a "normal" situation Quick and dirty way to see if your functionality is working Useful in integration and functional tests
7
Happy Path Selenium Example
describe "A User on the home page" do before do open "/" end describe "clicking the up vote" do describe "when logged in" do @user = users(:quentin) element(“link=Login”).click element("name=password").type('test') element("name=commit").click it "increments the vote count by 1" do element("css=.score").assert_contains('0') element("css=.up").click element("css=.score").assert_contains('1')
8
Edge Case Testing Tests the edge cases of the piece of functionality
Invalid Data Invalid fixture state Ensures full code coverage Useful in Unit tests
9
Edge Case Testing VoteSubmissions::UpVoteSubmissionsController
POST create when not logged in redirects to SessionsController#new when logged in and passed invalid data does not create a Vote responds with an error and passed valid data and the User does not have a Vote for the PainPoint creates a Vote responds with json representation of the User data of the PainPoint and the User has a Vote for the PainPoint does not create a new Vote sends an up_vote event to the existing Vote
10
Lifecycle of a Test TDD Tests to drive the design of the software
Regression Testing Tests to ensure that your software still works when you make changes Retirement of a Test Tests that are no longer useful
11
TDD Red -> Green -> Refactor
Write the tests first, then implement the software These tests drive design Tests should be refactored You can manually test drive your code, its just slower and you dont get to keep the tests
12
Goals of TDD Specification, not validation Feedback
Developer makes smaller steps Developer knows when the code is finished Developer has an example of using the implementation code Developer maintains focus on the objective Fast Iterations Developer rhythm Confidence Simplicity YAGNI (You Aint Gonna Need It) Make a regression test
13
TDD – Test your tests Red -> Green -> Refactor
Its easy to make a test that does not test anything For example, testing the elements within an empty collection Use Preconditions to set the context of your test
14
Retroactive TDD Comment out the implementation you want to test
Write the tests Watch them fail for expected reasons Uncomment the implementation Watch the tests pass Refactor
15
Regression Test After the TDD phase, your tests serve to make sure your software still works Tests live longer than the code (the implementation often changes)
16
Regression Test Goals Verify your software does not break due to changes in implementation or state Courage Support Experimentation & Refactoring Documentation Clarity Fail in the right places Avoid crying wolf due to unnecessary brittleness Keep tests predictable
17
Regression Test - Documentation
Tests should clearly document your system Refactor the test if it is not clear or focused Nested ExampleGroups are very helpful in showing contextual logic Unit tests should match the logical layout of your software
18
Regression Test – Clarity and Focus
User sends messages to friends and receives replies from them ↲ when the friend responds back otherwise no reply is sent User #send_message sends a Message to a friend #receive_message receives a Message from a friend
19
Monitoring your tests Are you getting good coverage?
Are these tests still relevant? How often do these tests fail? How long does your suite take to run? Are your tests easy to run or do they get in the way?
20
TDD & Regression Testing
Their goals are not necessarily aligned Things change What is relevant today is not tomorrow Refactor early and often
21
Retirement of a Test If the test no longer contributes to logical coverage in its particular scope (unit, functional, integration, etc), then retire it.
22
Obsolete Tests They add clutter and make your test suite harder to read and reason about They take time to run They take space
23
Testing Untested Software
Working Effectively with Legacy Code - Michael Feathers Seams Places where you can alter behavior without editing the code Dont forget to Retroactively TDD test your tests Rails MVC separation makes it easier to add tests later
24
Consequences of Refactoring
Extract class or module refactoring can be supported by existing tests You may or may not need to test drive the extracted module It depends on your situation If you are unsure, error on the side of writing tests
25
Why Test Drive your refactorings
You can get defect localization The tests help the design of your extracted module
26
Why Not Test Drive your refactorings
TDD may disrupt your "refactoring flow" You may want your refactoring to be a spike to quickly experiment on an idea You can always retroactively TDD your changes You already have test coverage
27
When finished with the refactoring
Refactor your tests Move the tests into the correct places Use abstraction in your tests by verifying that the dependencies are utilized
28
Test Fixture Fixed state to be used as a baseline for your tests
Mock & Stubs Instantiated Fixtures Transactional Fixtures Fixture Scenario Object Mother
29
Test Drive Fixtures Verify your fixtures are in a valid state
Test drive a change to your DB schema by making a fixture test Verifies that your fixtures reflect reality Keeps your fixtures maintainable Discourages your fixture set from getting large describe "users.yml" do attr_reader :user describe "bob" do before do @user = users(:bob) end specify "was in the green and red room" do user.rooms.should include(rooms(:green)) user.rooms.should include(rooms(:red))
30
Fixture Scenarios http://code.google.com/p/fixture- scenarios/
describe User do describe “enter” do describe “when all of the rooms are full” do scenario :all_rooms_are_full it “raises a NoRoomAvailableError” do user = users(:bob) lambda {user.enter}.should raise_error(NoRoomAvailableError) end
31
One off cases You do not necessarily need to make a new fixture
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.