In late 2011 I hope we can all agree that unit testing is pretty important when creating websites or almost anything. Doesn’t really matter whether you prefer a blackbox integration testing approach or a strict unit testing style. What matters is that you have tests.

English: A series of build lights.

Image via Wikipedia

But what do you do when you want to test a form with a bunch of checkboxes?

You want to make sure all combinations of on/off tests are working. But with even just 6 checkboxes that’s 2^6=64 test and … well nobody in their right mind is going to write that many tests are they?

Last weekend I came up with a simple solution to this problem, dare I say elegant.

The approach is to make a list of checkboxes, then generate binary numbers from 0 to 2^(length of list). Then simply iterate over the generated binary numbers, pick all the checkboxes with a corresponding true bit in the number and run its test – the tests are lambda functions in a dictionary.

My code was complicated slightly because I had two distinct sets of checkboxes that had to be tested separately-ish, but here’s what this basically looks like in code.

    _columns = ['job_code', 'location_in', 'location_out', 'shift_report']
    def checkboxes(self):
        checks = []
        for i in range(2**len(self._columns):
            column_switch = bin(j)[2:].rjust(4, '0')
            checks.append([name for (yes, name) in
                           zip(column_switch, self._columns) if int(yes)])
        return checks

You also need to define the actual tests for all the checkboxes, deciding how thorough to be is a matter of personal taste, I like to test for the smallest possible symptom.

_column_checks = {
            'job_code': {True: lambda r:
                             self.assert_('<th>Job Code</th>' in r.content,
                                          "no code column"),
                         False: lambda r:
                             self.assert_('<th>Job Code</th>' not in r.content,
                                          "is code column")},
# and so on (this example has been violently snipped, likely missing a } or two

‘ in r.content, “no code column”), False: lambda r: self.assert_(‘Job Code

‘ not in r.content, “is code column”)}, # and so on

And finally the whole thing becomes a simple loop

     for checkboxes in self.checkboxes():
          # do a bunch of posts to django to set everything up
          for check in _column_checks.keys():
                _column_checks[check][check in checkboxes['columns']](response)

And that’s it. Simple easily modifiable code to test every possible combination of all checkboxes in a form.

Enhanced by Zemanta

Learned something new? Want to become a better engineer? 💌

Join 9,400+ people just like you already improving their skills.

Here's how it works 👇

Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet 📖 right away. After that you'll get a thoughtfully written email every week about React, JavaScript,  and lessons learned in my 20 years of writing code for companies ranging from tiny startups to Fortune5 behemoths.

Man, I love your way of writing these newsletters. Often very relatable and funny perspectives about the mundane struggles of a dev. Lightens up my day. ~ Kostas

PS: You should also follow me on twitter 👉 here.
It's where I go to shoot the shit about programming.