Writing steps right
Subtleties of Cucumber test definitions
October 16, 2013The task: write a test step that verifies an image is in the correct aspect ratio. On our first pass, we can:
- verify exact pixel dimensions
- check the request url for an aspect in the request
- assert the proportions of the actual image
Exact pixel dimensions
Then /^the image dimensions are (\d+) by (\d+)$/ do |width, height|
expect(current_image.width).to eq(width)
expect(current_image.height).to eq(height)
end
This approach is fragile in the light of responsive design. Different browser sizes will result in different image sizes. Slight changes in markup require re-editing tests.
How do you diagnose the issue when this fails? What caused the issue? There are too many degrees of freedom/failure available to this approach.
Checking the request url
Then /^the image's requested aspect ratio is (landscape|square|portrait)$/ do |aspect|
expect(current_image.src).to include(aspect)
end
There are only three options (landscape, portrait, square) instead of all possible numbers. You can't run the test against an invalid value, because it won't match.
This test will tell us which crop was requested of the server via the url. This proves the correct request was made, but does not verify the correct image was retrieved.
This test is much more useful, but it doesn't actually solve the question we set out to answer.
Testing for aspect ratio
Then /^the image's actual aspect ratio is (landscape|square|portrait)$/ do |aspect|
test = {
landscape: ->(w, h) { w > h },
portrait: ->(w, h) { h > w },
square: ->(w, h) { h == w }
}[aspect.to_sym]
expect(test.call image.width,image.height).to be_true
end
Like the previous example, aspects are fixed. The new hash is a set of lambdas representing a test for the requested ratio.
The test is simple: look up the aspect test, call it with a width and height, and verify it returns true.
Conclusion
I use a combination of #2 and #3 in my current tests. In the past I would have used #1 (sparingly) but responsive images make this less useful, unless the dimensions are well-defined.