Intro to Unit Testing and Test Driven Development in Python Using Pytest – Part 1

by | 2 Nov 2017 | Coding Journey | 0 comments

Unit Testing and Test Driven Development with Pytest

Introduction to Unit Testing

In this series of articles we are going to tackle the dreaded subject of unit testing in an approachable way. We will build a small piece of functioning code, explain what should be and most importantly what should not be tested and why.

We will talk about test driven development and the reasons it may be worth to start implementing it in your coding practices very early.

We will learn to use mocks and patching to get rid of dependencies on external objects and libraries.

All of it will be full of pictures enabling you to visualise the problems in a very simple way so do not fear that you will get lost – you won’t.

Intro to Unit Testing and Test Driven Development in Python Using Pytest – Part 1

by | 2 Nov 2017 | Coding Journey | 0 comments

Unit Testing and Test Driven Development with Pytest

Introduction to Unit Testing

In this series of articles we are going to tackle the dreaded subject of unit testing in an approachable way. We will build a small piece of functioning code, explain what should be and most importantly what should not be tested and why.

We will talk about test driven development and the reasons it may be worth to start implementing it in your coding practices very early.

We will learn to use mocks and patching to get rid of dependencies on external objects and libraries.

All of it will be full of pictures enabling you to visualise the problems in a very simple way so do not fear that you will get lost – you won’t.

Why Would You Unit Test Your Code?

Imagine you walk into a car/motorcycle dealer to buy the machine of your dreams (whatever it may be, go for it – no price limits here). I suspect that you believe that every single component that makes that car / bike was tested to destruction. Then they put subsections together and tested them and then they assembled the entire thing and test driven it for hours in the lab and outside.

This belief is exactly what users of our software have when they lay their hands on it. The only difference is our product is not physical but has to be tested in exactly the same way.

Man sitting on a luxury sport car

You would hope that in this car they tested every single component to destruction…

Naturally when you first start programming the only way you know how to test your code is to run the .py file and see what happens. I do not hide that it was the way for me for quite a while until I decided to build an application big enough that this kind of testing was no longer a valid and efficient way of doing things.

The problem with this “manual” way of testing also is that you are not testing components but the entirety of your application. We just mentioned that we should start from component’s testing first, right? You also have absolutely no record in writing of what has already been tested and what not!

Why do we need to test all the components separately first? Because each of them has a unique function and logic involved which controls the behaviour of the application and unfortunately testing the entire program does not always allow us to create all possible system states that can expose errors in our thinking.

The bonus of learning to unit test early in your programmer’s journey is that it will be natural for you and will allow to find bugs much faster. Also later on when you will be refactoring your code to improve it you will notice that the existing tests help you fix the broken code much easier.

And besides unit testing is what you have to do professionally so there is no avoiding it no matter what. Just get on with it.

What Kinds of Tests Are There?

When we speak about unit testing focusing only on individual components it would be nice to know what are the tests that check bigger code structures.Key stages of software testing

4 Main Stages of Testing

  1. Unit testing which checks very small pieces of code.
  2. Integration testing in which several components are checked together to prove that their interfaces cooperate appropriately. Progressively we increase the amount of components tested until we get to point 3.
  3. System testing where we scrutinize an entire system (there can be many systems in our entire application).
  4. Acceptance testing – at this stage the software is checked for readiness to present it to the customer who also can be involved in the final tests (User acceptance testing / beta testing).

The Definition of Unit Testing

Unit testing is a development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation. Unit testing can be done manually but is often automated.Source: http://searchsoftwarequality.techtarget.com/definition/unit-testing

We can argue what we mean by smallest testable part of an application but for all intents and purposes of our object oriented programming style in Python we will consider a class (object) the unit that will be tested.

Convert the Definition to Plain English

Have a look at the image below showing what happens when we unit test our code. Our entire program is a combination of objects collaborating with each other. Extracting an object and mocking its dependencies in unit testing

The unit – our class, gets extracted out of the normal place in the code and tested in isolation. This means we are interested only in the logic of our object under test and nothing but that logic. To achieve this goal we remove dependency on external objects by mocking them out. This includes our own classes as well as methods from 3rd party libraries, IO operations, database calls and most importantly web API calls etc. etc…

Mocks are performing a role of test doubles / fake objects which can be told how to react to our normal methods being called upon them. They can return values which we want them to return and then we can assess the behaviour of our object under test with concrete set of returned values. They can also store a list of methods called on them and give us that information and many many more things which we will discuss further in this series of articles.

A very important aspect of unit testing is to make sure our tests are independent from each other. This guarantees us opportunity to run them individually and in any order we wish. You can imagine that in a larger code base you do not want to run entire test suite for the whole software every single time. You may be working on a small problem involving just one class and want to test only couple of methods. If your tests are independent from each other then you are able to do that.

Therefore you want to avoid an approach in which you set your object up for test at the top of the test module in the global scope and then incrementally change its state through consecutive tests assuming in each one of them the state from a previous test is now the new initial state. This leads to complete entanglement of the tests to each other and the only order they can be run is consecutively.

Summary

We have covered a lot of initial aspects that need to be explained in unit testing. We know now why we should test our code and what is the method of doing that.

In “Unit Testing the Universe – Part 2” we are going to look at object under test and determine what is the interface, what parts of the object we are going to test and which we will skip and why.

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

Created by: Tomasz Kluczkowski

Copyright © Tomasz Kluczkowski

Created by: Tomasz Kluczkowski

Copyright © 2017