Growing Object-Oriented Software, Guided by Tests

Author: Steve Freeman, Nat Pryce
All Stack Overflow 38
This Year Stack Overflow 3
This Month Stack Overflow 1


by anonymous   2017-08-20

In addition to what Paul T Davies and Magnus Backeus have said. I think that at the end of the day it would be a people and cultural issue. If people are open minded and willing to learn it will be relatively easy to convince them. If they consider you a 'junior' (which is a bad sign because the only thing that matters is what you say not how old/experienced you are) you can appeal to a 'higher authority':

Stored procedures are dead and you are not the only one who thinks so:

It is startling to us that we continue to find new systems in 2011 that implement significant business logic in stored procedures. Programming languages commonly used to implement stored procedures lack expressiveness, are difficult to test, and discourage clean modular design. You should only consider stored procedures executing within the database engine in exceptional circumstances, where there is a proven performance issue.

There is no point in convincing people that are not willing to improve and learn. Even if you manage to win one argument and squeeze in NHibernate, for example, they may end up writing the same tightly coupled, untestable, data-or-linq-oriented code as they did before. DDD is hard and it will require changing a lot of assumptions, hurt egos etc. Depending on the size of the company it may be a constant battle that is not worth starting.

Driving Technical Change is the book that might help you to deal with these issues. It includes several behavior stereotypes that you may encounter:

  • The Uninformed
  • The Herd
  • The Cynic
  • The Burned
  • The Time Crunched
  • The Boss
  • The Irrational

Good luck!

by Ruben Bartelink   2017-08-20

Other hanselminutes episodes on testing:

Other podcasts:

Other questions like this:

Blog posts:

I know you didn't ask for books but... Can I also mention that Beck's TDD book is a must read, even though it may seem like a dated beginner book on first flick through (and Working Effectively with Legacy Code by Michael C. Feathers of course is the bible). Also, I'd append Martin(& Martin)'s Agile Principles, Patterns & Techniques as really helping in this regard. In this space (concise/distilled info on testing) also is the excellent Foundations of programming ebook. Goob books on testing I've read are The Art of Unit Testing and xUnit Test Patterns. The latter is an important antidote to the first as it is much more measured than Roy's book is very opinionated and offers a lot of unqualified 'facts' without properly going through the various options. Definitely recommend reading both books though. AOUT is very readable and gets you thinking, though it chooses specific [debatable] technologies; xUTP is in depth and neutral and really helps solidify your understanding. I read Pragmatic Unit Testing in C# with NUnit afterwards. It's good and balanced though slightly dated (it mentions RhinoMocks as a sidebar and doesnt mention Moq) - even if nothing is actually incorrect. An updated version of it would be a hands-down recommendation.

More recently I've re-read the Feathers book, which is timeless to a degree and covers important ground. However it's a more 'how, for 50 different wheres' in nature. It's definitely a must read though.

Most recently, I'm reading the excellent Growing Object-Oriented Software, Guided by Tests by Steve Freeman and Nat Pryce. I can't recommend it highly enough - it really ties everything together from big to small in terms of where TDD fits, and various levels of testing within a software architecture. While I'm throwing the kitchen sink in, Evans's DDD book is important too in terms of seeing the value of building things incrementally with maniacal refactoring in order to end up in a better place.

by anonymous   2017-08-20

Abstract class may be the trick, but as the Growing Object-Oriented Software, Guided by Tests book advises, it would impact the unit testing level:

Do not Mock Concrete class

Usage of Abstract class might not show very explicitly the various potential relationships with its collaborators.

Here's a question about this subject that I ask few times ago, to know further about that.

You would tell me: "But an abstract class is not a concrete class!"
I would call a concrete class, every class that gathers some behaviors in order to emerge an entity.
Abstract class may often implement several methods belonging to various responsibilities, and therefore reduce the explicitness of object's collaborators.

Thus, I would rephrase the "Programming to an interface" by "Programming by roles".

by anonymous   2017-08-20

It is always tricky to get a project off the ground using TDD if you have never done it before, and it is too big a topic to discuss in a Stack Overflow answer.

The best I can recommend is to read Growing Object Oriented Software Guided by Tests - in this book you are taken step by step through getting an application off the ground using TDD, and examples of how you would solve different problems using TDD as the application grows. The application they use as an example in the book is realistic and should help you learn the skills required to get yourself off the ground.

by anonymous   2017-08-20

There are no strict rules in this area, only guidelines. You usually have one test case per class, but there are different strategies:

For example you can use 'Per Class' approach for classes that are relatively small and follow SRP. But if you have legacy code with a giant *Manager class it is fine to use 'Per Method' and have dedicated test case for only one of its methods. I think that choosing naming strategy for tests is at least as important as test code organization.

Using code coverage tool can help you find spots of untested code. It is less useful as metric. Having high code coverage does not necessarily mean that you have good tests. At the end of the day what matters is that you have meaningful and readable tests.

by anonymous   2017-08-20

AF will do the right thing (User.Create() with an anonymous name arg) with no customizations whatsoever.

The only missing bit is setting the Id. Which is a question you'll have to answer for yourself -- how should your consuming code do this in the first place ? When you've decided, you could do fixture.Customize<User>( c => c.FromFactory( User.Create).Do( x => ???)

Perhaps you could consider exposing a ctor that takes an id too. Then you can do a Customize<User> ... GreedyConstructorQuery.

If your ORM is doing some wacky reflection and you like that and/or can't route around it you get to choose whether for your tests you should:

a) do that too - if that's relevant to a given test or set of tests

b) consider that to be something that just works

Regarding mixing mocking and feeding in of values to an Entity or Value object - Don't do that (Mark Seemann's Commands vs Queries article might help you here). The fact that you seem to be needing/wanting to do so makes it seems you're trying to be too ambitions in individual tests - are you finding the simplest thing to test and trying to have a single Assert testing one thing with minimal setup.

Go buy the GOOS book - it'll help you figure out ways of balancing these kinds of trade-offs.

by myoffe   2017-08-19
Nope, there's no way around it. Tests are not easy. But! Writing tests, learning from that, then improving your tests, which in turn help you design better software will make writing tests easier. And will help you write better code, in general.

Also, 99% of the time, the first test you are going to write in a job is for an existing piece of software. So it will definitely not be easy. But you will learn so much more about the software you are writing the test against rather than writing code in the edit-and-pray methodology.

I highly recommend reading

by antrix   2017-08-19
As a start, I recommend reading "Growing Object-Oriented Software, Guided by Tests". I am still not a 100% convert but I did get many of the same questions answered.

by jskulski   2017-08-19
I try to setup a feedback loop as soon as possible. I spend time setting up so i can do some simple action (hit a button, run a command, or automatically watch some files) to see if I'm on target it.

I found this saves immense time and keeps me on task pretty well.

This is from: - GOOS book -