Getting started with pytest and Flask

Getting started with pytest and Flask

Test-driven development is something that you get to hear a lot. Being self-taught, I pick things as I go as I didn't have a chance to go through traditional education.

Test driven development-It's an aproach where we develop scenarios/test cases to ensure or validate that the code will do what it is developed to do.

In this article you should at least have:

  • Basics of python

  • Basics of flask eg SQL-alchemy,flask-migrate etc

What is pytest

While python has an inbuilt test library, pytest offers a more robust way to practice test-driven development.

Features
  • Detailed information on failing assert statements

  • Auto-discovery of test modules and functions

  • Modular fixtures

  • Rich plugin architecture

What is flask

Flask is a micro-framework built with python. It is made minimal to develop web applications quickly and has a rich set of libraries to meet your need. It is easy to start as once had one script with 400 lines run a whole monolith application that served content to users with authentication and content management—all in one file.

Let's get started with the data layer and create models and create tests for them. There are two types of tests we need to do:

  1. Unit tests- Here we test individual components of the code.

  2. Functional tests- This aims to ensure that the application meets its functional requirements.

I will provide the final repository and the code for your practice.

Data Layer: Unit Tests

Let's develop models. The application we want to make is a book application.

class Books(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(128),nullable=False)
    author=db.Column(db.String(128), nullable=False, default = "unknown")
    isnb=db.Column(db.String(128), nullable=False)
    pages=db.Column(db.Integer, nullable=False)
    description=db.Column(db.String(128), nullable=False)

    def __init__(self, title, author,isnb,pages,description):
        self.author=author
        self.description=description
        self.isnb=isnb
        self.pages=pages
        self.title=title

    def __repr__(self):
        return'<Book %s' % self.

Now we can develop simple unit tests to ensure that our model should work fine. The unit tests can be as follows:

def test_new_book():
    """
    GIVEN a Books model
    WHEN a new Book is added
    THEN check the author, title, isnb, description are added correctly
    """

    book = Books("Hello world", "JonDoe", "TU8738GFDHJJS778", 400, "Lorem Ipsum")

    assert book.author == "JonDoe"
    assert book.title == "Hello world"
    assert book.isnb != "WUEUEJSJHHJJs88183JJ"

The most important thing is to make sure the test fails first. The aim should be to create test cases based on what a user could do and make sure it meets all the requirements.

Usually, we develop tests using the following approach

  • Given- Given this(Can be a function, a class etc)

  • When- This new class is instantiated or the function is invoked,

  • Then-Make sure that what this unit/component is supposed to, meets all the requirements.

And that's how we develop the unit tests. To run the tests:

python -m pytest

Home page-Functional test

We will then create just a simple page that returns a message:

{"message":"Helloworld"}

We are going to do a functional test here. We have this controller that handles the logic which is a simple message.

def hello_controller():
    return jsonify(message="hellowrold")
@app.route('/')
def hello_world():
    return hello_controller()

To test if this function works correctly, we need to develop a functional test.


def test_homepage():
    """
    GIVEN a flask application configured for testing
    WHEN the "/" page is requested(GET)
    THEN check that the response is valid
    """

    with app.test_client() as test_client:
        response = test_client.get('/')
        res= json.loads(response.data)
        assert response.status_code == 200
        assert res['message'] == "hellowrold"

we write the test functions starting with test_* to help pytest find these modules.

test_client is used to provide a client to call the different routes to ensure that we can test functionality. We can also test the HTML also.

This is simply how we run tests in flask web applications. The use cases will vary depending on your requirements.