Some Definitions – Testing Techniques 9

I think that I’m coming to the end of my series of blogs on testing techniques, and it feels like it’s been along haul. One of the things that has become clearer to me is that approaches to testing are still in their infancy and as such are a definite source of contention or discussion amongst developers – and that’s a good thing.

I suspect that we are at a point in the history of our profession where the discipline of writing tests is only just gaining ground and will one day be common place and taught as part of elementary programming classes (1). Today’s blog provides a summary of the of the terms used in my previous blogs in this series.

Unit Tests
I covered the definition of a unit test in part two of this series of blogs, giving the views of Shane Warden, who in his book The Art of Agile Development states that unit tests should run at a rate of “hundreds per second”; Michael Feathers, who in his book Working Effectively with Legacy Code states that a unit test is not a unit test if:

  1. It talks to a database.
  2. It communicates across a network.
  3. It touches the file system.
  4. You have to do special things to your environment (such as editing configuration files) to run it.

I also quoted Roy Osherove, who in his book The Art Of Unit Testing sums up a good unit test as: “an automated piece of code that invokes the method or class being tested and then checks some assumptions about the logical behaviour of that method or class. A unit test is almost always written using a unit testing framework. It can be written easily and runs quickly. It’s fully automated, trustworthy, readable and maintainable”.

Unit tests can be summed up using the FIRST acronym: Fast, Independent, Repeatable, Self Validating and Timely.

When to Use Unit Tests
Unit tests are the bread and butter of testing. If you employ Test Driven Development, TDD, then you write failing tests before you write your production code. If you don’t use TDD, then at least write your tests at the same time as your production code i.e. write a method and then write its tests. This technique doesn’t involve the paradigm shift that accompanies TDD, but it’s much better than writing tests after you’ve written all the code, which is usually considered tedious by developers. There should be one test for every scenario, which translated into plain English means every path through your code: both sides of every if statement and every case of a switch statement. In short, every project should have hundreds of Unit Tests and you should have the confidence that if you change a part of the code then you won’t break something.

Stubs
Stubs are used to isolate an object under test from the rest of the system. They are objects that are injected into your object to replace real objects in test situations. Martin Fowler defines stubs, in his essay Mocks Aren’t Stubs as:

“Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it ‘sent’, or maybe only how many messages it ‘sent’”

…whilst a similar definition, taken from The Art of Unit Testing is:

“A stub is a controllable replacement for an existing dependency (or collaborator) in the system. By using stub, you can test your code without using the dependency directly.”

Mocks
Mocks are replacement objects used to imitate, or mock, the behaviour or roles of production objects. This really means checking that an object under test calls methods on a mock object as expected with the test failing if it doesn’t; hence, you’re asserting on the correctness of method calls and the execution path through your code, rather than, in the case of a regular unit test, the return value of the method under test.

Integration Tests
Integration tests are the opposite of unit tests. The idea behind integration tests is to prove that your objects collaborate with each other and the system around them. To paraphrase Michael Feathers, integration tests CAN:

  1. talk to a database.
  2. communicate across a network.
  3. touch the file system.
  4. require you to do special things to your environment (such as editing configuration files) to run it.

Roy Osherove in the Art of Unit Testing states that an “integration test means testing two or more or more dependent software modules together as a group”. For me this constrains the definition a little too much after all, in testing objects in a single module you can access a database or file system whilst figuring out if your objects can collaborate.

In projects I’ve previously worked on, there’s usually been a module specifically written to hold integration tests. This is because integration tests are less numerous than unit tests (perhaps at a ratio of 1:10) and, by virtue of the fact that they access their environment, are usually substantially slower and therefore corralling all integration tests into their own Maven module means that they don’t have to run every time you build a module, speeding up build and development time.

End to End Integration Tests
I’ve covered End to End tests in detail in the second blog in this series, so to summarise, they can be defined as a special case of integration tests in that the test commences at, or just behind, a system boundary and executes through all layers of the system. Where the system boundary, or just behind the system boundary is a matter for debate. In terms of a Spring MVC app, there’s no reason why an end to end test shouldn’t start at your controller code ignoring the browser and dispatcher servlet. After all, I suspect that the Guys at Spring have tested their code thoroughly, so why should you waste time testing it? Also, testing what the front end looks like s a whole different kettle of fish.

(1) I often suspect that testing techniques are not actually taught in collages and universities – but I’ve no evidence of this. If there are any academics out there who can tell me that unit testing is taught, encouraged and an integral part of their Computer Science Degree courses then I’d be happy to hear from them.

Reference: Some Definitions – Testing Techniques 9 from our JCG partner  Roger Hughes at the Captain Debug’s Blog.

Related Articles :

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


2 + = eight



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books