Unit Testing in RubyProgramming methodologiesSome ideas from agile programmingTest suitesXP approach to testingTerminologyOnce more, in picturesThe test runnerHow not to write a unit testHow to write a unit test classAvailable assertion methodsStructure of a unit testTesting for exceptionsA complete exampleThe test class, part 1The test class, part 2Slide 17Test-Driven Development (TDD)Recommended approachThe EndJan 15, 2019Unit Testing in RubyProgramming methodologiesThe grim facts:The majority of large programming projects failProjects that succeed are usually full of bugsModifying and debugging programs usually introduces yet more bugsHence, it is hazardous to modify a “working” programThe time spent maintaining a program far exceeds (10x?) the amount of time it took to write the programProgramming methodologies are attempts to solve these problems by properly organizing programs and/or programmersThe current (and best) methodologies are the “agile” methodologies“Agile” means writing software that is easily changedXP (Exteme Programming) is the best known agile methodologyXP tends to work best for small groups of programmersSome ideas from agile programmingThere is no “silver bullet,” but agile methodologies are the best we have at presentMost large programming projects fail, so...“Write the simplest thing that can possibly work.”Always have a working version, no matter how little it doesNever add a feature until all known bugs have been fixedAny code that hasn’t been tested is assumed to be wrongHave tests for all code, and keep it up to dateRun tests frequently—very frequentlyTests must be trivially easy to run, or you won’t bother running themTest suitesObviously you have to test your code to get it working in the first placeYou can do ad hoc testing (running whatever tests occur to you at the moment), orYou can build a test suite (a thorough set of tests that can be run at any time)Disadvantages of a test suiteIt’s a lot of extra programmingThis is true, but use of a good test framework can help quite a bitYou don’t have time to do all that extra workFalse—Experiments repeatedly show that test suites reduce debugging time more than the amount spent building the test suiteAdvantages of a test suiteReduces total number of bugs in delivered codeMakes code much more maintainable and refactorableThis is a huge win for programs that get actual use!XP approach to testingIn the Extreme Programming approach,Tests are written before the code itselfIf code has no automated test case, it is assumed not to workA test framework is used so that automated testing can be done after every small change to the codeThis may be as often as every 5 or 10 minutesIf a bug is found after development, a test is created to keep the bug from coming backConsequencesFewer bugsMore maintainable codeContinuous integration—During development, the program always works—it may not do everything required, but what it does, it does rightTerminologyA test fixture sets up the data (both objects and primitives) that are needed to run testsExample: If you are testing code that updates an employee record, you need an employee record to test it onA unit test is a test of a single classA test case tests the response of a single method to a particular set of inputsA test suite is a collection of test casesA test runner is software that runs tests and reports resultsAn integration test is a test of how well classes work togetherJUnit provides some limited support for integration teststest suiteOnce more, in picturesA unit test tests the methods in a single classA test case tests (insofar as possible) a single methodYou can have multiple test cases for a single methodA test suite combines unit testsThe test fixture provides software support for all thisThe test runner runs unit tests or an entire test suiteIntegration testing (testing that it all works together) is not well supported by JUnitunit test (for one class)another unit testtest case (for one method)another test casetest case (for one method)another unit testanother test caseanother test caseanother test casetest fixturetest runneranother test caseThe test runnerThe test runner runs all your testsIf they all succeed, you get a green barIf any fail, you get a red barand links to the tests that failedHow not to write a unit testUnit tests must be fast and easy to run—or you won’t run themThe only output you should need to look at, in order to see that all tests passed, at is the green barOf course, if you get a red bar, you need to explore furtherDon’t do any output from your unit tests!Ideally, the methods you are testing should not do any outputIn most well-written programs, there is a separation of concerns—methods either compute or do output, but not bothIt is possible to write unit tests for methods that do output, but that is a slightly advanced topic I won’t cover hereHow to write a unit test classA unit test class is a class you write that extends Test::Unit::TestCaseYou will need the line require 'test/unit'Your test class will inherit the following methods:def setupThis a method that will be called before each of your test methodsTypically, you will override this method and use it to assign values to some instance variables you need in testingdef teardown()This a method that will be called after each of your test methodsTypically you will just ignore this method, unless you need to close filesYou will also write any number of test methods, all of which have the form def test_SomethingSomething is usually, but not necessarily, the name of the method you want to testInside each test method, you will do some computations and call one or more assert methods to test the resultsAvailable assertion methodsassert booleanassert_equal expected, actualUses ==assert_same expected, actualUses equal?assert_not_equal expected, actualassert_not_same expected, actualassert nil objectassert not_nil objectassert_block blockAll these methods can take an additional message argumentThis is not a complete listing of the assert methodsThe first two methods are by far the most commonly usedStructure of a unit testrequire "test/unit"require
View Full Document