0

Let's say i have a simple python program and a simple test file

iseven.py:

import math

def is_even(n):
    return n%2==0

print is_even(2)
print is_even(3)

and test_iseven.py:

import unittest
from iseven import is_even

class IsevenTests(unittest.TestCase):
    def test1(self):
        self.assertTrue(is_even(2))
        self.assertFalse(is_even(3))

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

Is there a difference in running the tests between

python test_iseven.py

and

python -m unittest test_iseven.py

? Because I've seen both in guides and tutorials, and output is identical. Also: The test is just for that one function, yet the whole program is executed when running the tests, so I get the program's output in the console. That is not supposed to happen, right?

1 Answer 1

1

Is there a difference between ...?

There is no big difference when it comes to executing the tests.

The main difference is that in the latter case, you can omit the

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

but you have to type more on the command line every time you want to run the tests.

So I prefer the first solution.

Python executes the whole program.

The behavior is correct. To be able to import is_even from the module iseven, Python has to parse the whole module. It can't really just look at the function.

Since Python is a scripting language, parsing the module means that it has to execute all the commands in it. From Python's point of view, def is a command like print which creates a new function instance and adds it to the current scope.

Or to put it differently: If it wouldn't run the print, it also couldn't run the def.

This behavior is often used to do magic. For example, in my i18n module for Python, I use:

@i18n
def name(): pass

At runtime, I collect all functions decorated with @i18n and turn them into code which checks the current language, loads the correct text from the translation file and returns it. That means I can do later:

print name()

and it will do the right thing.

EDIT Now you may have code in your module that you want to execute only when the module is run as a "program" (i.e. not when it's imported from somewhere else). Here is how you can do that:

def is_even(n):
    return n%2==0

def main():
    print is_even(2)
    print is_even(3)

if __name__ == '__main__':
    main()

General recipe: Always move all code into functions; avoid keeping anything at the "root" level of the module.

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

1 Comment

Well ok, thanks for the great answer.The second part is still annoying since it displays existing prints and means long runtime for a simple unit test if the main program does some number crunching. Also this is never mentioned in the videos :x

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.