Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/WorkTeam01/team-practice/llms.txt

Use this file to discover all available pages before exploring further.

The test suite uses pytest and covers 63+ cases across core arithmetic, edge cases, error handling, and GUI behavior. GUI tests run headlessly via tkinter mocks defined in conftest.py, which replace real tkinter components with lightweight Python dummy classes — no display or Tcl/Tk runtime required.

Prerequisites

Install all test dependencies with a single command. The only runtime requirement for testing is pytest>=7.0.0, declared in requirements.txt:
pip install -r requirements.txt
requirements.txt contains:
# Dependencias para desarrollo y testing
pytest>=7.0.0

Running all tests

Run the full test suite from the project root:
pytest -v
The -v flag enables verbose output, printing each test name and its pass/fail status as it runs.

Running specific modules

Target a single test file to focus on one area of the codebase:
pytest tests/test_calculator.py -v

Filtering by test name

Use the -k flag to run only tests whose names match a keyword. This is especially useful when iterating on a specific feature, such as parenthesis handling:
pytest tests/test_gui.py -k "parenthesis" -v
This runs every test function in test_gui.py whose name contains the word parenthesis — for example, test_parenthesis_basic, test_parenthesis_nested, and test_parenthesis_with_power.

Coverage report

Coverage reporting requires pytest-cov, which is not included in requirements.txt. Install it separately before running the commands in this section:
pip install pytest-cov
Generate an HTML coverage report to see which lines of the source code are exercised by the test suite:
pytest --cov=src --cov-report=html -v
After the run completes, open htmlcov/index.html in your browser to browse line-by-line coverage for every file in the src/ package.

Test structure

The suite is organized across three files in the tests/ directory:
  • tests/test_calculator.py — Unit tests for the 8 core mathematical functions imported directly from src.calculator. These tests exercise pure logic with no GUI dependency. The test functions are:
    • test_add — basic addition with positive, negative, and zero inputs
    • test_subtract — basic subtraction including results that are negative
    • test_multiply — multiplication with zeros and sign combinations
    • test_divide — floating-point division with mixed signs
    • test_divide_by_zero — verifies that divide(10, 0) raises ZeroDivisionError
    • test_power — integer and fractional exponents, including a ValueError guard for negative bases with fractional powers
    • test_valor_maximovalor_maximo returns the larger of two numbers
    • test_valor_minimovalor_minimo returns the smaller of two numbers
    • test_abs_value — absolute value for negative, positive, and zero inputs
  • tests/test_gui.py — Integration-style tests for the CalculatorGUI class. They instantiate the full GUI object and call its public methods (number_button_click, operation_click, equals_click, scientific_click, open_parenthesis_click, etc.) to simulate user interactions and assert on calc.current_value.
  • tests/conftest.py — Shared pytest configuration. Defines dummy tkinter classes (DummyRoot, DummyEntry, DummyButton, DummyLabel) and an autouse=True fixture that patches them in before every test, so the GUI can be instantiated without a real display.

Understanding the tkinter mocks

conftest.py makes GUI tests portable by replacing the real tkinter widgets with minimal Python objects that implement just enough of the tkinter API for the CalculatorGUI constructor and methods to work. The four dummy classes are:
  • DummyRoot — mimics tk.Tk, implements title(), geometry(), configure(), grid_rowconfigure(), grid_columnconfigure(), mainloop(), bind(), after(), and destroy().
  • DummyEntry — mimics tk.Entry, tracks an internal _text string and exposes delete(), insert(), and get().
  • DummyButton — mimics tk.Button, accepts constructor arguments and a grid() call but does nothing.
  • DummyLabel — mimics tk.Label, stores a _text value and supports config(text=...) updates.
The replace_tkinter fixture is marked autouse=True, so pytest applies it to every test automatically — no explicit @pytest.mark.usefixtures decorator is needed:
@pytest.fixture(autouse=True)
def replace_tkinter():
    original_Tk = tk.Tk
    original_Entry = tk.Entry
    original_Button = tk.Button
    original_Label = tk.Label

    tk.Tk = DummyRoot
    tk.Entry = DummyEntry
    tk.Button = DummyButton
    tk.Label = DummyLabel

    try:
        yield
    finally:
        tk.Tk = original_Tk
        tk.Entry = original_Entry
        tk.Button = original_Button
        tk.Label = original_Label
The try / finally block guarantees that the original tkinter classes are always restored after each test, keeping tests fully isolated from one another.

Example tests

The following tests from test_calculator.py illustrate the testing style used throughout the suite. test_divide_by_zero verifies that the divide function raises the correct built-in exception rather than returning an incorrect value or silently swallowing the error:
def test_divide_by_zero():
    """Test que división por cero lanza excepción."""
    with pytest.raises(ZeroDivisionError):
        divide(10, 0)
test_power checks multiple scenarios in a single test function — integer exponents, a zero exponent, a fractional exponent (square root), negative bases, and the guarded case where a negative base with a fractional exponent must raise ValueError:
def test_power():
    """Test potencia básica."""
    assert power(2, 3) == 8
    assert power(5, 0) == 1
    assert power(4, 0.5) == 2.0
    assert power(-2, 3) == -8
    assert power(-2, 0) == 1
    assert power(-2, -3) == -0.125
    with pytest.raises(ValueError, match="Raíz negativa"):
        power(-4, 0.5)
Add the -x flag to any pytest command to stop the run immediately on the first failing test. This is useful when debugging a newly broken feature and you want to focus on one failure at a time: pytest -x -v.

Build docs developers (and LLMs) love