Needle: Automated tests for your CSS

Needle is a tool for testing your CSS with Selenium and nose.

It checks that CSS renders correctly by taking screenshots of portions of a website and comparing them against known good screenshots. It also provides tools for testing calculated CSS values and the position of HTML elements.

Installation

If you haven’t got pip installed:

$ sudo easy_install pip

As root, or in a virtualenv:

$ pip install selenium
$ pip install needle

Getting started

Create test_bbc.py in an empty directory:

from needle.cases import NeedleTestCase

class BBCNewsTest(NeedleTestCase):
    def test_masthead(self):
        self.driver.get('http://www.bbc.co.uk/news/')
        self.assertScreenshot('#blq-mast', 'bbc-masthead')

This is a test case which tells the Selenium web driver (by default Firefox) to open BBC News and check the bar across the top of the page looks correct. assertScreenshot() take two arguments: a CSS selector for the element we are capturing and a filename for the image.

To create an initial screenshot of the logo, we need to run Needle in ‘baseline saving’ mode:

$ nosetests test_bbc.py --with-save-baseline

This will create screenshots/baseline/bbc-masthead.png. Open it up and check it looks okay.

Now if we run our tests, it will take the same screenshot and check it against the screenshot on disk:

$ nosetests test_bbc.py

If a regression in your CSS causes them to become significantly different, the test will fail.

Selecting a WebDriver

You may control which browser is used by Needle by overriding the get_web_driver() method:

from needle.cases import NeedleTestCase
from needle.driver import NeedlePhantomJS

class MyTests(NeedleTestCase):

    @classmethod
    def get_web_driver(cls):
        return NeedlePhantomJS()

    def test_something(self):
        ...

By default Needle uses NeedleFirefox, which is a wrapper of Selenium’s built-in selenium.webdriver.firefox.webdriver.WebDriver class. You may use any of the following WebDrivers: NeedleRemote, NeedlePhantomJS, NeedleFirefox, NeedleChrome, NeedleIe, NeedleOpera and NeedleSafari. Refer to Selenium’s documentation to learn how to install and configure any of those WebDrivers.

Setting the viewport’s size

You may set the size of the browser’s viewport using the set_viewport_size() method:

from needle.cases import NeedleTestCase

class MyTests(NeedleTestCase):

    def test_something(self):
        self.set_viewport_size(width=1024, height=768)
        ...

This is particularly useful to predict the size of the resulting screenshots when taking fullscreen captures, or to test responsive sites.

You may also set the default viewport size for all your tests with the viewport_width and viewport_height class attributes:

from needle.cases import NeedleTestCase

class MyTests(NeedleTestCase):
    viewport_width = 1024
    viewport_height = 768

    ...

Engines

By default Needle uses the PIL engine (needle.engines.pil_engine.Engine) to take screenshots. Instead of PIL, you may also use PerceptualDiff:

from needle.cases import NeedleTestCase

class MyTests(NeedleTestCase):
    engine_class = 'needle.engines.perceptualdiff_engine.Engine'

    def test_something(self):
        ...

Besides being much faster than PIL, PerceptualDiff also generates a diff PNG file when a test fails, highlighting the differences between the baseline image and the new screenshot. Note that you will need to download the perceptualdiff binary and place it in your PATH for this to work.

Indices and tables

Table Of Contents

This Page