Ah, I am so extremely excited about this it’s hard to write a blog post and stay on track. Oh, the possibilities!! Please note the WiH in the title of this post: that means “Written in Haste” i.e. largely unedited and incomplete and a “Just publish it, Lara“, kind of thing.
Over the past few days, I have been working on a ticket that I created for myself: “[SPIKE] CSS algorithms tests”. I’ve had an idea for testing CSS algorithms, and this ticket was for investigation into that idea. At PMC we are in the process of moving the CSS algorithms from Deadline to a shared repository, and that’s scary. There should be tests for those algorithms. But what does that even mean?
First, let me tell you about how much I fucking love tests.
I have been writing mostly Node scripts lately, working on getting all of the Larva (the name of PMC’s “embryonic” design system) code out of the Deadline theme and into a monorepo for sharing among other sites. “Node scripts” might sound fancy if you’ve never written Node scripts and never had a reason to (me, 10 months ago).
I’m learning this is the case for all of technology: it sounds really fancy and intimidating if you haven’t done it before, but once you have put in your time learning about it and then doing it wrong over and over, the concepts start to solidify and you realize there is no “secret sauce”. But then it can be hard to remember what it was like before you knew the technology, and that’s where all of the weird misunderstandings on Twitter and in life in general stem from. Maybe, probably.
Anyway…tests. One year ago, I knew jack shit about writing tests. That’s a crass way of saying basically nothing. But now, after a lot of fumbling around in PHP Unit tests and reading about the concepts from many different and having conversations and asking questions, I see the light! Two concepts that most helped me to understand tests are the test pyramid and forcing myself to try out test driven development in this Node scripting work.
There is some kind of legitimate magic that happens when you force yourself to stop writing code for a few minutes and, instead, write 1) a sentence about what the heck it is you are trying to code, and 2) a failing test that implements that future code.
It’s like working backwards: you name and call the function in a sandbox environment, then write the function code to make the test pass. Why is this magic?
- Your code is all but guaranteed to work,
- You have a system in place that will let you know when it stops working when you or someone else makes changes in the future,
- You have a speedy sandbox outside of the actual environment in which to run your code,
- The test will find all kinds of weird edge cases as you work that would otherwise likely not show up until the code was shipped or you have too much to do to fix it correctly.
I mean…doesn’t that sound like magic? It’s amazing and fun and satisfying and I just love it and I want to do this with CSS.
You might be thinking either of these things:
- “Okay, Lara, we get it, you drank the TDD Kool Aid.”
- “Well actually, Lara, you can test CSS with visual regression testing tools like Percy or Backstop.JS”.
In answer to number 1, sure, maybe, but hear me out! In answer to number 2, that is regression testing, and that is not what I am talking about here.
The thing is, test driven development happens with unit tests. Unit tests are small tests that run fast, outside of the production application. They test individual “units” of code. In an imperative language, a “unit” loosely maps to function or a class method, and there is some kind of test suite or tool for the language in question that you can use to run those tests, usually in the command line.
With CSS, this is tough. You need a browser. CSS is a domain-specific, declarative programming language, and the browser is the domain. What’s more, the declarative nature of CSS means that its implementation in browsers is constantly in flux (which is a Very Good Thing and one reason declarative languages are awesome) but, at least in 2019, that makes it pretty hard to write reliable tests for CSS without a browser. And a browser is a big ‘ol piece of software, which runs contrary to the unit test requirements of fast and outside of the production environment.
There are some kinda solutions out there like JSDOM or Headless Chrome, but JSDOM does not contain a complete implementation of the CSSOM, and given how much CSS evolves (which, again, is a feature not a bug for sure) it will probably not ever be reliably up to date with browsers unless A Big Tech Company decides it is in their interest to contribute to it in that way.
Yes, Headless Chrome is a solution, but that is only Chrome…
And that is where I am stopping this post. It is almost 6pm on Friday and I have a neighborhood community picnic to go to. The picnic is a potluck and I was not organized enough in time to make something, so I purchased some very beautiful and hopefully delicious baked goods from The Butterwood Bake Consortium. Bye!