Is it good to enforce a CSS code style guide?

The goal

Have SCSS stylesheets that look as if there written by 1 developer while working in a team.

Is this even an issue to begin with?

Frontend developers tend to be strict on the way they write CSS/JS but that’s not the main reason. Having organized and clean code is key for fast iterations. Everyone wants to be Agile these days.

If all the files look the same it’s easy to read and easy to pick up again in the future should the project require more phases.

How did we do it?

All recent projects at TBSCG have a build process (Grunt) to compile SCSS, JS, HTML, etc. So we simply included a linter task in that process.

We created a rules file to specify what want we wanted to enforce. Things like:

  • HEX color codes should be in variables. And even better, all in 1 file.
  • Spaces between brackets and class names.
  • Break lines between rules.
  • No !important anywhere 😎
  • Leading zero ( .5 vs 0.5 )
  • Order of the properties (did you know ordering the properties generates smaller gziped files than unordered?)

We only add this linter task to the dev build, so it will never crash in production should we commit a file with errors.
However, with the dev task Grunt will stop as we configured this to be errors not warnings.

Alright, I know what you must be thinking. In some cases hacks might be necessary (we all know how pesky CSS can be), there is a special markup to bypass the enforced rules. It should be used in very special cases. Otherwise the linter makes no sense.

Examples

Because code speaks better than me. Here are some examples of what I mean.

The following code fails to comply with the linter rules. Thankfully Atom knows that and highlights the problems even before I run my Grunt task, so I can fix them as I go.

linter-scss-errors

When running the Grunt task (in case your IDE does not warn you). Here’s the output:

SpaceBeforeBrace: Opening curly brace `{` should be preceded by one space

PropertySortOrder: Properties should be ordered bottom, display, position, width, z-index

DuplicateProperty: Property `bottom` already defined on line 4

SpaceBeforeBrace: Opening curly brace `{` should be preceded by one space

DeclarationOrder: Expected item on line 14 to appear before line 12. Rule sets should be ordered as follows: `@extends`, `@includes` without `@content`, properties, `@includes` with `@content`, nested rule sets

Now here’s the code fixed to pass the linter. Looks better, doesn’t it?

linter-valid-scss

Using it in a real project

Everything is great and all but can this be used in a real project? Does it make sense? Is it productive?

I won’t deny there’s a learning curve for those developers who are used to write code without any strict code style. I truly believe this is good in the long run. Once you get used to the rules, you’ll use them as you type.
The IDE is also important, you need to install the proper plugins to detect the linter config file, so it warns you without the need to run Grunt. In our case Grunt is our second line of defense. Your own editor should be the first to let you know.

Here’s the opinion of Artur Spulnik a Web Developer at TBSCG who worked with me on this real experiment:

Thanks to these principles code was much easier to read and maintain. I had to summon all my knowledge about the alphabet to correctly queue all definitions. There was a lot of pain in the beginning with operators order, and those wild spaces (or lack of them). But with practice comes success and I felt boost of productivity. Especially in terms of teamwork.

Have you ever written code this way? If you haven’t, will you give it a try?

Test Driven Development – But Why?

An introduction to the TDD methodology

Everyone knows that tests are needed, but do you know really why? What are the benefits?

smiling-business-person-300x199In the beginning of our projects, we are in a green field where every code we write is nice and works, the speed of the project is high, the number of bugs is low and developers and clients are happy.

As the project advance the code start to get messy, every time we have to make a change is harder, in more places and force us to hack our own code or add some nasty code.

manzanaAfter a few months our code is rotten, becomes rigid and fragile. The speed of the team decreases and the number of bugs increases. The developer is scared to introduce changes to the code and to refactor because he doesn’t know if he will break another functionality, all the bug fixes or changes to existing code are small hacks.

So the developer is scared to touch the code because it is too fragile, he needs some kind of protection that he doesn’t break any functionality. This protection are the Tests.

Imagine to have a suite of test that could detect the vast majority of the bugs that could be run just with the click of a button in a few minutes… this is what TDD aims for.

