At the last Duluth .Net User Group meeting we had a group discussion around the topic of testing. As an extension of that meeting I want to present a collection of information for folks who are just getting familiar with software testing. The following is an outline of our discussion including links to more in depth articles.
Common Types of Software Testing:
- Unit Testing
- Integration Testing
- End To End Testing
- Smoke Tests
After briefly discussing the types of test we focused in on Unit Testing.
We loosely defined unit testing as “tests that can run on a small piece of the code base, isolated from external dependencies”. Every software decision has a trade-off so we tried to list out the benefits of unit testing weighed against its cost.
- Regression safety, provides a level of confidence in the code
- Having tests gives you a tool to put more tests in place when you find bugs
- Gives other developers a starting place to understand the code
- Can be used as a part of the continuous delivery feedback loop to know if code is stable
- Can save time debugging the code
- Adds overhead to changing code
- At least doubles the code base
- Have to maintain test setup code and fake data
- Adds upfront development time
Unit testing styles can be broken into a few categories as well, defined by looking at how a programmer approaches testing and what tools they use.
Styles of Testing
- Make no distinction between mocks and stubs, and use a mocking framework for everything
- Use stubs when necessary mostly avoiding mocks
- TDD (Test Driven Development)
- Follow the guiding principle of writing tests first before any code is written
- BDD (Behavior Driven Development)
- Believe that code should be tested focusing on the codes domain language and user requirements
- Code First - Test Last Developers
- These developers realize the importance of tests but shun the dogma of TDD & BDD, writing the tests after they solve the problem at hand.
The discussion turned to looking at how architecture of code affects testing. We found that many of us had worked with code bases where testing was impossible without some level of refactoring. The conclusion was that code must be designed to be tested.
Frameworks or Patterns that Make Testing Easier
- MVC - Model View Controller
- MVVM - Model View View Model
- MVP - Model View Presenter
- All of these patterns separate out the view making testing simpler
- IOC - Inversion of Control
- A pattern that allows for easy substitution of code dependencies
The group consensus was that while testing can be tedious and add overhead, it provides a margin of confidence for development that cannot be ignored nor denied.