Why did we succeed?
• We took the project seriously.
• We had an awesome sponsor.
• We stuck to Scrum and continually refined our process
• We used industry-standard techniques to maintain a
high level of build quality
• We bribed Jeff early and often
The Rules for Maintaining Build Quality
• There must be an authoritative copy of the source
code that is accessible by the whole team at any time.
• There must be unit tests covering as much of the code
as possible within the authoritative copy.
• The authoritative copy must compile, build, and
execute all tests without errors for the duration of the
Enforcing the Rules
Centralized Version Control System
Building without errors
Git/Mercurial: Artificial Centralization
(This is what GitHub does)
General Thoughts on VCS’s
• Thanks to GitHub, Mercurial is not as popular as git.
• Subversion is much simpler than git and is very widely used.
• It is not as good at merging as git
• The centralized model can be a bit slow
• It has a very mature and stable GUI for Windows: TortoiseSVN
• Git is the new hotness.
Personal branches are awesome!
It is much more difficult to understand conceptually
So many commands that GUI’s can’t do it justice – use the command line
If you do something wrong, get ready to spend a lot of time on StackOverflow
• If somebody ever says the words “CVS” or “Visual Source Safe”: RUN.
Make sure you check in the right files!
• INCLUDE: all code and tests that you write.
• EXCLUDE: anything that is generated when you compile or build
• EXCLUDE: any third party binaries that are managed by a dependency
tracker (e.g. Maven, NuGet)
• INCLUDE: any third party binaries that are NOT managed by the above
• INCLUDE: Configuration files for servers UNLESS the client specifically
forbids it (e.g. database passwords)
• Google search: “.gitignore c#” or “.gitignore java”
What are Unit Tests?
• Code that tests a component of your system in isolation
• Dependencies on other components are mocked
• Typically written with the help of a Unit Testing Framework
JUnit – Java
NUnit – .NET
RSpec – Ruby
• Tests are run using a Test Runner (usually comes with the Framework)
Why bother? I’ll just run the program and
test it that way!
• This kind of testing (“end-user testing”) is important but insufficient.
• Bigger programs can take a long time to compile, build, execute.
• Setting things up just right for a good test can be difficult using a UI
Okay, fine. I’ll do it when I’m done with
the rest of the project.
• The code you’ve already written may be resistant to automated tests.
• If you wait till the end, there will be no time left.
So when do I write tests?
Write them before
you write your code!
The TDD Method
Pick a single requirement to implement.
Write a test that shows you’ve implemented it.
Add the minimum code so the project compiles.
Verify that the test fails.
Implement the requirement.
Verify that the test passes.
Refactor, ensuring all tests still pass.
Go to step 1.
My new client: FizzBuzz Inc.
“We need a specialized console application that can print the numbers
from 1-100. Every time it prints a number divisible by 3, it should write
the word fizz next to the number. Every time it prints a number
divisible by 5, it should write the word buzz next to the number. Oh,
and if it’s divisible by 15, make sure it prints fizzbuzz. Thanks!
Some Cool Things that Just Happened
• Executed the application only at the very end.
• We ended up with a reusable service module!
• The UI piece became very dumb.
New Requirement (time permitting)
For the number 98, print the text from the latest @roufamatic tweet.
• Create SERVICES that do interesting things
• Give those services an INTERFACE
• Pass that INTERFACE into classes that depend on the service
• Wire up the SERVICE on application startup
• Recommend: an Inversion of Control Container can handle the wiring
• Java: Spring
• .NET: StructureMap, Castle Windsor, Ninject, Unity
TDD – Tips to keep yourself sane
• Testability is more important than 100% test coverage.*
• “Testability correlates with maintainability” (Wiechers, Software Requirements) – it’s
easier to add features to testable code.
• When testable code breaks in the field, it’s easy to debug: just write a test!
• Use TDD to establish your architecture, then use as needed to feel
confident. (i.e. Cover the Scary Bits)
• Beware “Copy Pasta” in tests – D.R.Y. it up
• UI’s are resistant to testing. Make them as dumb as possible so they don’t
• Use in-memory databases (e.g. H2) for testing database access code
• Try a continuous test runner! MightyMoose (.NET), Infinitest (Eclipse),
* - except in life-threatening situations!
Continuous Integration in a nutshell
• Set up a server that watches VCS for changes
• When any changes occur, the server:
• Builds the solution
• Runs all unit tests
• Places the built files somewhere accessible (e.g. a shared development
• If there are any errors in any of the above, the server alerts everybody
on the team.
Continuous Integration Servers
Great Java/Maven integration
Huge plugin library for everything else
Great .NET integration (or so I’m told)
One of the first, but I don’t hear
about it as often
Quick tour of Jenkins (Is there really any
• This actually took me long enough to set up that I’m wondering if it’s
time I checked out TeamCity… Other JetBrains products are stellar…
• Take steps now to improve your final product later!
• There is some initial pain to get set up and to work within the
• Once you are used to it, your confidence in making changes will
increase while your bugs decrease.