Skip to main content

Posts

Showing posts from 2014

Pair Programming vs Pairing

I'm a fan of pair programming. I owe a lot of this practice to my improvement early on in my career. I define pair programming as two developers working on a task using one or more machines at the same time.I have had some excellent pair programming sessions. I can even remember some of them in great detail. Here I went away learning something new, solved a difficult problem, or just generally had a fun time.On the other hand I've also had some awful experiences, which unfortunately I can still remember. Here my partner wouldn't play the role of the driver or navigator correctly, wouldn't be engaged, or just generally didn't get into the flow of pair programming.Team's mandating 100% pair programming is bad. Some tasks don't need two developers to be working on them concurrently. Here pairing should be used. Pairing is two developers working together to solve a task, but doing so separately. During pairing regularly communication, design sessions and feedba…

A Unit is Not Always a Method or Class

Part three of my Three Steps to Code Quality via TDD series. The most important concept when coupled with the previous two points - not every unit will relate to a method or class.Part 1 - Stop Making Everything PublicPart 2 - Limit the Amount of Dependencies you Use Most introductions into TDD use simple examples. Even the excellent TDD by Example uses a value object in terms of Domain Driven Design. Most introductory articles on the Internet suffer the same fate. While these are great for demonstrations, they don't relate to what most developers need to code on a day to day basis. It's around this point where people proclaim that the benefit of automated testing (even after the fact) is a waste of time.One of my biggest revelations with TDD was that each unit does not need to equate to a single method or class. For a long time I followed what others did. Each collaborator would be injected and replaced with a test double. Each class would have a corresponding test file. Howe…

Limit the Amount of Dependencies you Use

Part two of my Three Steps to Code Quality via TDD series and ties very closely into step one, limiting the visibility of your classes.Part 1 - Stop Making Everything PublicPart 3 - A Unit is Not Always a Method or Class The more dependencies you use the more your tests are coupled to implementation.Consider the constructor below.Code like this is common and difficult to work with. Each dependency you inject requires a mock, stub or fake when writing tests. This couples the implementation to the test despite the use of interfaces or abstract base classes.Every public dependency here increases the resistance for change. If I was to remove the builder and replace with some equivalent code to construct a Bar instance, the test would fail despite being functionally equivalent. This is wrong.A constructor is part of the public API of an object even though this is not detailed as part of interfaces in languages such as C#/Java. Every collaborator that is provided by a constructor should hav…

Stop Making Everything Public

Part one of my Three Steps to Code Quality via TDD series.Part 2 - Limit the Amount of Dependencies you Use Part 3 - A Unit is Not Always a Method or Class We always default to public class when creating a new class. Why? The concept of visibility in OO languages appears very early on in programming books, yet more often than not most of the classes we create default to public visibility.@simonbrown stated that each time you make something public you need to make a donation to charity. In other words we should think more about why the class we are making should be visible to everyone. I really like this idea that the use of the public keyword should be a well thought out decision.Server side development has a part to play in the lack of concern given to visibility issues. Library or framework developers on the other hand must carefully consider what is part of the public API. Any changes made after are considered breaking and require careful consideration. Yet in the land of server s…

Three Steps to Code Quality via TDD

Common complaints and problems that I've both encountered and hear other developers raise when it comes to the practice of Test Driven Development are: Impossible to refactor without all the tests breakingMinor changes require hours of changes to test codeTest setup is huge, slow to write and difficult to understandThe use of test doubles (mocks, stubs and fakes is confusing)Over the next three posts I will demonstrate three easy steps that can resolve the problems above. In turn this will allow developers to gain one of the benefits that TDD promises - the ability to refactor your code mercifully in order to improve code quality.StepsStop Making Everything PublicLimit the Amount of Dependencies you Use A Unit is Not Always a Method or ClassCode quality is a tricky subject and highly subjective, however if you follow the three guidelines above you should have the ability to radically change implementation details and therefore improve code quality when needed.

Factory Obsession

