New-age Transactional Systems - Not Your Grandpa's OLTP
John Hugg discusses high volume transaction processing applications with high and low frequency profiles, and how VoltDB can be used for that purpose.
The content has been bookmarked!
There was an error bookmarking this content! Please retry.
Posted by Mike Bria on Jan 22, 2009
Hot in the Test-Driven Development Yahoo group this week is a discussion concerning the perceived continuum between the so-called "Classic" and "Mockist" approaches to TDD. Steve Freeman, Nat Pryce, Michael Feathers, Dale Emery, and many more discuss terminology and describe their approaches. The discussion also debates whether there even really exists such a continuum, and if so, what distinguishes the approaches that represent it's extremes?
After stating he "feels inclined to the classic-TDD approach", Olaf Bjarnason started the 70+ entry discussion with this question to the group: "What made you switch [to "mockist"] from classic, if you were there before? How does the new method feel?". Many of the early responses though centered more around a challenge Olaf's thread title, "Classic/Mockist discussion". Is there really a need for such a binary distinction?
Nat Pryce, co-creator of JMock, expresses his feeling:
I think the whole division of TDD practice into "mockist" vs "state based" is pointless, distracting and does a disservice to people trying to learn and use TDD.
Mock objects are just a tool. They are one of many tools that you need to use when doing TDD. Like any tool, they are designed to help solve a set of problems in a specific context. Outside that context they do not help and can be a hindrance.
If this is the case, how then does one know when to apply this "tool"? How does one know to test "state", namely without a mock, versus asserting behavior, namely by using mocks?
Dale Emery chimes in to describe how he typically makes the distinction:
Lots of people use the distinction of "state-based" versus "behavior-based." I use a twist on this. I think "result" versus "protocol". If the essence of the test is whether the UUT produced the correct result, I don't usually need a mock for that. If the essence of the test is whether the UUT properly executed its role in a protocol--i.e. whether it sent the right messages to the right collaborators, given the starting conditions and the stimulus--I use mocks to represent the UUT's direct collaborators.
Lior Friedman asserts that a mock's place is in representing a contract:
For me usage of mocks indicate the existence of a "contract" between the class under test and another class which is used. And the goal of the test is to verify that the contract is fulfilled.
Charlie Poole pitches in with his gauge on when state-based is the way to go:
I'd use state-based testing on an object if I had no other way to observe it's behavior - that is if /all/ the call did was change an observable state of the object. Assuming the object actually did something, I'd want to verify [with a mock] that it did it.
Adam Sroka on when he uses a mock:
For my own part, I *always* mock at system defined boundaries (e.g. filesystem, network, database, etc.) I usually mock when I want to elicit loose coupling between an interface and it's client in a top-down direction. And, I generally don't mock when the object I am interacting with is small and easily faked/stubbed.
As the thread goes on, and as may be highlighted by the above sound-bites from it, there is a recurring observation that while many of these ideas are similarly themed, they don't seem to share a commonly categorizable, named approach beyond "We do it sometimes, but not others". Further, each (with the exception possibly of Sroka's statement about "top-down") tend more to the following: The decision to mock is being driven by the design, as opposed to the converse, where the design is driven by the mocks.
Regarding this idea of using mocks to drive design, Michael Feathers gives an example:
To me, the real meat behind the whole subject is just how far people are willing to push "tell, don't ask." Mocks are a prop for a design approach.
...
Imagine you have some object and you want to get report of its errors:
class Errors {
int errorCount();
Error getError(int index);
}
Errors errors = object.getErrors();
That's an ask. We can do state-based testing of the Errors object in the test.
To make it a tell you'd move to this:
interface ErrorReceiver {
void accept(Error error);
}
ErrorReceiver receiver = ...;
object.reportErrors(receiver);
We can set expectations on a mock receiver and pass it during testing and use a "real" class in production.
Later, largely in response to a post by Steve Freeman (another co-creator of JMock) describing his partner Nat Pryce's categorization of some "mock-worthy peer objects" ("Dependencies","Notifications", and "Policies"), Feathers (and also Colin Jack) assert that the design ideas the duo have been putting forth in fact exist at the core of this "mocks as a tool to drive design" philosophy. Further, more to the point of this thread, that when people talk of a "mockist TDD approach" they are referring in large part to these design ideas, and that the recurring confusion about "Classic vs Mockist TDD" could be reduced if these collection of ideas had a more concrete name.
As Pryce reminds the group, he and Freeman have a book in the works that may just provide some this clarification being requested. He also points the group to a write-up of his on "State vs Interaction Based Testing".
So, keeping it real, this conversation is really not a new one (Google it), but it is it seems a recurring one. Is there a "Classic TDD", and does it mean "Design begets Mocks"? Is it characterized by something else? Is there "Mockist TDD"? Is it characterized by a "Mocks beget Design" philosophy? "Tell, Don't Ask"? Is it something altogether else? Either way, is it really a "this OR that" thing, or more likely "this for these AND that for those"?
Of course, as always, this news is simply a [hopefully objective] highlight of the Yahoo group discussion, and as such only a piece of the puzzle. Read it for yourself, as well as other sources, and tell others here and/or in the discussion what your experience says.
Agility at scale, become as agile as you can be
A practical guide to choosing the right agile tools
A Guide to Branching and Merging Patterns
agility@scale eKit: 10 Principles, Scaling Model, Metrics, Collaboration
In today’s hyper-competitive world, later may be too late to adopt Agile development and this Roadmap for Success will help you get started. Download "Agile Development: A Manager's Roadmap for Success" now!
Could you provide the real link to the discussion group? I don't find some-site.com to be particularly useful.
Perhaps it's more of an argument among those who haven't done TDD for a while. Talking about the distinction and leading people towards state-based testing will keep then from being too extreme and entering an unfortunate place I call "mock hell".
With the knowledge of mocks in hand and the understanding that they are to be used sparingly, new TDDers will find themselves in the balanced place that the gurus on the list (above) are at.
Hm, sorry Clay, not sure what you mean. All seems fine to me?
Cheers
MB
final link in the post "Yahoo group discussion" goes no where:
[quote]
Of course, as always, this news is simply a [hopefully objective] highlight of the Yahoo group discussion, and as such only a piece of the puzzle. Read it for yourself, as well as other sources, and tell others here and/or in the discussion what your experience says.
[/quote]
I personally think its somewhat of an inane argument. If the test is requiring interaction, use a mock. if it requires a change of state use an assert. How this picked up traction.. I really don't know..surely there is some code to written team... get to it!
Got it, thanks!
John Hugg discusses high volume transaction processing applications with high and low frequency profiles, and how VoltDB can be used for that purpose.
Kevlin Henney examines code samples to see what can be learned from them starting from the premise that one won’t write great code unless he knows how to read it.
Jason Ayers share the observations he made watching a team of developers collaborating in real time on the same code base, pushing XP, pair programming and continuous integration to their extremes.
Michael Snoyman presents Yesod, a web framework written in Haskell and containing a web server, templating, ORM, libraries (templating, gravatar, etc.).
Richard Kreuter and Kyle Banker on how to avoid classical RDBMS transactional systems by using compensation mechanisms, transactional messaging or transactional procedures.
Attila Szegedi talks about performance tuning Java and Scala programs at Twitter: how to approach GC problems, the importance of asynchronous I/O, when to use MySQL/Cassandra/Redis, and much more.
One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.
InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.
6 comments
Watch Thread Reply