Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Steps to take to slowly integrate unit-testing into a project

I'm currently on a co-op term working on a project nearing completion with one other co-op student. Since this project has been passed down from co-op to co-op, poor practices have been taken along the way and testing has been left until the end. I've decided I'd like to write unit-tests to learn something new while testing.

However, I'm working on a 3-tier, tightly coupled app that seems impossible to unit test in its current form. I don't want to throw off the other co-op student with no knowledge of any of these concepts by refactoring the code beyond recognition overnight. So what steps should I take to slowly pull the code towards unit-testability? Should I first implement a factory pattern and let the other student familiarize themselves with that before moving forward?

My apologies if my knowledge is flawed and there should be no issue whatsoever. I'm new to this :)

like image 998
Chris Avatar asked Jun 19 '09 13:06

Chris


People also ask

What are the steps required to perform unit testing?

A unit test typically comprises of three stages: plan, cases and scripting and the unit test itself. In the first step, the unit test is prepared and reviewed. The next step is for the test cases and scripts to be made, then the code is tested.

How do you speed up integration testing?

Introduction. In-memory databases such as H2, HSQLDB, and Derby are great to speed up integration tests. Although most database queries can be run against these in-memory databases, many enterprise systems make use of complex native queries which can only be tested against an actual production-like relational database.


2 Answers

Working Effectively with Legacy Code by Michael Feathers

Hard to know if implementing a factory pattern will do any good, depends on what the code is doing :)

like image 95
Loofer Avatar answered Oct 19 '22 09:10

Loofer


Working Effectively with Legacy Code by Michael Feathers (also available in Safari if you have a subscription) is an excellent resource for your task. The author defines legacy code as code without unit tests, and he gives practical walkthroughs of lots of conservative techniques—necessary because you're working without a safety net—for bringing code under test. Table of contents:

  • Part: I The Mechanics of Change
    • Chapter 1. Changing Software
      • Four Reasons to Change Software
      • Risky Change
    • Chapter 2. Working with Feedback
      • What Is Unit Testing?
      • Higher-Level Testing
      • Test Coverings
      • The Legacy Code Change Algorithm
    • Chapter 3. Sensing and Separation
      • Faking Collaborators
    • Chapter 4. The Seam Model
      • A Huge Sheet of Text
      • Seams
      • Seam Types
    • Chapter 5. Tools
      • Automated Refactoring Tools
      • Mock Objects
      • Unit-Testing Harnesses
      • General Test Harnesses
  • Part: II Changing Software
    • Chapter 6. I Don't Have Much Time and I Have to Change It
      • Sprout Method
      • Sprout Class
      • Wrap Method
      • Wrap Class
      • Summary
    • Chapter 7. It Takes Forever to Make a Change
      • Understanding
      • Lag Time
      • Breaking Dependencies
      • Summary
    • Chapter 8. How Do I Add a Feature?
      • Test-Driven Development (TDD)
      • Programming by Difference
      • Summary
    • Chapter 9. I Can't Get This Class into a Test Harness
      • The Case of the Irritating Parameter
      • The Case of the Hidden Dependency
      • The Case of the Construction Blob
      • The Case of the Irritating Global Dependency
      • The Case of the Horrible Include Dependencies
      • The Case of the Onion Parameter
      • The Case of the Aliased Parameter
    • Chapter 10. I Can't Run This Method in a Test Harness
      • The Case of the Hidden Method
      • The Case of the "Helpful" Language Feature
      • The Case of the Undetectable Side Effect
    • Chapter 11. I Need to Make a Change. What Methods Should I Test?
      • Reasoning About Effects
      • Reasoning Forward
      • Effect Propagation
      • Tools for Effect Reasoning
      • Learning from Effect Analysis
      • Simplifying Effect Sketches
    • Chapter 12. I Need to Make Many Changes in One Area. Do I Have to Break Dependencies for All the Classes Involved?
      • Interception Points
      • Judging Design with Pinch Points
      • Pinch Point Traps
    • Chapter 13. I Need to Make a Change, but I Don't Know What Tests to Write Characterization Tests
      • Characterizing Classes
      • Targeted Testing
      • A Heuristic for Writing Characterization Tests
    • Chapter 14. Dependencies on Libraries Are Killing Me
    • Chapter 15. My Application Is All API Calls
    • Chapter 16. I Don't Understand the Code Well Enough to Change It
      • Notes/Sketching
      • Listing Markup
      • Scratch Refactoring
      • Delete Unused Code
    • Chapter 17. My Application Has No Structure
      • Telling the Story of the System
      • Naked CRC
      • Conversation Scrutiny
    • Chapter 18. My Test Code Is in the Way
      • Class Naming Conventions
      • Test Location
    • Chapter 19. My Project Is Not Object Oriented. How Do I Make Safe Changes?
      • An Easy Case
      • A Hard Case
      • Adding New Behavior
      • Taking Advantage of Object Orientation
      • It's All Object Oriented
    • Chapter 20. This Class Is Too Big and I Don't Want It to Get Any Bigger
      • Seeing Responsibilities
      • Other Techniques
      • Moving Forward
      • After Extract Class
    • Chapter 21. I'm Changing the Same Code All Over the Place
      • First Steps
    • Chapter 22. I Need to Change a Monster Method and I Can't Write Tests for It
      • Varieties of Monsters
      • Tackling Monsters with Automated Refactoring Support
      • The Manual Refactoring Challenge
      • Strategy
    • Chapter 23. How Do I Know That I'm Not Breaking Anything?
      • Hyperaware Editing
      • Single-Goal Editing
      • Preserve Signatures
      • Lean on the Compiler
    • Chapter 24. We Feel Overwhelmed. It Isn't Going to Get Any Better
  • Part: III Dependency-Breaking Techniques
    • Chapter 25. Dependency-Breaking Techniques
      • Adapt Parameter
      • Break Out Method Object
      • Definition Completion
      • Encapsulate Global References
      • Expose Static Method
      • Extract and Override Call
      • Extract and Override Factory Method
      • Extract and Override Getter
      • Extract Implementer
      • Extract Interface
      • Introduce Instance Delegator
      • Introduce Static Setter
      • Link Substitution
      • Parameterize Constructor
      • Parameterize Method
      • Primitivize Parameter
      • Pull Up Feature
      • Push Down Dependency
      • Replace Function with Function Pointer
      • Replace Global Reference with Getter
      • Subclass and Override Method
      • Supersede Instance Variable
      • Template Redefinition
      • Text Redefinition
  • Appendix: Refactoring
    • Extract Method
like image 21
Greg Bacon Avatar answered Oct 19 '22 08:10

Greg Bacon