I have noticed a pattern over the years with developers of which I will refer to as factory obsession. Everything is a factory or builder object. To some, the use of new is banned.Consider a object that is responsible for some business logic and finally saves the result to a persistent store.Message here is a value object, however the new can cause an odd fear within developers. Therefore a factory is required. Or is it? How can we test the repository is updated with the new message without reference equality?An example test in C#, using the Mock framework with this newly introduced factory would look like:This fear of new is wrong.Instantiating value types is a good thing.Instantiating entities is a good thing.Instantiating services can depend - if the service is expensive we don't want to create lots of instances on a whim.Here the factory offers nothing but a more strongly coupled solution.If we ignore the factory the test becomes easier to write. To do this equality should be …

Ratcheting

Some tasks in software development are mundane such as formatting and code conventions. Where possible tooling should take away some of this pain, however sometimes you need a developer to take on a task that requires a great deal of time and/or effort to complete. Tooling will only get you so far. An example of this would be declaring that all projects build and compile with zero warnings. I've tried this in the past after a team retrospective. We had hundreds of errors per project, covering about fifteen projects at the time. Spending several weeks of development time resolving these would not have be fun nor financially viable. However we really wanted to implement this changeSolutionI wrote a single test which would execute as part of the build process that asserted the count of the errors per project.Every now and then whenever I had some slack time (10 mins before a meeting, 30 mins at the end of the day etc...) I would open up a project and fix some errors. Then run the tes…

Dependency Injection (DI) Containers

