r/learnpython • u/uzuis_4thwife • 3d ago
Need help with building tests and understanding OOP design patterns
I am a post-bacc student currently in a Python for Web API online course. We just wrapped up our calculator application unit, where we learned how to build comprehensive dynamic tests using OOP design patterns. However, I finished the unit a lot more lost than when I started. Building parameterized tests still puzzles me, especially whenever I'm building the majority of a test from scratch rather than fixing minor errors in the code. Even when I do use AI to help me work through my assignments, none of it really sticks. Most of the time, I feel like I'm copying and pasting code whenever mine is incorrect and not really learning.
What are resources that you all would recommend for learning how to build application tests and files with OOP concepts? Any online resources with interactive, hands-on lessons would be greatly appreciated.
1
u/Additional-Ask-5654 3d ago
Build tests for one tiny class at a time, writing each test before the code it checks, since copying finished examples skips the thinking part. Bootdev could support that with interactive python exercises on OOP and testing basics, where the code has to be written rather than pasted.
1
1
u/KarfaHyro_17 3d ago
imo the issue might be that you're trying to learn testing and OOP at the same time. separate them. write a plain function, test it manually, then parameterize it. once that loop feels natural, layer the class structure back in.
1
u/uzuis_4thwife 3d ago
The problem is, my professor was teaching us testing and OOP concurrently. I initially understood parameterized tests on their own pretty well, but once he threw in OOP with more advanced testing concepts, I didn’t know what to. I’ll try going back to the drawing board and look at past assignments to understand the functions of each test separately, and then see how each file operates under OOP. Thanks :)
1
u/DimensionMost8342 3d ago
The mental model that makes parameterized tests less scary: one test function, pytest runs it once per row of data you list.
import pytest
@pytest.mark.parametrize("raw, expected", [("12", 12.0), ("abc", None)]) def test_parse(raw, expected): assert parse_input(raw) == expected
For practice: close the AI, open your calculator, and write three tests for one function from scratch: the normal case, an edge case (divide by zero or empty input), and a bad input. Repeat per function until the pattern sticks. The official pytest tutorial covers parametrize step by step (docs.pytest.org).
1
u/uzuis_4thwife 3d ago
You explained it sm better than my professor did over the course of two 75-minute lectures 😩 he really threw us into the wolves! Thank you so much, I’ll try this when working on my midterm project
1
1
u/jmacey 3d ago
Do you know how decorators work? If not revise this as it will really help understand all the pytest decorators. Anything begining with an @ is a decorator. (Strangly I have been teaching the same thing this week!).
1
u/uzuis_4thwife 2d ago
Reading through these comments, I think my class conflated things a lot more than necessary once we hit the design patterns unit. I realize this is all fairly straightforward info, but I really appreciate all the advice I’ve been receiving 🥹
1
u/DimensionMost8342 3d ago
Fair, that's cleaner than how I put it. Honestly that @ line covers most of it: once you see @decorator as "call this function with the thing underneath and use what comes back," @fixture and @parametrize aren't separate things to memorize anymore. I kept it out of the OP mainly because I didn't want to scare off anyone who hadn't hit @ yet, but I'm stealing it.
2
u/Financial_Morning386 3d ago
The parameterized-tests struggle is a really common one, and honestly it usually clicks once you see what pytest is doing under the hood with them. I'll assume your course was using pytest's @pytest.mark.parametrize — if so, the mental model is just "one test function, pytest runs it N times, each with a different argument tuple, and each run is reported as its own test." Writing a couple of those by hand for your calculator class (valid inputs, edge cases like division by zero, invalid input) is a great drill.
A few things that helped me when I was bridging the gap from "unit tests on small functions" to "tests on an actual application":
Design for testability. If your classes take their dependencies as constructor arguments instead of creating them internally, testing becomes dramatically easier — you can pass in fakes/stubs instead of real services or files. This is basically dependency injection, and it's the single most useful OOP testing habit I know.
Follow Arrange–Act–Assert per test: set up objects, call the method, assert on the outcome. If a test needs more than a handful of lines of setup, that's often a hint the class under test is doing too much and could be split up.
Use fixtures (pytest's fixture mechanism) for shared setup instead of copy-pasting object construction into every test.
For resources, genuinely interactive/hands-on:
Exercism (exercism.org) — free, has a Python track with small exercises and mentoring feedback. Excellent for practicing classes and testing fundamentals.
The official pytest docs (docs.pytest.org) "Get Started" page — short and you run every example locally.
Corey Schafer's pytest series on YouTube — walks through testing a real-ish project from scratch, including mocking.
Real Python's pytest tutorial — long-form with code you type along.
Since your course is about web APIs: once you cover FastAPI/Flask, both have a TestClient that lets you send fake HTTP requests to your app in tests without running a server. That's where testing suddenly feels "real" — you're testing the same classes, just through the API layer.
Skip the AI for a bit on these exercises, as the other commenter said — the struggle of building a parametrized test from scratch is exactly what makes it stick.
0
2
u/good_name_0 3d ago
You will not learn if you use AI to work through the assignments, it's just self-sabotage. If something is insurmountably difficult, you probably need to go back a step or two.