Alias: InMemoryImpostor, LoopBack
One of: TestingPatterns
(I just heard this called LoopBack
, and realized I have possibly been saying "shunt" for years in error -- AlistairCockburn
See also: MockStubShunt
Looking for new names, help appreciated.
Please comment or vote on the following, or add...
- LoopBack *
- MockObject *
- Stubs: StubFunction? / StubMethod? / StubRoutine??
- The TestingFramework that calls your code would be a "TestHarness?".
- In Memory Impostor
- Short Circuit
- Refracted Interface
- External Interface Refracted
- External System Parody
- Hermaphroditism (see note from other discipline, below)
See also: LawOfStubs
, and others
Loopback is the term I have always used to describe the "test connector" you describe as a shunt below. But to me, that implies a stronger "eating your own output" mode (e.g., showing on a screen, as if received, what is being sent from the keyboard). (I have recently also heard the term "frog the circuit" to mean the same thing.) Perhaps "testing surrogate" would better describe a shortcut emulation of some external system?
I like "surrogate". I'll try that for a while. -- Alistair (7/00)
A Shunt is basically a wire that goes out the back of one jack, and into an input, so the machine is connected to itself. When you run the machine, it thinks it is connected to the world, but it is only talking to itself. In software, the trick is to fake communication against the outside world, then run the tests locally. Then your testing is partitioned.
Some tests make sure that the lowest layer of database access works as planned. Then I write a suite based on the assumptions demonstrated by the first suite. It assumes that I can get things into and out of the real database, so I don't have to have the real database there. That way I can create an in-memory impostor for the database and exercise the higher level objects.
: you really don't want your UT to depend on a live DB somewhere with an exact set of test data in it
Why don't I? -- KeithBraithwaite
I only have a little experience with this, but I found two problems. When the database goes down at 23:00, you can't run your tests anymore. Probably serves me right for working so late. A bigger problem is that the tests are dead slow. Setting up a database connection, wiping clean the schema and recreating it from scratch takes a lot of time. Now we only set up the connection once instead of for every single test. We also just remove the records from all tables instead of deleting the tables themselves. This way the tests are faster, but still pretty slow.
Is there a reason why you are doing all that maintenance? Our test DB (or, our test suite) wasn't nearly volatile enough to justify that. We had one connection per test suite, (so the first test case could take a long time) had separate scripts to massage the data as required and tore down the tables themselves very infrequently (usually after some mortal screw-up). -- KeithBraithwaite
Can't we just Shunt to a UnitTest
DB server or database running the same DB as the Development DB server? The former could have a script added that restores an exact test image of a database after every test.
This is what I'm doing. I am new to database apps, so I would really like to hear anyone's suggestions on testing. Could someone please explain why relying on having a DB there is a bad thing? -- KayJohansen
test DB and live DB
Live DB is Test DB
- mainly useful in development
- Clone the (bits of) the production DB (that you need), have the test cases demand that the biz layer to be tested is hooked up to the development DB, which is populated with appropriate data.
- Resulting Context
- you have to build, populate the development DB
- new tests and changes to existing tests require may require DB modifications
- you can put whatever you need in the DB (most DBA's will be reluctant to put UnitTest data into a production DB)
- Could potentially be used any time.
- Write the tests against the data in the production DB.
- resulting context:
- Your tests are more "realistic" in some sense
- You may not be able to test some change in the business layer until some hoops have been jumped through to change the production DB, leading to slower refactoring etc.
Generate fake data
- Performance hits against live DB while real users are using it -- I've knocked our production DB out (Oracle 8i) with a logic error in a query that returned several million rows using several joins. Lots of complaints. ;)
This might be your only option, as both of the above schemes may be illegal under EuropeanDataProtectionLegislation
: programmers have no right to see customers' personal data.
Teams that I have worked on have had great success using test DB and live DB
There was one guy who joined the team (which I had the privilege to lead) who had read up on XP and had been using JavaUnit
elsewhere. However: he at first had lot of difficulty with the idea that the test
was the definitive document, and that if we needed to change the DB, then we'd just do that.
"if you changed the test, you'd have to change the data"
"but you'd have to change the data"
"ok, then we'd do that"
When he finally got it, the SuperCranialLightBulb?
burned very brightly indeed. I think that the single most satisfying moment for me on that project was seeing the mists of confusion clear for him.
Did anyone ever tell you not to put any SQL statements at all above the Biz Objects layer? but to only use a lite or full InterpreterDesignPattern?
? This is why. -- PhlIp
Where are you seeing any indication that SQL statements are being placed above the business objects?
Some people do put SQL statements way up high in the stack. The ShuntPattern
doesn't say anything about SQL, but I think PhlIp
is saying, don't put SQL up there, and the reason has to do with creating the shunt for the persistence layer (which the SQL code would wreck).
I'm saying it because I often see raw SQL statements up in the UI and Biz Rules layers. (Not that I ever wrote them there ;-) But they constrain you to A> Not Test, B> Not Shunt, or C> Shunt to the exact same dialect of SQL as the main DB.
Is this the same idea as FakeTheSideEffects
I get the terms "stubs" and "TestingHarness?
" from traditional testing texts. -- JeffGrigg
From the "Glossary of Terms Used In Software Testing":
- refactored because original document moved. Best match found: http://www.testingstandards.co.uk/living_glossary.htm
- Test Harness: "A testing tool that comprises a test driver and a test comparator." (UnitTests, by XP definition.)
- Stub: "A skeletal or special-purpose implementation of a software module, used to develop or test a component that calls or is otherwise dependent on it. After [IEEE]."
The book "Testing Object-Oriented Systems: Models, Patterns, and Tools" ISBN 0-201-80938-9
also uses the terms stub, test harness, test framework, and test harness framework. ;-> See http://www.awl.com/product/0,2627,0201809389,00.html
I believe Stub is not the same as Shunt or InMemoryImpostor
. Those latter two provide a way for the system to talk to itself properly when disconnected, the stub provides a crippled way for the system to not abend when disconnected, quite a difference. With a Shunt / Surrogate / Short Circuit / InMemoryImpostor
, you can really run the tests, but using hand crafted responses stored in local memory.... it presupposes there is some quite easy way to indicate "Now we're connected / now we're disconnected." -- Alistair
I saw this posting on Egroups for XP, hope it helps:
A>We have a similar situation. Our solution is to develop in a local mode, here everything (client, server, whatever) is run in the same JVM. Passing these local tests is all that's necessary for commit. A subset of the tests (those that can be run on a proper client) has been earmarked and we regularly run these in a more realistic setting (over a network, using Jini lookups to find out what's where, and stuff). Usually all that comes out from that are one or two "forbidden casts" (casting from an interface to the implementation to do special stuff - somehow we keep doing this in the wrong places ;-)), easily fixed.
A>As a side effect, the scaffolding required to make everything run in a single JVM, bypassing Jini etcetera, for development purposes also make it easy to pack everything onto a laptop for demonstration purposes.
B>I like it. I wish I had thought of that at the start of my current project. It would have eliminated a lot of headaches.
From www.dictionary.com "An anomalous condition in humans and animals in which both male and female reproductive organs and secondary sexual characteristics are present in the same individual." (Just in case anyone didn't know...) (Now deprecated amongst those most affected. They prefer the term inter-sexed (just in case anyone didn't know))
In the field of electronics, a "hermaphroditic connector" is one which acts both as the plug and the socket. That is, it can plug into itself, so you don't need two different parts.
I've written test code wherein the module under test (MUT) would in essence call a simulation of its external partner and provide it with the not only the usual output data, but its own response back to the MUT. The same code was supplying its usual output and accepting back a faked response as its own input, which sounds pretty hermaphroditic to me... -- PeterHansen
(By the way, definitely don't stick with "shunt". Again from electronics, but really just from English, a "shunt" does not necessarily feed something back into itself. A synonym is really "bypass". Shunting a railway car means to move it from one track to another, not to turn it around and send it back whence it came. "Loopback" is a big win over "shunt" any day.)
''(I'm now using the word LoopBack
in all my conversations on the subject... it works much better -- AlistairCockburn
Agreed, A ShuntPattern
should be called a LoopBack
. Similar to, but not the same as a MockObject
. -- BenAveling
A stub is usually something which implements an interface, and does the most trivial thing possible. Especially useful in languages like C/C++, where symbols must be resolved at compile/link/load time or your program won't run--stub functions are written to get the bloody thing to link.
I suggest that LoopBack
is a poor name as well. A shunt
object is more like a fake
object or a test
object ... a Fake Database
, which I might create in a test for instance, might receive a "query" message and reply with one "row" every time, regardless of the content of the query message. But, for me, LoopBack
strongly evokes the image of returning exactly what it was sent. So, I might expect that a LoopBack
object would receive a "query" message and reply with ... what? the content of the message? -- EricHerman
A lot of these synonyms have very different meaning for me, and while most reflect some aspect of the solution space, there seem to be several related and interdependent pattern here.
Therefore I've tried to draw on the wider semantics of the words.
In electronics/electrical engineering, a shunt is a parallel low-resistance circuit used to shift a load from one circuit to another.
On a railway, a shunt refers to the engine and the process of shifting a carriage from one train or line to another.
A quick google also shows that in medicine a shunt is a type of by-pass to control the pressure in a blood vessel.
a shunt is about easing a load by using a parallel or alternate low-resistance path perhaps controlled by something external.
In electronics/electrical engineering, a loopback is a return path for output to be used as input to allow the circuit to regulate itself.
In Crypto, a LoopBack
is a synonym for a feedBack, where the output is used to modify an input value.
Therefore a loopback is about feeding the output of a system into the input, so that it can self-regulate.
These all imply some form of false or temporary situation that is not part of the ongoing system.