How to Add a Unit Test

What is and Why Unit Test

Unit test and unit testing are important concepts and activities that help us to write high quality code with productivity. Let’s highlight the folowing advantages:

  1. It allows part of our program to be test independently from ther others, hence helping us to focus on what we are testing.
  2. Unit testing can be automated, hence giving us a ability of testing our program automatically.
  3. It allows us to accumulate a suite of test cases. Imagine if I develop my feature with its corresponding test cases and you also do the same. Collectively we can test the different features of the program automatically.

Understanding Requirements

Let’s demostrate how to add a Unit to test the feature I am building, i.e. support of external hyperlink. Let’s understand the requirements:

_images/raw-hyperlink.png

As you can see above, hyperlinks are not displayed properly in the screen. We would like to add support for hyperlink such that:

  1. We would read the page line-by-line, and replace all `link description <link>`_ patterns such that they are instead become [ref=link]link description[/ref]. For example, the above link should be presented as [ref=https://en.wikipedia.org/wiki/Unit_testing]unit testing[/ref].
  2. There can be 1 or more hyperlink within single line. Each of them should be handled accordingly.
  3. Once clicked, a web browser should be launched to display the corresponding web page.

Let’s add a Unit Test for parsing and formatting the hyperlink as required above. We will leave launching a web browser to be done in the next module.

Adding Unit Test with Pycharm

  1. Add a method format_hyperlink(self, line) inside CourseApp class. For now, let’s simply add return line as its implementation.
  2. Add a file test_CourseApp.py. It should look like this. Press ALT-SHIFT-10 to run it.
_images/running-test-in-pycharm.png

As you can see. Pycharm will show you how many test cases are you passing / failing. In this case, as we haven’t implement anything yet in our format_hyperlink(self, line) function, it is expected that we have failing cases. Here we are demostrating one important feature on how unit test can be used to drive our development effort that:

  1. Before startng writing code, write test which fail first.
  2. Make change to pass tests.
  3. Repeat until you have passed all tests.

In later modules, you will see how we make use of unit testing to not just improve the correctness of our code, but also improve the quality of our code. We collectively call this effort a Test-driven Development (TDD) methdology. For now, let’s focus on writing code to passes all of our test cases first.

Implementing the Function to Pass the Tests

Let’s try implementing the function like the following:

def format_hyperlink(self, line):
  return re.sub('`(.*) <([^>]*)>`_', r'[ref=\2]\1[/ref]', line)

And run the test again. This time we have passed 2 cases, but leaving 1 case failing:

_images/pass-1-test.png

Now let’s fix our code to be the following:

def format_hyperlink(self, line):
  return re.sub('`([^`]*) <([^>]*)>`_', r'[ref=\2]\1[/ref]', line)

And run the test again. This time we have passed all tests. Cool!

_images/pass-all-tests.png

Discussion

  1. In the implementation above, we are using Regular Expression module to help us extracting information from a pattern and replacing the matching pattern with the re-formatted information that was extracted previously. You may check out this video for a tutorial.
  2. Once you have finished, in your own word, can you explain what does teh regular expression do which passes all the tests?
  3. Then, in your own word, can you explain why the first attempt does not work for more than 1 hyperlink?

Seeing the New Feature

So now my feature looks good. I can intrgrate my change to see it in shot:

_images/hyperlink.png