The Artima Developer Community
Sponsored Link

Weblogs Forum
A Set of Unit Testing Rules

50 replies on 51 pages. Most recent reply: Jan 21, 2011 2:19 AM by Steve Merrick

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 50 replies on 51 pages [ « | 1 ... 26 27 28 29 30 31 32 33 34 ... 51  | » ]
James Sadler

Posts: 1
Nickname: jsadler
Registered: Sep, 2005

Re: A Set of Unit Testing Rules Posted: Sep 14, 2005 12:47 AM
Reply to this message Reply
Advertisement
> > <i><p>A test is not a unit test if:</p>
> > <li>It talks to the database
> > <li>It communicates across the network
> > <li>It touches the file system
> > <li>It can't run at the same time as any of your other
> > unit tests
> > <li>You have to do special things to your environment
> > (such as editing
> > config files) to run it.
>
> Sometimes, your unit test must do some of these things:
> 1. You test a class who's function is to interact with a
> db, write/read a file, or write/read the Windows
> Registry.

You don't need to write a unit test that accesses the database for every piece of code that accessed the database. Here's what you do: encapsulate all access to your database through an implementation of an interface called MyDatabaseService (or whatever). This class itself can either be:

- tested using the unit test tool of your choice
- or simply tested by inspection (it's a really thin layer, and hey, you are pretty sure that Oracle tested their JDBC adapters eh?!)

From then on, all code can be tested against a mock version of the MyDataBaseService. You can us inversion of control at run time (see Spring) to enable this sort of thing easily.

What you should ask yourself is this: what am I testing? Am I testing MY piece of code, or am I testing the database (or some other external dependency)?

Where I work, we use this mocking technique to return fake values etc, and it is very effective. The tests are testing OUR code, and we have 2000 JUnit tests that run in about 35 seconds. Only about 10 tests go out to the network. We have very very very few bugs in our system, so it definitely works.

> 2. You develop a client; to make sure it works, it
> must interact with a server. At my work, for
> example, our client must exchange timestamped, signed, XML
> messages with a server. The test will not be complete
> without server interaction. Actually, you simply
> cannot test this without a server.

Same issues here, any external dependency can be hidden behind an interface that can be mocked out at test time. The mock will have no logic: it will simply return the data required for the code under test to work. At run time , you replace the mock with the real implementation that actually goes to the server.

When mocks are done well, they have zero logic. I cannot stress that enough: usually the body of a method in the mock is empty, or simply returns a default value.

Of course you will still have intergration tests, and they will use the REAL implementations of your 'external system' interfaces. You can use JUnit for these if you like, but strictly speaking, they are not unit tests. Where I work, none of our integration tests have ever failed, not because we are the best developers the world has ever seen, but because the 'external service' implementations are so thin. And I don't want to test that JDBC works, TCP/IP works, Swing works, etc : I want to test my code.

Unit tests should also be self contained, have no static state and should be able to be run one at a time, in any order you please (TestNG relaxes this a bit).

- ) self contained; they are testing my code, and are defined entirely in code. I don't want my tests to fail because someone deleted some records from the database.

- ) no static state; for the guarantee that there are no 'magic' dependencies between tests. Don't want to get into a situation where one test will only run if test X is run first. This means static variables in my code are readonly, and static initializers are avoided if possible.

- ) no external dependencies; if tests fail, it is always because I screwed up the code and for no other reason

>
> You want to say these are not unit tests? I'll argue that
> the tests can't be any simpler.

Hopefully I have illustrated that this is not the case.

James.

Flat View: This topic has 50 replies on 51 pages [ « | 26  27  28  29  30  31  32  33  34 | » ]
Topic: Computer About to Play Jeopardy Previous Topic   Next Topic Topic: The Search for Requirements

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use