Unit%20Testing%20in%20Ruby - PowerPoint PPT Presentation

About This Presentation
Title:

Unit%20Testing%20in%20Ruby

Description:

The majority of large programming projects fail. Projects that succeed are usually full of bugs ... The time spent maintaining a program far exceeds (10x? ... – PowerPoint PPT presentation

Number of Views:78
Avg rating:3.0/5.0
Slides: 21
Provided by: davidma
Category:

less

Transcript and Presenter's Notes

Title: Unit%20Testing%20in%20Ruby


1
Unit Testing in Ruby
2
Programming methodologies
  • The grim facts
  • The majority of large programming projects fail
  • Projects that succeed are usually full of bugs
  • Modifying and debugging programs usually
    introduces yet more bugs
  • Hence, it is hazardous to modify a working
    program
  • The time spent maintaining a program far exceeds
    (10x?) the amount of time it took to write the
    program
  • Programming methodologies are attempts to solve
    these problems by properly organizing programs
    and/or programmers
  • The current (and best) methodologies are the
    agile methodologies
  • Agile means writing software that is easily
    changed
  • XP (Exteme Programming) is the best known agile
    methodology
  • XP tends to work best for small groups of
    programmers

3
Some ideas from agile programming
  • There is no silver bullet, but agile
    methodologies are the best we have at present
  • Most large programming projects fail, so...
  • Write the simplest thing that can possibly
    work.
  • Always have a working version, no matter how
    little it does
  • Never add a feature until all known bugs have
    been fixed
  • Any code that hasnt been tested is assumed to be
    wrong
  • Have tests for all code, and keep it up to date
  • Run tests frequentlyvery frequently
  • Tests must be trivially easy to run, or you wont
    bother running them

4
Test suites
  • Obviously you have to test your code to get it
    working in the first place
  • You can do ad hoc testing (running whatever tests
    occur to you at the moment), or
  • You can build a test suite (a thorough set of
    tests that can be run at any time)
  • Disadvantages of a test suite
  • Its a lot of extra programming
  • This is true, but use of a good test framework
    can help quite a bit
  • You dont have time to do all that extra work
  • FalseExperiments repeatedly show that test
    suites reduce debugging time more than the amount
    spent building the test suite
  • Advantages of a test suite
  • Reduces total number of bugs in delivered code
  • Makes code much more maintainable and
    refactorable
  • This is a huge win for programs that get actual
    use!

5
XP approach to testing
  • In the Extreme Programming approach,
  • Tests are written before the code itself
  • If code has no automated test case, it is assumed
    not to work
  • A test framework is used so that automated
    testing can be done after every small change to
    the code
  • This may be as often as every 5 or 10 minutes
  • If a bug is found after development, a test is
    created to keep the bug from coming back
  • Consequences
  • Fewer bugs
  • More maintainable code
  • Continuous integrationDuring development, the
    program always worksit may not do everything
    required, but what it does, it does right

6
Terminology
  • A test fixture sets up the data (both objects and
    primitives) that are needed to run tests
  • Example If you are testing code that updates an
    employee record, you need an employee record to
    test it on
  • A unit test is a test of a single class
  • A test case tests the response of a single method
    to a particular set of inputs
  • A test suite is a collection of test cases
  • A test runner is software that runs tests and
    reports results
  • An integration test is a test of how well classes
    work together
  • JUnit provides some limited support for
    integration tests

7
Once more, in pictures
test suite
  • A unit test tests the methods in a single class
  • A test case tests (insofar as possible) a single
    method
  • You can have multiple test cases for a single
    method
  • A test suite combines unit tests
  • The test fixture provides software support for
    all this
  • The test runner runs unit tests or an entire test
    suite
  • Integration testing (testing that it all works
    together) is not well supported by JUnit

unit test (for one class)
test case (for one method)
another test case
test fixture
8
The test runner
  • The test runner runs all your tests
  • If they all succeed, you get a green bar
  • If any fail, you get a red barand links to the
    tests that failed

9
How not to write a unit test
  • Unit tests must be fast and easy to runor you
    wont run them
  • The only output you should need to look at, in
    order to see that all tests passed, at is the
    green bar
  • Of course, if you get a red bar, you need to
    explore further
  • Dont do any output from your unit tests!
  • Ideally, the methods you are testing should not
    do any output
  • In most well-written programs, there is a
    separation of concernsmethods either compute or
    do output, but not both
  • It is possible to write unit tests for methods
    that do output, but that is a slightly advanced
    topic I wont cover here

10
How to write a unit test class
  • A unit test class is a class you write that
    extends TestUnitTestCase
  • You will need the line require 'test/unit'
  • Your test class will inherit the following
    methods
  • def setup
  • This a method that will be called before each of
    your test methods
  • Typically, you will override this method and use
    it to assign values to some instance variables
    you need in testing
  • def teardown()
  • This a method that will be called after each of
    your test methods
  • Typically you will just ignore this method,
    unless you need to close files
  • You will also write any number of test methods,
    all of which have the form def test_Something
  • Something is usually, but not necessarily, the
    name of the method you want to test
  • Inside each test method, you will do some
    computations and call one or more assert methods
    to test the results

11
Available assertion methods
  • assert boolean
  • assert_equal expected, actual
  • Uses
  • assert_same expected, actual
  • Uses equal?
  • assert_not_equal expected, actual
  • assert_not_same expected, actual
  • assert nil object
  • assert not_nil object
  • assert_block block
  • All these methods can take an additional message
    argument
  • This is not a complete listing of the assert
    methods
  • The first two methods are by far the most
    commonly used

12
Structure of a unit test
  • require "test/unit"require "file_to_be_tested"c
    lass CountTest lt TestUnitTestCase def
    setup Perform initializations here end
    def test_some_method Tests go here end
    def teardown Release any resources (usually
    not needed) endend

13
Testing for exceptions
  • Methods should throw exceptions if they are
    called incorrectly
  • You can test whether a method throws an exception
    when it ought to
  • def test_exceptions begin Call the
    method that should throw an exception rescue
    Exception or you can test for specific
    exceptions return The exception
    happened, so the test passes end
    flunkend
  • Ruby also has assert_raise and assert_throws
    methods, but I havent been able to make them work

14
A complete example
  • class Counter attr_reader value
  • def initialize _at_value 0 end
  • def increment n if n _at_value
    1 else _at_value n0 end end
  • def reset _at_value 0 end end

15
The test class, part 1
  • require "test/unit"require "counter"class
    CountTest lt TestUnitTestCase
  • def setup _at_c Counter.new end
  • def test_increment_with_no_args
    assert_equal 0, _at_c.value _at_c.increment
    assert_equal 1, _at_c.value _at_c.increment
    assert_equal 2, _at_c.value end
  • def test_increment_with_arg assert_equal 0,
    _at_c.value _at_c.increment 3 assert_equal 3,
    _at_c.value _at_c.increment 5 assert_equal 8,
    _at_c.value end
  • def test_reset _at_c.increment
    _at_c.increment 10 assert _at_c.value gt 0
    _at_c.reset assert _at_c.value.zero? end

16
The test class, part 2
  • def test_exceptions begin
    _at_c.increment 'four' return rescue
    Exception end flunk endend of the
    test class

17
Test suites
  • A test suite is a collection of unit tests
  • In Ruby, all you have to do is require each test
    file
  • Example suite (containing just the one unit test
  • require 'ruby_tests
  • Note In RadRails, running a test suite produces
    only text output

18
Test-Driven Development (TDD)
  • It is difficult to add unit tests to an existing
    program
  • The program probably wasnt written with testing
    in mind
  • Its actually better to write the tests before
    writing the code you want to test
  • This seems backward, but it really does work
    better
  • When tests are written first, you have a clearer
    idea what to do when you write the methods
  • Because the tests are written first, the methods
    are necessarily written to be testable
  • Writing tests first encourages you to write
    simpler, single-purpose methods
  • Because the methods will be called from more than
    one environment (the real one, plus your test
    class), they tend to be more independent of the
    environment

19
Recommended approach
  • Write a test for some method you intend to write
  • If the method is fairly complex, test only the
    simplest case
  • Write a stub for the method
  • Run the test and make sure it fails
  • Replace the stub with code
  • Write just enough code to pass the tests
  • Run the test
  • If it fails, debug the method (or maybe debug the
    test) repeat until the test passes
  • If the method needs to do more, or handle more
    complex situations, add the tests for these
    first, and go back to step 3

20
The End
If you don't unit test then you aren't a software
engineer, you are a typist who understands a
programming language.
--Moses
Jones
1. Never underestimate the power of one
little test. 2. There is no such thing as a
dumb test. 3. Your tests can often find
problems where you're not expecting them. 4.
Test that everything you say happens actually
does happen. 5. If it's worth documenting,
it's worth testing.

--Andy Lester
Write a Comment
User Comments (0)
About PowerShow.com