What is TDD?

Kent-Beck-ingeniero-de-softwareIt is an Agile methodology which consists in letting our tests drive the development of the product writing them first to force us to write the exact code that makes those test pass.

This technique was created/redefined by Kent Beck one of the 17 original signatories of the Agile Manifesto and is related to Test-First programming concepts of the Extreme Programming.

But why?

Reduce the debug time

imagesIf we have a complete suite of tests we keep writing and updating them and running quite often, every time there is a bug, this bug will appear in the test as an error, so is already spotted just when it was created, and it will be easier to fix since it is located in the code that we just wrote so it is fresh to our mind. You don’t have to spend hours debugging through the whole call stack to check when, where and about what is the bug.

Living documentation

imgresNormally when we try to use a new API we go directly to the examples of code that shows how to use the API, and sometimes we even copy & paste the example and try to tweak it to use it in our code. So well, the Unit tests are those examples. If you have a complete set of Unit test in your product you only need to take a look at them in order to know how your code works.

You have in your set of tests an example of every possible way to use your code. Is the perfect documentation that is reliable and is always updated.

The courage for change

hqdefaultThanks to the suite of unit tests that covers most of your code you can be sure that your code is working, this will eliminate the fear of the developer to change anything allowing him to clean the code and refactor freely. Tests stop the code from rotting.

Why to write tests first?

tddWriting tests first makes the production code testable. Ok that’s obvious but what is de benefit? If the production code is testable it means that it is decoupled, if you can test a part of the production code by separate in one unit test then that part is decoupled from the rest of the components. The more decoupled the system is the more flexible and extensible is.

You get a better design just by writing test first.

Normally if you write your tests after writing your production code they won’t be as complete as if they were written first because you already know your code works and it is boring to write only tests, sometimes you are tempted to take shortcuts and you miss some tests.

If you write the test first you are writing code to pass those test, so every line of production code is covered by a test. You trust your test, they are more complete than if you write them after.

And how do we do TDD?

It consists in a 3 phases cycle, known as red, green, refactor. This cycle must be very short and the iterations must be quite fast in order to not be much time outside of the green phase where all your code is working.

tdd-cycleThere are 3 phases:

Writing a failing test first.

Writing the production code to pass the test.

Refactoring the production and the test code.

In the Red phase we write a unit test that fails that will force us to write the production code that we want to write.

In the Green phase we are able to write the production code to make that failing unit test pass. We write no more no less.

In the Blue phase, when our production code works as desired, we clean the production and the test code, making it more sustainable, extensible, removing duplication, in other words, we clean the code.

The 3 laws of TDD.

TDD is a discipline, as any discipline it has a set of rules that for the beginners can sound a little extreme, but with time they will become more and more logical. Here are the 3 Uncle’s Bob TDD rules, read them well and understand them well:

• You are not allowed to write any production code unless it is to make a failing unit test pass.

• You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.

• You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

Follow these 3 rules and they will force you to write alternating between test and production code in short time periods and you will always have production code that is passing all the tests or at least was not long time ago.

At the beginning coding in the TDD way will be slow and hard, but with time you will change your mindset and you will be automatically thinking about features that your code should do, instead of solutions, writing tests for it instead of implementing the production code directly and thinking how to write your production code to be easily testable and decoupled from other functionality.

Most of the information was obtained from the teachings of Robert C. Martin Aka Uncle Bob in his videos. You can download his videos at CleanCoders.com and follow his company blog for more interesting articles 8thLight Blog.

Recommended lectures:

Clean Code – by Robert C. Martin

http://www.amazon.es/Clean-code-Handbook-Software-Craftsmanship/dp/0132350882

Growing Object-Oriented Software, Guided by Tests – by Steve Freeman and Nat Pryce

http://www.amazon.es/Growing-Object-Oriented-Software-Addison-Wesley-Signature-ebook/dp/B002TIOYVW

Test Driven Development. By Example – by Kent Beck

http://www.amazon.es/Driven-Development-Example-Addison-Wesley-Signature/dp/0321146530