Announcing Quixote: CSS Unit Testing

I’m very excited to announce Quixote, an open-source library for unit testing CSS.

We’ve been working on proof-of-concept tests of CSS on the Live channel since the middle of June. It was challenging work, but we worked out all the major issues. Now I’m ready to take that proof-of-concept and turn it into a general-purpose library: Quixote.

I’m conducting a virtual hackathon October 13-16 to build the library. Join us!

Watch the video announcement here.

Why Unit Test CSS?

Same reason we unit test anything: refactoring and maintainability.

CSS gets complicated very quickly. It’s easy to have a lot of duplication and a rats-nest of styling rules. Most people take advantage of CSS’s cascading nature to eliminate duplication and control complexity, but that also makes it much harder to make changes safely. A big site can have hundreds of styles interacting with hundreds of pages—a combinatorial explosion that’s a nightmare to test fully.

Quixote will test how styles are expressed on your actual pages. Your tests will talk about positioning, stacking order, colors, and so forth. This will allow you to unit test specific markup and confirm that your styles are applied the way you expect them to be. That, in turn, will give you the confidence to refactor and improve your CSS.

Take control of your CSS. Test it, so you can maintain it.

What’s a “Unit Test” of CSS?

There are tools, such as the BBC’s Wraith, that test CSS by loading your HTML in a browser, taking a screenshot, and comparing that screenshot to a known-good version. Like most end-to-end integration tests, it’s slow and brittle.

In comparison, a CSS unit test involves setting up a specific, narrow scenario and testing one focused idea. For example, this test from our proof-of-concept code checks the way our logo is styled. It only looks at the logo and it runs in a fraction of a second:

it("centers logo at top of page", function() {
  expect(isContentCenteredInPage(logo)).to.be(true);
  expect(elementPixelsFromTopOfPage(logo)).to.be(12);
  expect(fontSizeOf(logo)).to.be("22px");
  expect(textColorOf(logo)).to.be(WHITE);
});

(I have ideas for vastly improving on the proof-of-concept’s assertions, by the way.)

A good unit test tool allows you to use the TDD “red-green-refactor” cycle: it’s fast enough, and targeted enough, that you can use your tests to drive your design.

Why Quixote?

There’s a surprisingly-large number of CSS test tools out there. The website csste.st has a rundown. Most of them work by taking screenshots or performing static analysis (linting). There’s a bare handful that actually enable a unit testing approach, and all but one are years out of date. The one remaining tool—Hardy—is nicely polished, but it uses a cumbersome custom syntax and relies on Selenium, an integration testing tool.

I think we can do better. With modern unit testing tools, such as Karma, Mocha, and Chai, we can already write proper unit tests, in JavaScript, that run cross-browser and execute in milliseconds. By adding Quixote to the mix, we’ll finally bring CSS under our control as well.

Yeah, it’s a bit crazy. A bit idealistic. Even a bit… absurd. (The name’s intentional, after all.) I’m doing it anyway.

I’ve proven the concept. Now it’s time to write the library. Join us!

comments powered by Disqus