Gen-AI Developer Classroom notes 23/Mar/2025

Configuring Pytest for Projects in Python

Description

  • src/utils/ as the source package (without __init__.py)
  • tests/utils/ for tests
  • pytest for testing
  • pytest-cov for coverage
  • setup.py for editable install
  • .coveragerc for customizing coverage
  • pytest.ini for simplified test config

Project Structure

my-python-app/
├── src/
│   └── utils/
│       └── math_utils.py
├── tests/
│   └── utils/
│       └── test_math_utils.py
├── setup.py
├── pytest.ini
├── .coveragerc
├── requirements.txt
├── .gitignore
├── README.md

Step-by-Step Setup

1. Create Project Folder and Enter It

mkdir my-python-app
cd my-python-app

2. Create Folder Structure

mkdir -p src/utils
mkdir -p tests/utils

3. Create Source File

src/utils/math_utils.py

def add(a, b):
    return a + b

4. Create Test File

tests/utils/test_math_utils.py

from utils.math_utils import add

def test_add():
    assert add(2, 3) == 5

5. Create setup.py for Editable Install

setup.py

from setuptools import setup, find_packages

setup(
    name='my_python_app',
    version='0.1',
    packages=find_packages(where='src'),
    package_dir={'': 'src'},
)

6. Create .coveragerc to Customize Coverage Behavior

.coveragerc

[run]
source = src
branch = True

[report]
omit =
    tests/*
    */__init__.py

show_missing = True
skip_covered = True


directory = htmlcov

7. Create pytest.ini to Simplify Testing Commands

pytest.ini

[pytest]
minversion = 6.0
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = --strict-markers --disable-warnings --cov=src --cov-report=html

8. Create a Basic README

echo "# My Python App" > README.md

9. (Optional) Set Up a Virtual Environment

python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

10. Install Dependencies

pip install pytest pytest-cov
pip install -e .

11. Freeze Dependencies

pip freeze > requirements.txt

12. Run Tests with One Simple Command

pytest

Thanks to pytest.ini, this will:
– Discover all tests in tests/
– Measure coverage for utils/ in src/
– Apply .coveragerc rules
– Show uncovered lines in the terminal


13. (Optional) Generate HTML Coverage Report

pytest --cov-report=html

Then open htmlcov/index.html in your browser.


Basic Assertion Examples

  1. Equality Check:
    python
    def test_sum():
    assert sum([1, 2, 3]) == 6

  2. Membership Test:
    python
    def test_membership():
    assert 3 in [1, 2, 3]

  3. Instance Check:
    python
    def test_isinstance():
    assert isinstance([1, 2, 3], list)

  4. Reversed List:
    python
    def test_reversed():
    assert list(reversed([1, 2, 3])) == [3, 2, 1]

  5. Boolean Tests:
    “`python
    def test_all_true():
    assert all([True, True, True])

def test_any_true():
assert any([False, True, False])
“`

Using pytest-assert-utils for Advanced Assertions

The pytest-assert-utils library provides specialized utilities for assertions:

  1. Dictionary Subset Assertion:
    “`python
    from pytest_assert_utils import assert_dict_is_subset

def test_dict_subset():
expected = {‘a’: 12}
actual = {‘b’: 20, ‘a’: 12}
assert_dict_is_subset(expected, actual)
“`

  1. Model Attribute Assertion:
    “`python
    from pytest_assert_utils import assert_model_attrs
    from collections import namedtuple

Model = namedtuple(‘Model’, ‘id,key,other_key,parent’, defaults=(None,) * 4)

def test_model_attrs():
assert_model_attrs(Model(key=’value’), {‘key’: ‘value’})
“`

  1. List Containment:
    “`python
    from pytest_assert_utils import util

def test_list_containment():
assert util.List.containing(1) == [1, 2, 3]
assert util.List.containing_only(1, 2) == [1, 2, 2]
assert util.List.containing_exactly(5, 6, 4) == [4, 5, 6]
“`

  1. Set Assertions:
    “`python
    from pytest_assert_utils import util

def test_set_operations():
assert util.Set.containing(1) == {1, 2, 3}
assert util.Set.not_empty() == {1}
assert util.Set.empty() == set()
“`

  1. String Assertions:
    “`python
    from pytest_assert_utils import util

def test_string_operations():
assert util.Str.containing(‘app’) == ‘apple’
assert util.Str.empty() == ”
assert util.Str.not_empty() == ‘hamster’
“`

Standard pytest Assertions with Fixtures

Using fixtures to supply data to tests:

import pytest

@pytest.fixture
def supply_data():
    return [25, 35, 45]

def test_compare_with_value(supply_data):
    zz = 35
    assert zz in supply_data, "Value comparison failed"

Databases

  • Databases can be categorized largely into two types
    • Relational Databases
    • NOSQL Database
  • A Database offers a storage for data as well as query mechanism
  • Relational Databases have a strict schema (Structure) where as NOSQL have a softer or no schema at all

Relational Databases

  • Data is organized in a Database.
  • Database contains tables
  • Table contains records

Python with Databases

  • To deal with databases we have two ways of programming
    • Running sql commands from python code
    • ORM (Object Relational Mapping) Frameworks
  • To connect to database we need connection string.

Dealing with configuration values in python

  • What are environmental variables & why should i use them?
  • Reading configurations values in python:
    • json
    • yaml
    • python-dotenv

By continuous learner

enthusiastic technology learner

Leave a Reply

Discover more from Direct AI Powered By Quality Thought

Subscribe now to keep reading and get access to the full archive.

Continue reading