As explained in my Summer of code 2017: Python post I decided to pick up Python
This is officially day 32. today I decided to take a look at unit testing. I decided to look at the unittest unit testing framework that ships with Python
The unittest unit testing framework was originally inspired by JUnit and has a similar flavor as major unit testing frameworks in other languages. It supports test automation, sharing of setup and shutdown code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework.
So let's see what it all looks like. First we are going to create a simple method and save it in a file named utils.py
This method will return what was passed in if it was none or a string, it will convert to utf-8 if bytes were passed in, for everything else a type error will be returned
def ToString(data): if isinstance(data, str): return data elif isinstance(data, bytes): return data.decode('utf-8') elif data is None: return data else: raise TypeError('Must supply string or bytes,' ' found: %r' % data)
To unit test this method, we are creating our test class and we will save this in a file named UnitTestSample.py
Here is what it looks like
from unittest import TestCase, main from utils import ToString class UtilsTestCase(TestCase): def test_ToString_bytes(self): self.assertEqual('hello', ToString(b'hello')) def test_ToString_str(self): self.assertEqual('hello', ToString('hello')) def test_ToString_bad(self): self.assertRaises(TypeError, ToString, object()) def test_ToString_none(self): self.assertIsNone( ToString(None)) def test_ToString_not_none(self): self.assertIsNotNone( ToString('some val')) if __name__ == '__main__': main()
We need to import unittest as well as our ToString method
As you can see, we have a couple of AssertEqual calls, AssertEqual tests that first and second are equal. If the values do not compare equal, the test will fail.
We also have assertIsNone and assertIsNotNone, these test that something is none or is not none
Finally we use assertRaises. AssertRaises tests that an exception is raised when callable is called with any positional or keyword arguments that are also passed to assertRaises(). The test passes if exception is raised, is an error if another exception is raised, or fails if no exception is raised.
Running the code above will give us this output, all 5 tests have passed
Running C:\Python\Projects\UnitTestSample\UnitTestSample.py ..... ---------------------------------------------------------------------- Ran 5 tests in 0.000s
To print out the name of each test, we need to change main and pass in verbosity level 2
In the code main will now look like this
main(verbosity=2)
Running the same test class again will give us also the test methods that were called, here is the output
The interactive window has not yet started. Running C:\Python\Projects\UnitTestSample\UnitTestSample.py test_ToString_bad (__main__.UtilsTestCase) ... ok test_ToString_bytes (__main__.UtilsTestCase) ... ok test_ToString_none (__main__.UtilsTestCase) ... ok test_ToString_not_none (__main__.UtilsTestCase) ... ok test_ToString_str (__main__.UtilsTestCase) ... ok ---------------------------------------------------------------------- Ran 5 tests in 0.016s OK The interactive Python process has exited. >>>
That is all for this post, if you want to know more about unit testing with Python, I suggest you start here: https://docs.python.org/3/library/unittest.html#module-unittest
You might also want to look at Nose2, you can find that here: http://nose2.readthedocs.io/en/latest/
nose2 is the next generation of nicer testing for Python, based on the plugins branch of unittest2. nose2 aims to improve on nose by:
- providing a better plugin api
- being easier for users to configure
- simplifying internal interfaces and processes
- supporting Python 2 and 3 from the same codebase, without translation
- encouraging greater community involvement in its development
No comments:
Post a Comment