Testing colored output with Cucumber
I am improving a Command line app to manage my todos. I am developing it entirely ‘Behaviour Driven’, using Cucumber and Aruba.
All is pretty straightforward, but I had a hard time testing the colors in the output. Colors are made with Rainbow; which is really neat, but sometimes a little too smart. Rainbow detects when it outputs to something that cannot handle colors and turns them off. The solution turned out to be really simple though.
Lets start with a simple script that outputs some Rastafari
Running this, results in:
But piping this into a file, or for example less, shows no colors; This is a useful feature built into Rainbow. When testing with cucumber, the colors are gone too:
This passes, but does not test any colors. First thing is to tell
Aruba/Cucumber to not strip the colors, ansi-codes, with an @ansi
tag.
Next thing is to tell Rainbow to output colors regardless of where it outputs to. We need to do do this in the application itself, by making the application a little more testable. However, Aruba strips the colors for a reason: it is really hard to test when all your output is littered with ANSI escape codes. You really only want to force Rainbow to output them when you are testing for colors.
This allows you to force coloring when testing or running by setting the
variable, like so export FORCE_COLORS=TRUE; ./bin/example example
. A step could
them look like “When I run export FORCE_COLORS=TRUE; ./bin/example example
”.
More usefull however, is that we can set this variable in cucumber for
all the @ansi
-tagged scenario’s. In a support-file
features/support/ansi.rb
:
With the scenario tagged @ansi, it fails: expected
"\e[31mYah!\e[0m\n\e[30m\e[1m...\e[0m\n\e[33mRasta-\e[0m\n\e[32mfari\e[0m\n"
to include "Yah! ...
. Good.
Testing against strings like “\e[31m”, however, is both error-prone and unreadable. A simple new step definition, in which we add the ansi-escape codes, using Rainbow, to the to-be-tested string. Which allows us to test colors really easy.
The features/support/ansi.rb
should include “rainbow”.
Readable, easy testing of your colored output!