1 / 16

Test-Driven Development and Refactoring

Test-Driven Development and Refactoring. CPSC 315 – Programming Studio. Testing. Discussed before, general ideas all still hold Test-Driven Development Generally falls under Agile heading A style of software development, not just a matter of testing your code

dylanm
Download Presentation

Test-Driven Development and Refactoring

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Test-Driven Development andRefactoring CPSC 315 – Programming Studio

  2. Testing • Discussed before, general ideas all still hold • Test-Driven Development • Generally falls under Agile heading • A style of software development, not just a matter of testing your code • Enforces testing as part of the development process

  3. Test Driven Development Overview • Repeat this process: • 1. Write a new test • 2. Run existing code against all tests; it should generally fail on the new test • 3. Change code as needed • 4. Run new code against tests; it should pass all tests • 5. Refactor the code

  4. Test Writing First • Idea is to write tests, where each test adds some degree of functionality • Passing the tests should indicate working code (to a point) • The tests will ensure that future changes don’t cause problems

  5. Running Tests • Use a test harness/testing framework of some sort to run the tests • A variety of ways to do this, including many existing frameworks that support unit tests • JUnit is the most well-known, but there is similar functionality across a wide range of languages

  6. Test framework • Specify a test fixture • Basically builds a state that can be tested • Set up before tests, removed afterward • Test suite run against each fixture • Set of tests (order should not matter) to verify various aspects of functionality • Described as series of assertions • Runs all tests automatically • Either passes all, or reports failures • Better frameworks give values that caused failure

  7. Mock Objects • To handle complex external queries (e.g. web services), random data, etc. in testing • Implements an interface that provides some functionality • Can be complex on their own – e.g. checking order of calls to some object, etc. • Can control the effect of the interface

  8. Example Mock Object • Remote service • Interface to authenticate, put, get • Put and Get implementations check that authentication was called • Get verifies that only things that were “put” can be gotten. • As opposed to an interface that just returned valid for authenticate/put, and returned fixed value for get.

  9. Successful Tests • Tests should eventually pass • You need to check that all tests for that unit have passed, not just the most recent.

  10. Checklist: Test Cases • Does each requirement that applies to the class or routine have its own test case? • Does each element from the design that applies to the class or routine have its own test case? • Has each line of code been tested with at least one test case? • Has this been verified by computing the minimum number of tests necessary to exercise each line of code? • Have all defined-used data-flow paths been tested with at least one test case? • Has the code been checked for data-flow patterns that are unlikely to be correct? • Defined-defined, defined-exited, defined-killed, etc. • Has a list of common errors been used to write test cases to detect errors that have occurred frequently in the past? • Have all simple boundaries been tested: maximum, minimum, off-by-one? • Have compound boundaries been tested: combinations of input data that might result in a computed variable that is too small or too large? • Do test cases check for the wrong kind of data? • Are representative, middle of the road values tested? • Are the minimum and maximum normal configurations tested? • Is compatibility with old data tested? • Do test cases make hand-checks easy?

  11. Refactoring • As code is built, added on to, it becomes messier • Need to go back and rewrite/reorganize sections of the code to make it cleaner • Do this on a regular basis, or when things seem like they could use it • Only refactor after all tests are passing • Test suite guarantees refactoring doesn’t hurt.

  12. Reasons to Refactor • Code is duplicated • A routine is too long • A loop is too long, or too deeply nested • A class has poor cohesion • A class interface does not provide a consistent level of abstraction • A parameter list has too many parameters • Changes within a class tend to be compartmentalized • Changes require parallel modifications to multiple classes • Inheritance hierarchies have to be modified in parallel • Case statements have to be modified in parallel • OMG this list is long!!! (see page 565 – 570 in Code Complete)

  13. Reasons Not to Refactor • None? • Don’t use refactoring as a cover for code and fix. • Refactoring is changes in working code that do not affect behavior. • Avoid refactoring instead of rewriting. • Sometimes code just needs to be redesigned and reimplemented.

  14. RefactoringCommon Operations • Extract Class • Extract Interface • Extract Method • Replace types with subclasses • Replace conditional with polymorphic objects • Form template • Introduce “explaining” variable • Replace constructor with “factory” method • Replace inheritance with delegation • Replace magic number with symbolic constant • Replace nested conditional with guard clause

  15. When to Refactor • Consider refactoring after you • Add a routine • Add a class • Fix a defect • Touch anything in the code • Target error-prone and high complexity modules.

  16. Resources • Test-Driven Development By Example • Kent Beck; Addison Wesley, 2003 • Test-Driven Development A Practical Guide • David Astels; Prentice Hall, 2003 • Software Testing A Craftsman’s Approach (3rd edition) • Paul Jorgensen; Auerback, 2008 • Many other books on testing, TDD, also

More Related