简体   繁体   中英

How to use Python unit tests in self-contained program?

I want to use Python 3.3 with unit tests in small self-contained program, ie I don't want to split it up into a command line part and a "functional" part, which can be tested if it is started on itself on the command line.

So I have this little program:

import unittest

def stradd(a, b):
   return a + b

class test_hello(unittest.TestCase):
   def test_1(self):
      self.assertEqual(stradd("a", "b"), "ab")

unittest.main()
print(stradd("Hello, ", "world"))

Unfortunately, the print() is never reached, since unittest.main() exits the program. And even if it would not exit, it would print all kinds of output to the screen that I don't want to see in normal operation.

Is there a way to run the tests silently, as long as there is no error? Of course, they should complain loudly if something doesn't work.

I've seen Run python unit tests as an option of the program , but that doesn't answer my question as well.

It is possible to achieve the effect you want with a plain unittest module. You just need to write your own simple test runner. Like this:

import unittest

def stradd(a, b):
    return a + b

class test_hello(unittest.TestCase):
    def test_1(self):
        self.assertEqual(stradd("a", "b"), "ab")


def run_my_tests(test_case):
    case = unittest.TestLoader().loadTestsFromTestCase(test_case)
    result = unittest.TestResult()
    case(result)
    if result.wasSuccessful():
        return True
    else:
        print("Some tests failed!")
        for test, err in result.failures + result.errors:
            print(test)
            print(err)
        return False


if run_my_tests(test_hello):
    # All tests passed, so we can run our programm.
    print(stradd("Hello, ", "world"))

run_my_tests function will return True if all tests pass successfully. But if there is a test failure, it will print all errors/failures to stdout. For example:

$ python myscript.py 
Hello, world

$ # And now the test fails...
$ python myscript.py 
Some tests failed!
test_1 (__main__.test_hello)
Traceback (most recent call last):
  File "myscript.py", line 8, in test_1
    self.assertEqual(stradd("a", "c"), "ab")
AssertionError: 'ac' != 'ab'

Just use python's nosetests or py.test . Then you can write the code exactly the way you want to - with nothing except test_ functions added to the program and run tests via

$ nosetests filename.py

or

$ py.test filename.py

Also yeah no need of classes then:

def test():
    assert stradd("a", "b") == "ab"

Though it doesn't answer you "run silently" part. For me this + command line history works fine. For tiny programs ofc, basically snippets.

Other test frameworks won't help here because it's not test framework which is an issue here. Having said that py.test is the best one out there :).

The problem is unittest.main() function is designed specifically to run tests in a standard way and does not offer a way to customize this process in any way. This leaves us with two options

  • Use subprocess for running tests in separate process using unittest.main() , check the output and continue with running our program if all tests passed
  • Leave high level unittest.main() alone and use other facilities provided by unittest module

I'll write about both of these options as soon as I find some more free time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM