The Benefits of Writing Unit Test
- Unit tests prove that your code actually works.
- You get a low-level regression-test suite.
- You can improve the design without breaking it.
- It’s more fun to code with them than without.
- They demonstrate concrete progress.
- Unit tests are a form of sample code.
- Test-first forces you to plan before you code.
- Test-first reduces the cost of bugs.
- It’s even better than code inspections.
- It virtually eliminates coder’s block.
- Unit tests make better designs.
- It’s faster than writing code without tests!
Python unittest
Below is my python unittest template:
import unittest
import os
import string
from random import sample
from mock.mock import patch
#from nose.tools import with_setup
# setup_module/teardown_module effects on this module
def setup_module(module):
pass
def teardown_module(module):
pass
# setup_by_decorator/teardown_by_decorator effects on using @nose.tools.with_setup
# Please note that with_setup is useful only for test functions, not for test methods in unittest.TestCase subclasses or other test classes. For those cases, define setUp and tearDown methods in the class.
#def setup_by_decorator():
# pass
#def teardown_by_decorator():
# pass
#special_test = with_setup(setup_by_decorator, teardown_by_decorator)
#@special_test
#def test_special_case(self):
# pass
#mock toggle
mock_flag = int(os.getenv('ENABLE_MOCK', 0))
dynamic_mock_return_result={
args_key_word : mock_expect_return_value,
}
random_string_lenth = 8
class MyTestCase(unittest.TestCase):
# setup_class/teardown_class effects on the current class
def setup_class(cls):
pass
@classmethod
def teardown_class(cls):
pass
# Extension method for unittest module
def assertNoRaises(self, func, *args, **kwargs):
try:
func(*args, **kwargs)
except IXIASessionException:
self.fail("%s fail" % func)
#setUp/tearDown effects on each test method in this class.
def setUp(self):
if mock_flag:
patcher = patch('package.module.ClassName.method')
self.addCleanup(patcher.stop)
self.mock_method = patcher.start()
# dynamically varying the return values
self.mock_method.side_effect = lambda *args, **kwagrs: dynamic_mock_return_result[args_key_word]
print ("\n===> Unit Test [%s] Start..." % __name__)
def tearDown(self):
if self._resultForDoCleanups.errors:
'''
Note that in order to test something, we use one of the assert*() methods provided by the TestCase base class. If the test fails, an exception will be raised, and unittest will identify the test case as a failure. Any other exceptions will be treated as errors. This helps you identify where the problem is: failures are caused by incorrect results - a 5 where you expected a 6. Errors are caused by incorrect code - e.g., a TypeError caused by an incorrect function call.
'''
print ("\n===> Unit Test [%s] End..." % __name__)
def test_api_without_exception(self):
''' Prove that your code actually works. '''
self.assertNoRaises(package.module.ClassName.method, args_x)
#input a ramdom string and expect Exception raise
with self.assertRaises(Exception):
package.module.ClassName.method(''.join(sample(string.printable, random_string_lenth))
def test_scenario_as_demo(self):
''' A form of sample code. '''
# mock the method with context.
with mock.patch.object(client, 'send_request', return_value=fail_send):
self.assertEqual(get_response(), status_code)
if __name__ == '__main__':
unittest.main()
Reference:
Mock patch usage
Mock side effect usage
Python testing frameworks: Selecting and running tests
Testing with nose
nose extends unittest to make testing easier
Python & Jenkins
The detail, please refer to above hyperlink.
- Install Jenkins on Ubuntu
- Clone and install a Python application in a virtualenv
- Run tests using nose and publish tests results, code coverage and pylint reports
- Have Github notify Jenkins when new code is pushed
Jenkins Report
I prefer to use Jenkins restful api that can get jenkins jobs info easily to generate a html file, and sent it by Jenkins plugin Email Extension Plugin
Reference:
Orchestrating Your Jenkins Pipelines With Python and Jenkins API
#Coming Soon...
——