Understanding Unit Testing in Python

Written by terieyenike | Published 2022/09/04
Tech Story Tags: python | python-programming | unit-testing | python-tips | blogging-fellowship | python-development | software-testing | hackernoon-top-story

TLDRTesting your code is a vital part of the software development lifecycle, and it should always come before deploying the application to production. Unit tests are logical programs that a programmer writes to test a codebase. The test is crucial because it helps track and find bugs in the code. This article will teach you how to write basic tests using Python unit tests to check whether your code passes or fails during testing. The main aim of unit testing is to check if all the code functions perform as expected.via the TL;DR App

Testing your code is a vital part of the software development lifecycle, and it should always come before deploying the application to production. The test is crucial because it helps track and find bugs in the code.

Testing is a method of checking individual units of source code to confirm it works optimally before shipping code to production. It is important to note that deploying the source file to production for the users is unnecessary during unit testing.

It would be best if you also remembered that testing is not specific to Python.

This article will teach you how to write basic tests using Python unit tests to check whether your code passes or fails during testing.

Prerequisites

To complete this tutorial, you need the following:

  • Knowledge of writing Python code
  • An installation of the Python program on your local machine
  • A code editor of your choice

Getting Started

Writing tests are logical programs that a programmer writes to test a codebase. During development, a QA should understand the process to highlight what needs improvement in the app before shipping the product to the user. For this purpose, let’s write a function that sums two numbers and returns the result.

To begin, create a folder containing all the files for writing the test in this tutorial. Add a file named main.py to write the function in this new folder.

# main.py

# Add the sum of two numbers
def add_sum(num1, num2):
  return int(num1) + int(num2)

Now that we have the above code block let’s check that the code works by writing a function allowing users to enter their desired value via the input prompt. The function add_sum() takes two numbers as parameters and returns the value using the operator + sign to get the sum. In another file, result.py, copy and paste the following code:

# result.py

from main import add_sum

print("Please enter the two values\n")

num1 = int(input("Please enter the first number: \n"))
num2 = int(input("Please enter the second number: \n"))

total = add_sum(num1, num2)
print(f"The sum of the values is {total}")

This code block does the following:

  • Imports the add_sum() from main.py
  • converted the input prompt value to an integer using the int method
  • sums the values which print its total using the f-strings (formatting syntax) to get the output

What are Unit Tests and Test Cases?

Python comes with a built-in standard library module called unittest, which provides tools for constructing and running tests for your code. The main aim of unit testing is to check if all the code functions perform as expected.

A test case is a standard way to work with a unittest, with functionalities available in the test name class. Also, a test case is essential in the component code for individual unit testing. It uses different assert methods to check for and report failures immediately after running the code.

Passing a Test

This section is all about writing a series of tests.

Before creating the test file for writing all the test cases for the add_sum() function, let’s update the main.py. Copy and paste the following code:

# main.py

def add_sum(num1, num2):
        try:
          return int(num1) + int(num2)
        except ValueError as err:
                return err

The code block uses the try/except statement that handles exceptions in your code alerts you if there is an error in the except block. This method in programming helps catch errors and points you to the specific line number where the error occurred.

Now, create a test file in the same directory called test.py. In this file, copy and paste the following code:

# test.py

import unittest
from main import add_sum

class MainTest(unittest.TestCase):
        def test_do_stuff(self):
                result = add_sum(5, 10)
                self.assertEqual(result, 15)

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

As shown in the block of code above, the following occurs:

  • Import the unittest and function you want to test (it comes from the main.py)
  • Unittest works by creating a class containing the tests for the add_sum() function, which inherits inside the class what unittest gives, which is the unittest.TestCase
  • Define a function with the self keyword in the test_do_stuff() that represents the instance of the class
  • Within the test_do_stuff() test method, declare a variable and pass in the two arguments with different values
  • The last line uses the unittest assert method, assertEqual, which verifies that the arguments you pass from the result variable match the result you expect to receive
  • Finally, run the entire test file with the unittest.main()

Remember to start every method with the “test_” as the test.py runs automatically.**
**

Whenever you run a test, all the checks are expected to pass with an OK message in the console, meaning it was successful.

Ran 1 test in 0.000s

OK

Failing a Test

During development and testing, there should be scenarios for failure. Doing this shows that every program has vulnerabilities and bugs.

In the same file, test.py, let’s modify the code and paste in the following:

# test.py

import unittest
from main import add_sum


class MainTest(unittest.TestCase):
        # other test

        def test_do_stuff2(self):
                result = add_sum("hulu", 5)
                self.assertEqual(result, 5)
                
if __name__ == '__main__':
        unittest.main()

The result from running this code looks something like this:

FAIL: test_do_stuff2 (__main__.MainTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test.py", line 11, in test_do_stuff3
    self.assertEqual(result, 5)
AssertionError: ValueError("invalid literal for int() with base 10: 'hulu'") != 5

From the output above, the following can be resolved by reading the error code and correcting the code accordingly:

  • The error occurred on a specific line number, telling you to check and resolve the line number.
  • Next is the assertion error, which gives a value error signifying that the string ‘hulu’ is not a valid literal, knowing that in the main.py file, the two values are with the type of int
  • With this step, you know what to correct to make the code run the test OK with the correct values to pass to make the code successful.

Running the Code

When you have many files and different modules created, and you need to test all of them simultaneously instead of the default trying a single file, you can use this command to run all the tests simultaneously.

python3 -m unittest 

Also, to get more details about the test, use the command with the flag -v (verbose), which shows you the tests that are OK and the ones that failed.

python3 -m unittest -v

The result looks something like this:

test_do_stuff (test.MainTest) ... ok
test_do_stuff2 (test.MainTest) ... ok

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

Conclusion

Unit testing should be a practice done by the QAs and developers involved in writing and shipping code whenever a new feature is released before the users get to use the app. Doing tests regularly or periodically should not be an afterthought but rather build trust in how functional and efficient the app works.

This article gave you an overview of why tests are essential in the development and how to use unit tests to check the code function and meet a standard specification for users before deployment to production.

Learn More


Written by terieyenike | I am a frontend developer with a particular interest in making things simple and usable.
Published by HackerNoon on 2022/09/04