To fully isolate the tested unit, we must be able to stub its dependencies. In many programming languages, stubbing hard-coded constructors is impossible. The Dependency Injection pattern is the go-to solution for this problem – it allows us to extract dependencies into parameters provided from the outside of the tested unit, which in turn allows us to substitute them with stubs.
Continue reading “Test isolation: Dependency Injection vs stubbing constructors”
One of the defining attributes of Unit Tests is isolation. Even the name “Unit” implies it. Well isolated tests make it easier to pinpoint errors, are less brittle, and run faster.
But are your tests really well isolated? And are they easy to isolate or are they painful to setup?
Continue reading “The 4 steps towards well isolated tests”
In one of my previous posts, I wrote about the single and right level of abstraction. In that article, I focused on the code and unit tests level. However, the single and the right level of abstraction principle applies also at a much higher level – at the level of specification by example. The driving force behind it is different than in the case of unit tests though, so it’s worth a separate discussion.
Continue reading “The single and correct level of abstraction at the specification by example level – 5 rules to write good examples”
If we can’t, for some reason, have 100% test coverage, which parts of the system should we cover and to what degree?
What will give us more value:
- to cover only main positive scenarios, but for all features
- to cover only a few most important features, but in 100%
- to strive for as high coverage in as many features as possible, deciding what to cover with tests on a case-by-case basis
Many teams new to TDD or working on legacy projects struggle to achieve full test coverage for all features, so questions like this are not uncommon.
Let me share my opinion on this topic.
Continue reading “The most important thing about test coverage is consistency”
An old TDD dogma says that there should be only a single expectation per spec 1.
I agree that this is a good rule of thumb, but as with all such extreme advices, you shouldn’t follow it blindly. To better understand why the single expectation heuristic is useful, let’s focus on the impact it has on the two core aspects of BDD-style specs: acting as living documentation and guiding the design of the system.
Continue reading “Only 1 expectation per spec – an empty dogma or not?”
There are two popular styles of formatting test descriptions:
it('should do something') and
it('does something'). Which style should you use? Is any of them objectively better, or is it just a matter of personal taste?
To help us decide, let’s take a look at
does test styles from three points of view:
Continue reading “It should or it does?”
Developing new features using BDD is a very clean process. Our tests are always driven by user requirements. We split these requirements into several levels using nested contexts. We organize them into a neat structure, resembling almost end-user docs – and telling the coherent story of our system.
Unfortunately, things tend to become less tidy when bugfixing.
Continue reading “How to bugfix in a BDD way”
The tests are a mess!
There is a plethora of different kinds of automated tests. If we check out the Wikipedia entry on Software Testing we can find many specialized types of tests: sanity, smoke, usability, security, conformance and so on.
Similarly, the so called “test pyramid” model, popularized by Mike Cohn in his Succeeding with Agile book, also has several variants, with a different number and differently named layers:
Continue reading “The 3 kinds of tests you must understand to do effective TDD”
An interesting question arose during one of code reviews in our team: if there’s a constant 1 in the production code, should it be reused in the spec or should we use a literal value?
The one side of the argument was that using the literal value is a duplication. When this value changes, we have to update it both in the code and specs – therefore the constant should be reused.
The other side of argument was that the specs should work as a “double verification” mechanism, and thus avoid code reuse – otherwise, they will give false positives when the value of a constant is wrong.
Both arguments seem legitimate. Which approach should we choose, then?
Continue reading “Should we reuse constants between code and specs?”
The straightforward interpretation of the Single Level of Abstraction principle is to avoid mixing high and low level details in the same code.
Even at such a basic level it gives a lot of benefits. It helps keep the code focused, readable and easy to understand.
However, we can take this idea a step further.
Continue reading “The Single and the RIGHT Level of Abstraction”