11

Sorry for the basic question. I have used unittest method to check my models in one script. Now, my question is how do I call this script from another file and save testing results. Below is my code sample:

**model_test.py**

import unittest
import model_eq #script has models

class modelOutputTest(unittest.TestCase):
    def setUp(self):
        #####Pre-defined inputs########
        self.dsed_in=[1,2]

        #####Pre-defined outputs########
        self.msed_out=[6,24]

        #####TestCase run variables########
        self.tot_iter=len(self.a_in)

    def testMsed(self):
        for i in range(self.tot_iter):
            fun = model_eq.msed(self.dsed_in[i],self.a_in[i],self.pb_in[i])
            value = self.msed_out[i]
            testFailureMessage = "Test of function name: %s iteration: %i expected: %i != calculated: %i" % ("msed",i,value,fun)
self.assertEqual(round(fun,3),round(self.msed_out[i],3),testFailureMessage)

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

The next step I want is to create another script called test_page.py, which runs the unit test script and save results to a variable (I need to post results to a webpage).

test_page.py    

from model_test.py import *
a=modelOutputTest.testMsed()

However, I got the following errors.

Traceback (most recent call last):
  File "D:\Dropbox\AppPest\rice\Rice_unittest.py", line 16, in <module>
    a= RiceOutputTest.testMsed()
TypeError: unbound method testMsed() must be called with RiceOutputTest instance as first argument (got nothing instead)

Can anyone give me some suggestions? Thanks!

Thanks for the help from Nix! My next question is: I need to test the function with two given cases in a loop. It is posted here.

Community
  • 1
  • 1
TTT
  • 4,354
  • 13
  • 73
  • 123

3 Answers3

21

You need to use a test runner

test runner A test runner is a component which orchestrates the execution of tests and provides the outcome to the user. The runner may use a graphical interface, a textual interface, or return a special value to indicate the results of executing the tests.

from unittest.case import TestCase
import unittest
from StringIO import StringIO
class MyTestCase(TestCase):
    def testTrue(self):
        '''
        Always true
        '''
        assert True

    def testFail(self):
        '''
        Always fails
        '''
        assert False

from pprint import pprint
stream = StringIO()
runner = unittest.TextTestRunner(stream=stream)
result = runner.run(unittest.makeSuite(MyTestCase))
print 'Tests run ', result.testsRun
print 'Errors ', result.errors
pprint(result.failures)
stream.seek(0)
print 'Test output\n', stream.read()

>>> Output:  
>>> Tests run  2
>>> Errors  []
>>> [(<__main__.MyTestCase testMethod=testFail>,
>>> 'Traceback (most recent call last):\n  File "leanwx/test.py", line 15, in testFail\n                assert False\nAssertionError\n')]
>>> Test output
>>> F.
>>> ======================================================================
>>> FAIL: testFail (__main__.MyTestCase)
>>> ----------------------------------------------------------------------
>>> Traceback (most recent call last):
>>>   File "leanwx/test.py", line 15, in testFail
>>>     assert False
>>> AssertionError
>>>
>>>----------------------------------------------------------------------
>>>Ran 2 tests in 0.001s
>>>
>>>FAILED (failures=1)
Nix
  • 57,072
  • 29
  • 149
  • 198
  • Thanks so much for helping with this issue!!! I have been learning your examples. One question, is there any documents I can find all the available methods for unittest.TextTestRunner (like result.testsRun, result.errors)? Also for stream.read()? – TTT Jan 11 '13 at 17:48
  • This might be of help: http://docs.python.org/2/library/unittest.html#unittest.TestResult it shows most of the things you can access in test runner. As for stream its a stringio which is a "file like" string. It should not be used if you are going to have a lot of output. You should write the output to a file instead, and then read from it. – Nix Jan 11 '13 at 17:51
  • Last question... Should I include 'assertNotEqual' if I want to print some messages about a function is successfully tested? – TTT Jan 11 '13 at 17:57
  • I dont follow that question. – Nix Jan 11 '13 at 17:59
  • Sorry. Currently, if assertEqual fails, I will get an error message. I am wondering if I can generate a successful message once assertEqual is passed. – TTT Jan 11 '13 at 18:00
  • 1
    Not sure why you want to do that, you can pass `unittest.TextTestRunner(stream=stream, verbosity=2)` and it will result in something like: `testTrue (__main__.MyTestCase) ... ok` – Nix Jan 11 '13 at 18:08
  • Is it true that only the first iteration of the loop has been tested? Please check the updated post. – TTT Jan 11 '13 at 18:15
  • In python3, this works for me with no stream argument: `runner = unittest.TextTestRunner(); result = runner.run(unittest.makeSuite(MyTestCase)); print(result)` – JeremyDouglass Mar 25 '19 at 04:25
1

Assuming you have your unit tests located in the "test" directory:

# Tested in Python 3.8
# https://docs.python.org/3/library/unittest.html#module-unittest
from unittest import TestLoader, TestResult
from pathlib import Path


def run_tests():
    test_loader = TestLoader()
    test_result = TestResult()

    # Use resolve() to get an absolute path
    # https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve
    test_directory = str(Path(__file__).resolve().parent / 'test')

    test_suite = test_loader.discover(test_directory, pattern='test_*.py')
    test_suite.run(result=test_result)

    # See the docs for details on the TestResult object
    # https://docs.python.org/3/library/unittest.html#unittest.TestResult

    if test_result.wasSuccessful():
        exit(0)
    else:
        # Here you can either print or log your test errors and failures
        # test_result.errors or test_result.failures
        exit(-1)

if __name__ == '__main__':
    run_tests()
Jesuisme
  • 1,805
  • 1
  • 31
  • 41
0

Remove .py from header from model_test.py import *

mnille
  • 1,328
  • 4
  • 16
  • 20