Self-hosted service
mjhea0/flaskr-tdd avatar
mjhea0/flaskr-tdd

Flaskr-TDD: building a Flask mini-blog with test-driven development and pytest

Flaskr: Intro to Flask, Test-Driven Development (TDD), and JavaScript

2,344 stars515 forksPythonMIT

At a glance

What is it?
Flaskr-TDD walks Python developers through building a Flask mini-blog using test-driven development, adding pytest, Flask-SQLAlchemy, JavaScript, linting, and Postgres deployment to the official Flask tutorial. The tutorial targets Python 3.12.0 and Flask 3.0.0.
Who is it for?
Flaskr-TDD suits a developer who wants to see TDD applied to a Flask project from the first route to deployment, rather than learning TDD in isolation. The content most relevant to writing tests, building routes with Flask-SQLAlchemy, and adding JavaScript is in the TestDriven.io article, not the README file, which ends after the first test.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A stepped Flask mini-blog tutorial that introduces each feature through a failing test first

Flaskr-TDD extends the official Flask tutorial by layering test-driven development, JavaScript, and production deployment onto the standard mini-blog app that Flask's documentation uses for teaching. The official tutorial builds a blogging app called Flaskr; this repository retakes that same app from scratch, introducing each feature only after a test is written for it and observed to fail first.

Python developers who have finished a beginner tutorial and want to see how TDD integrates with Flask development rather than being taught as a separate discipline are the intended audience. The README lists three prerequisites it expects the reader to already grasp: the difference between HTTP GET and POST requests, what HTTP requests and responses are, and how HTML pages are rendered. The tutorial does not teach these concepts; it uses them.

Beyond TDD, the repository adds JavaScript for front-end interactivity, Black and Flake8 for formatting and linting, SQLAlchemy for database access, and Gunicorn plus Postgres for deployment. A developer who finishes all sections has worked through the stack but is not left with a production-ready application: the tutorial is a learning exercise, not a template.

Red-Green-Refactor: four steps that drive every feature from a failing test

Test-Driven Development follows the Red-Green-Refactor cycle. Write a test that describes the desired behavior, run it and confirm it fails, write the minimum code needed to make it pass, then refactor the code with the passing test suite providing a safety net against regressions.

In Flaskr-TDD, this cycle starts from the very first step. The project separates application code in `project/` from test code in `tests/`, and the first test in `tests/app_test.py` imports the Flask app and asserts that a GET request to the index route returns status code 200 and the response body `b"Hello, World!"`. That test file is written before the route exists. Running it fails. The exercise is to write just enough code in `app.py` to make it pass without writing anything beyond what the test requires.

Pytest v7.4.2 is the test runner. Python's standard library includes unittest, but the tutorial uses pytest throughout. A developer who prefers unittest would need to adjust imports and test function signatures before the first run.

Python 3.12.0, Flask 3.0.0, and pytest 7.4.2: setup steps and the first test

The setup begins with Python 3.12.0. Create a project directory, set up a virtual environment, and install Flask:

sh
$ mkdir flaskr-tdd
$ cd flaskr-tdd
$ python3.12 -m venv env
$ source env/bin/activate
(env)$ pip install flask==3.0.0

To exit the virtual environment later, run `deactivate`. To re-enter it, change back to the project directory and run `source env/bin/activate` again.

After the Flask install, create `project/` and `tests/` directories each with an `__init__.py` file, then add `app.py` inside `project/` and `tests/app_test.py`. Install pytest separately:

sh
(env)$ pip install pytest==7.4.2

The first test uses `app.test_client()` to make a request against the Flask app without running a server:

python
from project.app import app


def test_index():
    tester = app.test_client()
    response = tester.get("/", content_type="html/text")

    assert response.status_code == 200
    assert response.data == b"Hello, World!"

Running `pytest` before adding a route to `app.py` will fail because the import itself fails when the module has no content. Adding a minimal route that returns the string makes the test pass. The structure of the test file stays in `tests/app_test.py`; the tutorial renamed it from `app.test.py` in October 2020 to match pytest discovery conventions.

Flask-SQLAlchemy, Black, Flake8, psycopg2-binary, and Gunicorn in requirements.txt

All eight dependencies are pinned in `requirements.txt` to specific versions: Flask 3.0.0, Flask-SQLAlchemy 3.1.1, Gunicorn 21.2.0, psycopg2-binary 2.9.9, Black 23.10.0, Flake8 6.1.0, and pytest 7.4.2. Black handles code formatting automatically; Flake8 checks for style violations. Both were added to the tutorial in November 2019, at the same time jQuery was replaced with vanilla JavaScript.

Flask-SQLAlchemy provides the database abstraction layer. The presence of psycopg2-binary alongside it indicates the production deployment uses Postgres rather than the SQLite file the development environment uses. The `test.db` file at the repository root is a committed SQLite database from a prior test run. Committing a mutable database file to a shared repository means that different developers working from the same checkout start with different database states if they have already run their own tests locally.

