2

Below is a fizzbuzz program done TDD using unittest in one file, I run it in the command line using python fizzbuzz.py -v.

import unittest

class FizzBuzz():
    def fizz_buzz(self, number):
        if number % 3 == 0 and number % 5 == 0:
            return 'fizzbuzz'

        if number % 3 == 0:
            return 'fizz'

        if number % 5 == 0:
            return 'buzz'

        return str(number)

class FizzBuzzTests(unittest.TestCase):

    def setUp(self):
        self.fb = FizzBuzz()

    def test_one_gets_one(self):
        self.assertEqual('1', self.fb.fizz_buzz(1))

    def test_three_gets_fizz(self):
        self.assertEqual('fizz', self.fb.fizz_buzz(3))

    def test_five_gets_buzz(self):
        self.assertEqual('buzz', self.fb.fizz_buzz(5))

    def test_six_gets_fizz(self):
        self.assertEqual('fizz', self.fb.fizz_buzz(6))

    def test_fifteen_gets_fizzbuzz(self):
        self.assertEqual('fizzbuzz', self.fb.fizz_buzz(15))


if __name__ == '__main__':
    unittest.main()

I decided to split the file, as having the tests separate will read better.

The tree structure is

|-fizzbuzz
   |-app
     - __init__.py
     -fizzbuzz.py
   |-tests
     - __init__.py
     -test_fizzbuzz.py

I split the file as below (only showing part of it, one test and passing code)

#fizzbuzz.py
class FizzBuzz():
    def fizz_buzz(self, number):
        return str(number)

and

#test_fizzbuzz.py
import unittest
from fizzbuzz import FizzBuzz

class FizzBuzzTests(unittest.TestCase):

    def setUp(self):
        self.fb = FizzBuzz()

    def test_one_gets_one(self):
        self.assertEqual('1', self.fb.fizz_buzz(1))


if __name__ == '__main__':
    unittest.main()

In the fizzbuzz directory, i run tests with python tests/test_fizzbuzz.py which should pass.

But when I comment out the return str(number) or remove it, I still pass.

If I change self.assertEqual('1', self.fb.fizz_buzz(1)) to self.assertEqual('12', self.fb.fizz_buzz(1)) it is still running the code which is not there.

I deleted all the .pyc files in the test directory and now I get ImportError: No module named fizzbuzz error

If I move the fizzbuzz.py file into the test folder and run python tests/test_fizzbuzz.py the tests pass (this is how I got the .pyc files). But this is not what i want.

Why is this? Have I split this file up wrong? Am I missing extra code or files?

If I have split it up wrongly, what would be the best way to do so?

Any help appreciated, thanks.

1
  • fizzbuzz.py needs to be on your PYTHONPATH. But your use of __init__.py suggests that you want to use packages, in which case app is needs to be in your PYTHONPATH, and you should import app.fizzbuzz Commented Jun 13, 2016 at 16:08

1 Answer 1

1

It has to do with how python finds and executes code.

Python looks for modules/scripts/packages using sys.path. When you run a python script, it appends the directory of that script to sys.path which would be /etc/fizzbuzz/tests. This will not let python find the folder that contains fizzbuzz because it is in the directory above and not seen by python.

The easiest answer would be to add the file path to the directory above fizzbuzz to an evironment variable called PYTHONPATH. If the environment variable doesn't exist you can create it and python will add any directories in it to the sys.path.

Once this is done you will need to adjust a few things.

The import statements in test_fizzbuzz will need to change

from fizzbuzz.app import fizzbuzz

and change when you create fizzbuzz to

fizzbuzz.FizzBuzz()

alternatively you could change the import to:

from fizzbuzz.app.fizzbuzz import FizzBuzz

and you wouldn't need to change anything else.

Last thing, if you want to run any and all tests in the tests folder then you can run

python -m unittest discover tests

from the command line within the fizzbuzz project directory and it should find and run all tests in the tests folder. This would mean you wouldn't need the

if name == '__main__':

in the python files.

Hope this helps.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks managed to solve it. Just used python the hard way setup and used nosetest to run the tests and everything worked.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.