• No results found

Testing your code inside Docker

In document Learning Docker (Page 173-178)

In this section, we will take you through a journey in which we will show you how TDD is done using stubs, and how Docker can come handy in developing software in the deployment equivalent system. For this purpose, we take a web application use case that has a feature to track the visit count of each of its users. For this

example, we use Python as the implementation language and redis as the key-value pair database to store the users hit count. Besides, to showcase the testing capability of Docker, we limit our implementation to just two functions: hit and getHit.

NOTE: All the examples in this chapter use python3 as the runtime

environment. The ubuntu 14.04 installation comes with python3

by default. If you don't have python3 installed on your system, refer to the respective manual to install python3.

As per the TDD practice, we start by adding unit test cases for the hit and getHit functionalities, as depicted in the following code snippet. Here, the test file is named test_hitcount.py:

import unittest import hitcount

class HitCountTest (unittest.TestCase): def testOneHit(self):

# increase the hit count for user user1 hitcount.hit("user1")

# ensure that the hit count for user1 is just 1 self.assertEqual(b'1', hitcount.getHit("user1")) if __name__ == '__main__':

unittest.main()

This example is also available at https://github.com/thedocker/ testing/tree/master/src.

Here, in the first line, we are importing the unittest Python module that provides the necessary framework and functionality to run the unit test and

generate a detailed report on the test execution. In the second line, we are importing the hitcount Python module, where we are going to implement the hit count functionality. Then, we will continue to add the test code that would test the hitcount module's functionality.

Now, run the test suite using the unit test framework of Python, as follows: $ python3 -m unittest

The following is the output generated by the unit test framework: E

====================================================================== ERROR: test_hitcount (unittest.loader.ModuleImportFailure)

--- Traceback (most recent call last):

...OUTPUT TRUNCATED ...

ImportError: No module named 'hitcount'

--- Ran 1 test in 0.001s

FAILED (errors=1)

As expected, the test failed with the error message ImportError: No module named 'hitcount' because we had not even created the file and hence, it could not import the hitcount module.

Now, create a file with the name hitcount.py in the same directory as test_hitcount.py:

$ touch hitcount.py

Continue to run the unit test suite: $ python3 -m unittest

The following is the output generated by the unit test framework: E

====================================================================== ERROR: testOneHit (test_hitcount.HitCountTest)

--- Traceback (most recent call last):

File "/home/user/test_hitcount.py", line 10, in testOneHit hitcount.hit("peter")

AttributeError: 'module' object has no attribute 'hit'

--- Ran 1 test in 0.001s

FAILED (errors=1)

Again the test suite failed like the earlier but with a different error message AttributeError: 'module' object has no attribute 'hit'. We are getting this error because we have not implemented the hit function yet. Let's proceed to implement the hit and getHit functions in hitcount.py, as shown here:

import redis

# connect to redis server

r = redis.StrictRedis(host='0.0.0.0', port=6379, db=0) # increase the hit count for the usr

def hit(usr): r.incr(usr)

# get the hit count for the usr def getHit(usr):

return (r.get(usr))

This example is also available on GitHub at https://github. com/thedocker/testing/tree/master/src.

Note: To continue with this example, you must have the python3

compatible version of package installer (pip3). The following command is used to install pip3:

$ wget -qO- https://bootstrap.pypa.io/get-pip.py | sudo python3 -

In the first line of this program, we are importing the redis driver, which is the connectivity driver of the redis database. In the following line, we are connecting to the redis database, and then we will continue to implement the hit and getHit function.

The redis driver is an optional Python module, so let's proceed to install the redis driver using the pip installer, which is illustrated as follows:

$ sudo pip3 install redis

Our unittest will still fail even after installing the redis driver because we are not running a redis database server yet. So, we can either run a redis database server to successfully complete our unit testing or take the traditional TDD approach of mocking the redis driver. Mocking is a testing approach wherein complex behavior is substituted by predefined or simulated behavior. In our example, to mock the redis driver, we are going to leverage a third-party Python package called mockredis. This mock package is available at https://github.com/locationlabs/mockredis and the pip installer name is mockredispy. Let's install this mock using the pip installer: $ sudo pip3 install mockredispy

Having installed mockredispy, the redis mock, let's refactor our test code test_hitcount.py (which we had written earlier) to use the simulated redis functionality provided by the mockredis module. This is accomplished by the patch method provided by the unittest.mock mocking framework, as shown in the following code:

import unittest

from unittest.mock import patch # Mock for redis

import mockredis import hitcount class HitCountTest(unittest.TestCase): @patch('hitcount.r',mockredis.mock_strict_redis_client(host='0.0.0.0', port=6379, db=0)) def testOneHit(self):

# increase the hit count for user user1 hitcount.hit("user1")

# ensure that the hit count for user1 is just 1 self.assertEqual(b'1', hitcount.getHit("user1")) if __name__ == '__main__':

This example is also available on GitHub at https://github.com/ thedocker/testing/tree/master/src.

Now, run the test suite again: $ python3 -m unittest . --- - Ran 1 test in 0.000s OK

Finally, as we can see in the preceding output, we successfully implemented our visitors count functionality through the test, code, and refactor cycle.

In document Learning Docker (Page 173-178)