Gunicorn is the WSGI server for deployment. The repository contains a `Procfile` at the root, the file that Heroku reads to determine how to start the application process. A developer who wants to serve the app with a different WSGI server or on a different platform would need to replace or supplement this configuration.

Tutorial content splits between the repository and TestDriven.io; Heroku is the only documented deployment target

The repository README covers the setup and first test. The table of contents lists 18 sections: TDD introduction, Python setup, project setup, first test, Flaskr setup, second test, database setup, templates and views, styling, JavaScript, deployment, Bootstrap, SQLAlchemy, search, login requirements, Postgres on Heroku, linting, and a conclusion. Of those, only the sections through the first test are in the README file. The content on SQLAlchemy, JavaScript, search, login, Postgres, linting, and Bootstrap is in the TestDriven.io article, which the repository's README links to at testdriven.io.

The deployment path in the tutorial targets Heroku through the `Procfile` and psycopg2-binary. A developer who wants to deploy the application elsewhere would need to adapt those files independently, as the tutorial does not document alternatives.

The tutorial also uses `pathlib` for path handling, having migrated from `os.path` in October 2020. A developer following an older copy of the tutorial that predates this change would encounter differences in the path code. This migration is noted in the update log but not explained in the tutorial text.

The official Flask tutorial and TestDriven.io courses: where Flaskr-TDD sits relative to alternatives

At flask.palletsprojects.com, the official Flask tutorial covers the same Flaskr mini-blog application. The README for this repository states that the goal was to go further than that tutorial by adding TDD, JavaScript, and deployment. A developer who has already finished the official Flask tutorial and wants to add TDD to that knowledge has a clear reason to use this repository; a developer starting Flask for the first time may find the combined scope of Flask and TDD together in one exercise difficult.

The official tutorial does not use TDD at all. Following both in sequence would let a developer compare which design decisions change when tests drive each feature from the start versus when tests are added after the fact.

TestDriven.io, which publishes the full version of this tutorial, also offers separate courses on microservices using Docker, Flask, and React, as noted in the README. Those courses extend well beyond what a single tutorial repository covers. Flaskr-TDD is the entry point into that ecosystem rather than a self-contained resource.

Update log ends October 2023 while a 2026 push to the repository goes undocumented

The tutorial's update log covers changes from November 2013 through October 17th, 2023. The October 2023 entry bumped all pinned dependencies to Python 3.12.0. The last push was on 2026-04-13, which post-dates that final log entry, and the README does not explain what changed in that push. A developer who notices behavior inconsistent with the written steps should check the commit history to identify what was modified.

This gap is worth noting for anyone following the tutorial step by step. A code change made after the last documented update can cause the written instructions to diverge from the actual repository files, and there is no automated check in the repository that verifies the written steps still match the code.

The project uses no formal versioning scheme; changes arrive as individual commits without a label. The MIT license applies, and the code is open for modification and redistribution.

Editorial conclusion

Flaskr-TDD suits a developer who wants to see TDD applied to a Flask project from the first route to deployment, rather than learning TDD in isolation. The content most relevant to writing tests, building routes with Flask-SQLAlchemy, and adding JavaScript is in the TestDriven.io article, not the README file, which ends after the first test. Before starting, verify that the full article is accessible at TestDriven.io and check whether the Python 3.12.0 dependencies still work with the current Python version on your machine.

Frequently asked questions

How does Flaskr-TDD differ from the official Flask tutorial?

Flaskr-TDD builds the same mini-blog application as the official Flask tutorial but applies TDD discipline throughout, adding pytest, Flask-SQLAlchemy, Black, Flake8, and Heroku deployment. The official tutorial does not use TDD at all.

Where is the full Flaskr-TDD tutorial content?

The README in the repository includes only the setup and first test sections. The complete tutorial covering SQLAlchemy, JavaScript, search, login, Postgres, linting, and deployment is published at TestDriven.io.

What Python version does the Flaskr-TDD tutorial require?

The tutorial targets Python 3.12.0 and pins Flask to version 3.0.0, pytest to 7.4.2, and Flask-SQLAlchemy to 3.1.1 in the requirements.txt file.

What deployment platform does Flaskr-TDD target?

The tutorial targets Heroku. The repository contains a Procfile for Heroku's process runner and uses psycopg2-binary and Gunicorn, which are standard for Heroku-hosted Python applications. The README does not document deployment steps for other platforms.

What test runner does the Flaskr-TDD tutorial use?

The tutorial uses pytest v7.4.2. The README notes that Python's standard library includes unittest, but the tutorial uses pytest throughout for test discovery and running.

Official sources

  1. Issues
  2. License: MIT
  3. mjhea0/flaskr-tdd on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mjhea0-flaskr-tdd.svg)](https://hysenlabs.com/projects/mjhea0-flaskr-tdd)