StrengthsOne place for configurationRather than scattered through out the system. Most DI containers have some sort of "module" system where you group associated components together.ScopingDifferent types of lifestyle can be achieved. Per request, per thread, singleton and others. Usually other frameworks have the ability to plug into these containers, meaning such features integrate nicely.Feature richIncluded along with the basic DI components is usually a large amount of additional features which may or may not be needed.WeaknessesHeavyweightUsually in the form of frameworks or libraries. DI is a simple concept, but such containers can make getting to grips with it tremendously difficult.ConfigConfiguration can be difficult. Rather than just applying DI you need to learn the tooling. XML configuration has widely fell out of favour, but even code based configurations can be costly to setup.Runtime errorsAny errors that might have occurred at compile time (in a static langu…

Do it right - violate YAGNI

You Ain't Gonna Need It or YAGNI is about not writing code that is not needed. I've gone on to realise how important this is when it comes to programming for change.One of my biggest pet peeves that I have experienced working on agile teams is the excuse of YAGNI.YAGNI is no excuse for doing a "proper job". The third step of the TDD cycle allows you to take the simplest thing that could possible work and refactor it into something more dynamic, flexible or just plain better.If you spend your time writing the simplest thing possible such as brain dead procedural statements one after the next, the whole benefit of using TDD or writing automated tests is gone. You'd be more than capable of doing this yourself.My discover here was simple. Don't skip the refactor part of TDD. Don't allow someone to play the YAGNI card. Do it right.

Characterization Tests

Having worked with some truly awful codebases a common problem tends to arise every now and then. You need to make a change within some legacy component that most likely has limited or no automated tests around. This can be a scary process. There are a few techniques you can use to limit the fear of breaking some legacy code such as sprout methods or classes, however these aren't always optimal in all scenarios. Another option is characterization tests or "what is this bit of code actually doing?".Start with a simple test such as "ItWorks".Run the test - watch it fail.Using the stacktrace or error reported, write some additional setup.Run the test - watch it get past the previous error.Rinse and repeat step 3 - 4 until green.As part of the first step you should keep the initial test as simple as possible. For example if an input to the system under test (SUT) takes a Foo object, just instantiate Foo. Don't start setting values or fields on Foo. Let the fail…

Reinvent the Wheel, Often

We are often never told to reinvent the wheel. In other words, if your job is solve problems within Domain X you shouldn't spend your time recreating or solving problems that fall outside of this domain.For production code, this I agree with this statement fully. Software development is hard enough. The last thing we want is to waste resources such as time or money on anything we can get away with not implementing. For example, creating your own web framework is a project within itself. All you'll end up with is a slow, buggy, badly implemented version of a web framework that happens to power your domain. Sadly I have been on the receiving end of such decisions.There are two times however, when reinventing the wheel is a good thing.You can't get the product off the shelfLearning or personal benefitChances there is no web framework, database client, caching layer or so forth that you can use is very slim. Some systems become so bespoke or scale to such volumes that recreati…

DDD Validation

Validation within an application (specifically in terms of Domain Driven Design - DDD) can be solved in a variety of ways.A validate method on the entity/value type in questionAn IsValid property/accessor on the entity/value type in questionA separate service could be usedValidate MethodAdding a validate method would work, but the flaw with this approach is that you lack any context of what is happening to the object in question.Validate FlagSome sort of flag on the object that denotes whether or not the object is in a valid state is undesirable. Firstly it forces the developer to ensure they check this at the correct time. If the object is invalid, exactly what do you do at this point? This approach is often used with a combination of a validate method that returns the exact error messages.Validator ServicesA separate service seems less than ideal at first when you consider developing a richer domain model, but this solution has numerous benefits. Firstly unlike the two solutions abo…

Developer Diaries

A few weeks back I stumbled across a tweet which I unfortunately cannot find to give credit to. It talked about the benefit of keeping a developer diary.At the same time I was reading Getting Things Done (GTD). I felt inspired to take note of everything related to development that I do during my day to day time. This would satisfy the criteria I had for my GTD system, along with trying to emulate the success the original tweet was referring to.I don't have a fancy system. Rather I have a text file that is distributed between the numerous desktops and laptops I have access to. Here the file is synced, so I should always be up to date. Dropbox handles this for me. Each day I simply make a note of anything I think "I must remember that" or anything that happens to be useful, interesting or new. There is no complex system to this in order to keep in aligned with GTD, new points are simply appended at the bottom of the file. At the end of each week I simply group up related n…

Program for Change

We should program for change AKA the Open/Closed Principle. In my opinion, the OCP is one of the lesser respected SOLID principles. One of my biggest, and earliest failures fresh out of university was ignoring this concept.At the time I was applying YAGNI to some code myself and a couple of other developers were working on. After all agile methodologies promote this concept heavily. This made sense to me. My solution was to solve the problem with the minimal amount of fuss, however in doing so I strongly coupled the code we produced with the direct business requirements.The requirements stated that we would have three different types expenses. So I promoted that we model these three types of expenses directly. The UI knew about these expenses. The database knew about these expenses. The domain logic knew about these expenses.Everything worked well for a while. We finished early. We wrote just the code we needed. I was happy. Until the business requirements changed. The three types of …

Stop.Mocking.EVERYTHING

I've flip flopped on how to use mock objects since 2008. It's took me nearly five years to finally claim to have a solid, practical answer on what is in my opinion, their correct use.Mock EverythingSome developers told me to mock everything. Every. Single. Collaborator. I wasn't sure about this approach.My tests felt too brittle - tied to implementation details.My tests felt like a duplication of my production code.Your test count rises rapidly.This style of testing will slow you down - more to write/execute/debug.Mock NothingSome developers told me to mock nothing. Sometimes I never used mocks. I wasn't sure about this approach either.My tests felt too loose - it was easy to introduce bugs or defects.My production code suffered as I introduced accessors only for testing.No wonder I was confused. Neither approach seemed to be comfortable with me.SolutionUse mocks for commandsUse stubs for queriesThis halfway house is built around the idea of command and query separatio…

Acceptance Testing need not use the Full Stack

Joined a team with thousands of unit tests (~10k)But bugs still got through our QA processHow could this be?Team had a small number of full end to end live service testsSo my answer was to just increase the number of theseSurely this would solve our problem?Not quiteThe maintenance of these tests were a great burdenEach day many tests would fail, but nothing would be "broken".Data would have changed in the DBThe UI could have changedThe browser could have been slightly slowerAnd so onSolutionDelete the majority of live service tests - limit the tests to the core user journey through the applicationAs long as the pages load up, without an error we shouldn't careStopped testing logic or behaviour - made the tests loose, e.g. as long as value is not null or empty we are OK, we don't actually care what the value is.Made use of contract testing to substitute boundaries with in memory fakes, e.g. persistent storage. This allowed fast, stable acceptance tests to be run agai…

I Need to Stop Misusing Namespaces

At the recent NSBCon one interesting question that came about was how to structure a project. The panel consisting of various speakers had no answer, after all this is dependant upon the project in question. Therefore there is no right or wrong answer.However one point they were in unison about was splitting the domain and technical implementation of a project apart by the correct use of in namespaces.This is not the first time I've come across this, but I find myself breaking this principle on a regular basis. For example a typical project I work on looks like the following.ProblemsThe namespace reflects a technical implementation detail, and not the problem domain.Using Foo as an example, here the namespace is duplicated within the name of the types, which in turn defeats the point of namespaces.Another issue is that the types can be much longer than they need to be, which is often a criticism of enterprise software development, when the names of objects roll off the screen beca…

SOA Done Badly vs SOA Done Right

I was under the assumption I had been doing SOA for over 3 years. Previously I have had services which did stuff, these talked to other services which did other stuff and so on. We would group services around functionality.We would break these services down if they got too big to handle. Behind the scenes the services would talk to a single database. When it came to creating an application or system, these front end applications would invoke various services, which in turn invoked other services. This layered style of architecture worked for a while, so everything appeared to be fine.The overall architecture looked like this: Over time I began to question the benefit of this style. I spent more time coding than solving business problemsI spent more time debugging than solving problemsI spent more time fixing broken deploys than solving problemsI spent more time writing infrastructure (to glue services together) than solving problemsIt turns out this is actually quite a common style t…

The Importance of Tools

One of the most influential books I've read on software development has been The Pragmatic Programmer.One of the key points raised within the book is that of automation and tooling. For example, automating the build process is a very worthwhile undertaking. You should be able to check out some code and execute a script that will set up your machine, compile, test and deploy the code base in question.The key benefit of automating even trivial tasks such as automatically pulling down the latest code daily is that unlike developers, automating tooling will never perform the task wrong. Nor will they forget to do it. Ultimately this prevents the dreaded "works on my machine" issue.I've become such a fan of this approach to automating away any manual steps that some of the most used code I've written has been small scripts that execute hundreds of times a day. From a development point of view, the likes of good practices, SOLID, OO etc.. are usually void, such scripts…

Learning Tests

At the last Agile Staffordshire I attended the task was to complete the string calculator with constraints. The group worked in pairs and everything was running smoothly. Until I heard a few guys behind struggling with something.I'd worked with one of the developers previously, so they called me over to take a look. What he found was pretty shocking - they had found a bug in the .NET framework. The string class of all things. Bugs exist in all code. Bugs in the substring method though are probably rarer given how exhaustively used this particular bit of code is.The problem was how they expected the method to behave. When creating a substring they were getting confused with how the offests worked. This is an easy mistake. Different languages or frameworks can have different methods to do similar tasks. I take no shame in not knowing of the top of my head whether the offest of the substring method is an offset of the index, or an offset from the start of the string.I managed to spo…

Dont Tie Yourself to a Framework

Programming is greatSoftware development is the crap bit. You'll spend more time configuring, integrating and faffing rather than writing logic most of the time.Test Driven Development makes development easier as it forces you to decouple your code. Your core logic should be pure, dependency free C#, Java, Python etc.Your frameworks and libraries should be on the edge of the system.Most people do this for some of their code, e.g. your data access.What about the other parts of a system?Web frontendREST api'sConsole applicationsDesktop clientsWhy should we couple our applications with these layers?Hexagonal ArchitectureHexagonal Architecture is a solution to limit couplingEasily switch out your delivery mechanism, e.g. test runner adapter for testing, HTML adapter for production.Great example from Kevin Rutherford.Excellent video by Uncle Bob though terminology differs.Implementation details should be hidden behind adapters.Tested manually in the majority of casesFew integrati…

Flexible Selenium Tests via Page Objects

A fast, automated suite of unit and integration tests are not enough. At some point you'll need to test your presentation logic. Ideally your domain/business/game logic is stubbed so all you'll need to do at this point is check that the presentation is complete. For example, does view X load view Y? Does an error message appear when an error is raised?With web sites and web applications the standard tool to use is the excellent Selenium. The problem with UI tests in Selenium is they are often slower to write. Not only this the maintenance cost of such tests can often be much more expensive that other styles of tests. If the cost of such tests is high, the likely hood of developers writing UI tests is low. In my experience there are three types of UI tests in use.Low LevelHere UI tests are wrote directly against Selenium. This low level approach means tests are scattered with assertions and UI details. For example element locators such as divs and ids will be used with methods …

Design is Important

When I was a student I used to cheat. Not in exams or practical assignments, but I used to cheat when it came to my process to develop code. Early on I noticed a common pattern. After receiving an assignment I would perform some analysis, figure out a basic design and document my steps. The problem came when to code up the solution. I may have overlooked something, or made a mistake. Sometimes I would just come up with a better solution. This meant any time I spent documenting was lost. It turns out this wasn't cheating, after all there was nothing within the assignments enforcing a waterfall approach.I wasn't alone with this experience. Most of my peers had the same issue, and the report aspects of an assignment were often disliked for this very reason. My solution was simple. Code up something, get it working then document the design aspect. Rinse and repeat. Back in the early 2004 I wasn't aware of agile methodologies, but this solution worked a treat. In turn my classm…

TDD is a Tool

I remember being introduced to Test Driven Development (TDD) very well. This is because it had such an overwhelming change on how I write code day to day. It was incredibly alien, difficult, yet rewarding. On this journey for the last five years I've changed my style, learned how not to do it and finally found my "sweet spot" when it comes to pragmatic TDD.Deliver ValueWriting code is fun. Developing an application or system is fun. Using new technology is fun. Despite this the end goal should always be to deliver value. Delivering business value over religiously following a practice was a turning point in my journey. After all the user doesn't care about what is behind the scenes, as long as they can use your software, they're happy.When to Write Tests?One of the guidelines when starting TDD is"Never write a line of code without a failing test" - Kent BeckThis rule is wrong on many levels. Firstly it cripples most developers when starting TDD. Secondly…

The Correct Way to use var in C#

The .NET community is not widely controversial, though there is a strong topic that appears to come up time and time again when I pair with other developers - how to use var in C#.The var keyword was introduced in .NET 3.5. Unlike other languages this is still a strongly typed declaration. For example if we declare a string using var then we cannot re-assign this variable to another type. This would be a compile time error.There are two parties who have strong feelings about the use of var, both of which are wrong.Never use varSome developers suggest the use of var be denied. This leads to code such as the following. Overly verbose, and in some cases obscuring the intent of the code. This can commonly be seen when dealing with collections or generics.Always use varOther developers claim you should "var all the things". This leads to code which has the opposite problem from above. The intent of the code can be obscured due to not knowing what type you are dealing with. This i…

Top Down vs Bottom Up

Top down development has you starting at the highest point in the application that you can. From here you code down until there is nothing else left to develop. Once you reach this point you should be code complete. Along the way you may need to stub out areas that have not yet been created, or designed.Bottom up development has you starting at the lowest point in the application. The idea being that this part of the application has the most complexity or will be the most important. You will build the system up from a series of smaller components.Top down development and bottom up development was introduced to myself in my early days of university. At the time the distinction didn't really mean much - I was very much a developer who would work from the bottom up.Over time I have completely switched my stance on this. I believe agile practices and TDD are the reason for this change. I feel so strongly about this that I would go as far as to claim that within an agile team - bottom …