4
\$\begingroup\$

OK, maybe crazy overkill and a little silly, but why not? Here's a Python FizzBuzz Acceptance Test:

import unittest
from fizzbuzzmodule import fizzbuzz 

class FizzBuzzAcceptanceTestCase(unittest.TestCase):
    '''
    Test that fizzbuzz(int) returns int
    unless multiple of 3 (then returns 'fizz')
           multiple of 5 (then returns 'buzz')
           multiple of both (then returns 'fizzbuzz')
    '''
    def test_business_as_usual(self):
        '''
        test that an integer >= 0 not evenly divisible
        by three or five returns the same
        '''
        self.assertEqual(fizzbuzz(1), 1)
        self.assertEqual(fizzbuzz(2), 2)
        self.assertEqual(fizzbuzz(4), 4)
        self.assertEqual(fizzbuzz(7), 7)
        self.assertEqual(fizzbuzz(998), 998)
    def test_fizz(self):
        '''evenly divisible by 3 returns fizz'''
        self.assertEqual(fizzbuzz(3), 'fizz')
        self.assertEqual(fizzbuzz(6), 'fizz')
        self.assertEqual(fizzbuzz(111), 'fizz')
        self.assertEqual(fizzbuzz(999), 'fizz')
    def test_buzz(self):
        '''evenly divisible by 5 returns buzz'''
        self.assertEqual(fizzbuzz(5), 'buzz')
        self.assertEqual(fizzbuzz(10), 'buzz')
        self.assertEqual(fizzbuzz(20), 'buzz')
        self.assertEqual(fizzbuzz(500), 'buzz')
    def test_fizz_buzz(self):
        '''evenly divisible by 3 and 5 returns fizzbuzz'''
        self.assertEqual(fizzbuzz(15), 'fizzbuzz')
        self.assertEqual(fizzbuzz(30), 'fizzbuzz')
        self.assertEqual(fizzbuzz(45), 'fizzbuzz')
        self.assertEqual(fizzbuzz(600), 'fizzbuzz')

    # def test_zero(self):
        # self.assertEqual(fizzbuzz(0), 'fizzbuzz') #??????

def main():
    unittest.main()

if __name__ == '__main__':
    main()

Typed up a little implementation that passes these tests:

def fizzbuzz(number):
    '''
    if number divisible by 3 return 'fizz';
    5, 'buzz'; both, fizzbuzz
    else return number
    '''
    if not number % 3:
        if not number % 5:
            return 'fizzbuzz'
        else:
            return 'fizz'
    if not number % 5:
        return 'buzz'
    return number

def main():
    for i in range(1, 101):
        print fizzbuzz(i)

And when I run the tests:

>>> unittest.main()
....
----------------------------------------------------------------------
Ran 4 tests in 0.002s

OK

And my question is, how would you augment the above? Would you find it useful to run this test on someone's code? Does it clearly define a clean API? Would it be preferable to return a consistent type instead of strings or ints?

Should I have done this differently? Have I not considered any edge or corner cases?

\$\endgroup\$
2
  • \$\begingroup\$ you should remove the code golf part, or post it on the Code Golf Stack Site. \$\endgroup\$
    – Malachi
    Commented Jan 10, 2014 at 6:04
  • 1
    \$\begingroup\$ No code golf! :) \$\endgroup\$
    – Aaron Hall
    Commented Jan 10, 2014 at 6:06

1 Answer 1

4
\$\begingroup\$

For something so simple, it might be less overkill to use the doctest module. Write the expected calls and outputs in the docstring, then run python -m doctest -v fizzbuzzmodule.py. There's no need to write a separate class.

I've written one of the tests to ensure that the function also works when called with decreasing arguments.

As for the function itself, I believe that the code reads better if you write number % 3 == 0 instead of not number % 3. I would also use a conditional expression, but that's just a matter of personal preference.

def fizzbuzz(number):
    '''
    if number divisible by 3 return 'fizz';
    5, 'buzz'; both, fizzbuzz
    else return number

    >>> fizzbuzz(1)
    1
    >>> fizzbuzz(2)
    2
    >>> fizzbuzz(3)
    'fizz'
    >>> fizzbuzz(4)
    4
    >>> fizzbuzz(5)
    'buzz'
    >>> fizzbuzz(15)
    'fizzbuzz'
    >>> [fizzbuzz(i) for i in range(31, 20, -1)]
    [31, 'fizzbuzz', 29, 28, 'fizz', 26, 'buzz', 'fizz', 23, 22, 'fizz']
    '''
    if number % 3 == 0:
        return 'fizzbuzz' if (number % 5 == 0) else 'fizz'
    if number % 5 == 0:
        return 'buzz'
    return number
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.