Skip to content

Instantly share code, notes, and snippets.

@meza
Last active August 29, 2015 13:56
Show Gist options
  • Save meza/9069507 to your computer and use it in GitHub Desktop.
Save meza/9069507 to your computer and use it in GitHub Desktop.
Mini-blogpost in response of a twitter correspondence
/**
* Disclamer: This is sort of a rant, but without any negative feelings towards the creators of the project
* in question.
* I value their desire to help people write more readable code, and wish there were more people doing this!
* The only thing I'm questioning is the ever growing trend of tools over craft.
*
* This is a mini blog-post in response to https://twitter.com/hhariri/status/435457449232171008
*
* The reason I have some negative feelings is that writing readable code is not rocket
* science, and with tools like Spek, we're basically allowing people to be ignorant about crafting clean
* code.
*
* I'm not particularly happy with the pretense of the project, as the code used is indeed unreadable.
* I however don't see the solution in masking that unreadability by yet another tool, but in refactoring
* the code to make it self-documenting.
*
* With Spek, we create instant duplication of the code, in the comments. What happens if you change the
* income value or the expected outcome? You don't only have to change them in the test code, but the comments
* too.
*
* Let me quote the project readme:
*
* "Tests are specifications
* Tests are executable specifications of your system. They are real-time compilable code that tell you how
* a piece of code should behave and under what conditions is a certain outcome expected. That is why it is
* important to be explicit, concise and unambiguous when it comes to defining specifications."
*
* My point exactly!
*
* So without further ado, here's my version of the test in question.
* To be fair to the project, I haven't modified the interface of the TaxRateCalculator, although I would
* happily rename calculateRate() to rateOfIncome().
*
* @author meza www.meza.hu
*/
public class CalculatorTest {
@Test
public void testCalculateTaxRate() {
TaxRateCalculator calculator = new TaxRateCalculator(TaxRateCalculator.DEFAULT_LOCALE);
int income = 200;
int averageChangePerSemester = 10;
int actualRate = calculator.calculateRate(income, averageChangePerSemester);
int expectedRate = 300;
String messageOnFailure = String.format(
"The rate for an income of %d was not calculated correctly for an average change of %d per " +
"semester", income, averageChangePerSemester);
assertEquals(messageOnFailure, expectedRate, actualRate);
}
}
@hhariri
Copy link

hhariri commented Feb 18, 2014

Take your example:

You give the test the name:

testCalculateTaxRate

Firstly, I believe test is somewhat redundant and there for historical reasons if not anything else. You now pass in a locale to your constructor. Why? How do I know that Tax Calculations is subject to locale? This is something that someone at some point told me when speaking to the domain expert? Or is it written down somewhere? If it is, where?

Now, if you write:

given("Tax Calculator that is subject to locale changes")

this gives me something to contrast with.

Alternatively, you could write:

testCalculateTaxRateGivenATaxCalculatorThatIsSubjecToLocaleChanges

Same thing. Just one is more readable.

@hhariri
Copy link

hhariri commented Feb 18, 2014

Of course, we rely on people having to update the specs. But tell me, when are there more chances of having that done?When the spec is staring you right in the face or it's in some some document hidden somewhere else.

There's a certain level of professionalism required, much like that of not breaking tests or ignoring failed tests.

In terms of trusting the code, I don't think it's a question of trust as it is a question of understanding.

@matthewcannon
Copy link

I'm interested in this idea but I'm not sure I understand the notion of where the domain knowledge should "go", and how domain knowledge can be effectively communicated to developers new to a codebase. Would this level of domain specification not be expressed in the tests? If the developer is following a TDD cycle then the refactoring steps should have introduced appropriate abstraction in both the tests and the implementation? OCP, SRP, and ensuring there is no duplication between the tests and the implementation code should get us to this result. We should be left with test code that fully specifies the implementation, or am I missing something?

Regarding the discoverability of specifications where they are kept apart from the implementation, your codebase should be fully navigable in most modern IDEs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment