{"id":2196,"date":"2015-10-16T16:49:40","date_gmt":"2015-10-16T15:49:40","guid":{"rendered":"https:\/\/blogs.kent.ac.uk\/webdev\/?p=2196"},"modified":"2015-12-04T13:44:05","modified_gmt":"2015-12-04T13:44:05","slug":"css-testing-and-pattern-libraries","status":"publish","type":"post","link":"https:\/\/blogs.kent.ac.uk\/webdev\/2015\/10\/16\/css-testing-and-pattern-libraries\/","title":{"rendered":"CSS testing and pattern libraries"},"content":{"rendered":"<p>The <a href=\"http:\/\/www.kent.ac.uk\/is\/projects\/sds-replacement\/\">project I&#8217;m working on right now<\/a>\u00a0uses a bought-in piece of software with a complex set of patterns and styles. HTML elements can be used in different ways in different contexts, and the resulting css can be complicated and fiddly.<\/p>\n<p>To add to the complexity, much of the system has already been built (and is live) while the majority has yet to be built and is\u00a0actively evolving.<\/p>\n<p>If ever there were\u00a0a use-case for automated testing, this would be it.<\/p>\n<p>And yet as we all know testing web styling has in the past usually involved making changes, checking a few key pages, and then hoping everything will be ok. This works ok in smaller projects, but can be time consuming and error prone in larger projects.<\/p>\n<h2>PhantomCSS<\/h2>\n<p>I therefore looked at a handy visual regression tool called <a href=\"https:\/\/github.com\/Huddle\/PhantomCSS\">PhantomCSS<\/a>. It&#8217;s actually a <a href=\"https:\/\/github.com\/n1k0\/casperjs\">CasperJS<\/a> module which uses <a href=\"https:\/\/github.com\/ariya\/phantomjs\/\">PhantomJS<\/a> and <a href=\"http:\/\/huddle.github.io\/Resemble.js\/\">Resemble.js<\/a>\u00a0to compare baseline screenshots of a webpage with the current screenshots.<\/p>\n<p>Of course, comparing one complete web page with another complete web page isn&#8217;t much use, especially if those pages are dynamic.<\/p>\n<p>Far better is to compare your website&#8217;s building blocks in a pattern library.<\/p>\n<p>Luckily I already have a living pattern library for this project, which you can find out more about on my <a href=\"https:\/\/blogs.kent.ac.uk\/webdev\/2015\/09\/24\/building-and-hosting-a-pattern-library-on-github\/\">blog post about a github-hosted pattern library<\/a>. You might also want to bear Brad Frost&#8217;s <a href=\"http:\/\/bradfrost.com\/blog\/post\/atomic-web-design\/\">atomic design principles<\/a> in mind too.<\/p>\n<p>With a pattern library you can tell PhantomCSS to pick out the HTML examples (for example using an <code>id<\/code> on each example). It will then build screenshots of things like example panels, tables, forms and compare them to your baseline. Any differences will be picked up before you roll to live.<\/p>\n<h2>Setup<\/h2>\n<p>The great thing about PhantomCSS is that it&#8217;s pretty easy to set up. I&#8217;m not per se a full-on web developer (although I have some experience in that area) but I managed to get things set up pretty quickly.<\/p>\n<p>If you&#8217;re at all familiar with <a href=\"https:\/\/nodejs.org\/en\/\">node<\/a> and <a href=\"http:\/\/browsenpm.org\">npm<\/a>\u00a0then you can set up the required phantomcss, phantomjs, casperjs, and\u00a0resemblejs dependencies in your <code>package.json<\/code> file.<\/p>\n<p>You will also need the <code>phantomcss.js<\/code> config file. I had to manually copy this into my project, as I couldn&#8217;t figure out how else to include it. There might be a better way of doing this, but for now it works.<\/p>\n<h2>Get testing<\/h2>\n<p>Finally you&#8217;ll need to write your test suite file, using standard casperjs syntax.<\/p>\n<p>For example you&#8217;ll end up writing tests like:<\/p>\n<pre><code>\ncasper.thenClick('a[href=\"patterns.html\"]');\ncasper.then( function () {\n  phantomcss.screenshot( '#example-table', 'tables' );\n  phantomcss.screenshot( '#example-form', 'forms' );\n});\n<\/code>\n<\/pre>\n<p>where casperjs follows a link, loads a page, looks for certain elements, and takes a screenshot.<\/p>\n<h2>Any good?<\/h2>\n<p>I&#8217;ve so far used PhantomCSS\u00a0in a fairly experimental way. I certainly found it\u00a0to be much much nicer than having to check things manually!<\/p>\n<p>Setup and configuration was pretty simple even though I&#8217;m very far from being a hardcore dev.<\/p>\n<p>I would say that for this to work you really need a pattern library using the principles of atomic design. That will give you a great base for testing out all the possible design examples.<\/p>\n<p>In my current\u00a0project things were a bit more complex design-wise. It&#8217;s a pain but it&#8217;s just how things often are. So it made testing far harder, but still possible in many cases.<\/p>\n<p>For that reason I&#8217;d only advise automated css testing as a kind of fire blanket. It gives you peace of mind, but you will always need to do some manual testing as well.<\/p>\n<h2>Summary<\/h2>\n<p>PhantomCSS is a great tool for quickly and easily setting up some visual regression testing, preferably on your site&#8217;s pattern library (you <em>do<\/em> have a pattern library, don&#8217;t you?)<\/p>\n<p>It won&#8217;t cure all your most complex css testing issues, but it will give you an element of peace of mind that if you edit some css it won&#8217;t have some catastrophically weird effect somewhere else.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>PhantomCSS is a great tool for quickly and easily setting up some visual regression testing, preferably on your site&#8217;s pattern library (you do have a pattern library, don&#8217;t you?)<\/p>\n<p>It won&#8217;t cure all your most complex css testing issues, but it will give you an element of peace of mind that if you edit some css it won&#8217;t have some catastrophically weird effect somewhere else.<\/p>\n","protected":false},"author":2,"featured_media":2197,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1464,79395,79421],"tags":[79458,79455,28927,79392],"_links":{"self":[{"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/posts\/2196"}],"collection":[{"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/comments?post=2196"}],"version-history":[{"count":3,"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/posts\/2196\/revisions"}],"predecessor-version":[{"id":2200,"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/posts\/2196\/revisions\/2200"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/media\/2197"}],"wp:attachment":[{"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/media?parent=2196"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/categories?post=2196"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.kent.ac.uk\/webdev\/wp-json\/wp\/v2\/tags?post=2196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}