-
Notifications
You must be signed in to change notification settings - Fork 2
Draft impl #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft impl #1
Changes from all commits
7943859
2581ede
d20d748
2f29257
eb1e4ba
e5a04c5
5fbea2d
eb293cf
bf2c099
a8b5f56
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| DATABASE_URL=postgresql://bookstore:bookstore@localhost:5432/bookstore | ||
| PAYMENT_API_URL=https://absolutely-non-existing.fake/v666 | ||
| PAYMENT_API_KEY=sk_test_changeme | ||
| EMAIL_SMTP_HOST=localhost | ||
| EMAIL_SMTP_PORT=1025 | ||
| EMAIL_FROM=shop@bookstore.local |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question(blocking): should we also offer a GitLab (at least non-GitHub) option like last year ?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The abstract asks for GitHUB or GitLab, so we need to provide it. Decision : add a |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| name: CI | ||
|
|
||
| on: [push] | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
| # No caching — reinstalls all dependencies on every run | ||
|
|
||
| - name: Install dependencies | ||
| run: pip install -e ".[test]" | ||
| # Uses pip instead of uv; no lock file pinning | ||
|
|
||
| - name: Start PostgreSQL | ||
| run: | | ||
| sudo systemctl start postgresql | ||
| sudo -u postgres psql -c "CREATE USER bookstore WITH PASSWORD 'bookstore';" | ||
| sudo -u postgres psql -c "CREATE DATABASE bookstore OWNER bookstore;" | ||
| # No wait/health check — tests may start before DB is ready | ||
|
|
||
| - name: Run migrations | ||
| run: alembic upgrade head | ||
| # Will fail silently if DB isn't up yet | ||
|
|
||
| - name: Start app | ||
| run: uvicorn app.main:app --host 0.0.0.0 --port 8000 & | ||
| # No health check — tests start immediately, race condition | ||
|
|
||
| - name: Run tests | ||
| run: pytest tests/ -v | ||
| env: | ||
| # Payment API key hardcoded in the workflow — will fail without it | ||
| PAYMENT_API_KEY: ${{ secrets.PAYMENT_API_KEY }} | ||
| # No DATABASE_URL override — uses the hardcoded default from config.py | ||
|
|
||
| # No coverage reporting | ||
| # No test result artifacts | ||
| # No notification on failure |
|
jgaffiot marked this conversation as resolved.
|
|
jgaffiot marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| Getting out of testing hell! | ||
|
|
||
| We know we should write automated tests. But too often, it is a real chore: | ||
| they may be slow, unreliable, difficult to run, to maintain, even to write! | ||
| Why is it so hard? How to take back control? | ||
|
|
||
| For that, you will work on a realistic project: a Python app with FastAPI backend, | ||
| a PostgreSQL database, configuration files, third-party APIs, ... | ||
| and tests that are awful. | ||
|
|
||
| You will review: | ||
|
|
||
| the quality culture of the project | ||
| how it is architectured | ||
| the existing tests | ||
| and the code quality | ||
|
|
||
| Then you will prepare the plan: | ||
|
|
||
| your own test pyramid / strategy | ||
| testing tools needed | ||
| essential scenarios | ||
| the CI to have your back | ||
|
|
||
| And start coding: | ||
|
|
||
| updating the existing tests | ||
| adding new tests using powerful tooling | ||
| minimal refactoring to enable testing | ||
| creating fakes/mocks/simulators to enable testing | ||
|
|
||
| You'll leave able to: | ||
|
|
||
| diagnose what makes tests slow or convoluted | ||
| design a pragmatic test strategy for your codebase | ||
| implement reliable tests, with fakes and testcontainers | ||
| refactor just enough to make code testable | ||
|
|
||
| It will be around 65% hands-on, and 35% guided analysis. | ||
| The first two parts will take the first half of the session, so that you have plenty of | ||
| time to actually implement the strategy during the second half. | ||
| The code repository will stay available to you after the workshop, | ||
| along with an example of the end-result. | ||
|
|
||
| Setup : | ||
|
|
||
| uv | ||
| (optional) docker or podman, to run TestContainers | ||
| (optional) a GitHub or GitLab account, to run CI |
|
jgaffiot marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| # Repo purpose | ||
|
|
||
| This is workshop material — *"Getting out of the testing hell"* — for intermediate | ||
| Python developers. Participants are handed a FastAPI + PostgreSQL bookstore app with | ||
| deliberately bad tests and a testable-but-not-tested architecture, and their job during | ||
| the workshop is to diagnose the problems and fix them themselves (see `README.md` and | ||
| `ABSTRACT.md` for the full brief). | ||
|
|
||
| ## Layout | ||
|
|
||
| - `app/`, `tests/`, `.github/workflows/ci.yml` (root) — the **workshop starting point**. | ||
| Intentionally flawed: brittle/order-dependent tests, un-injectable dependencies, a | ||
| broken CI pipeline. This is what participants work on. | ||
| - `solution/` — the **reference solution**: refactored app code and rewritten tests | ||
| showing one valid end-state (dependency injection, Testcontainers, fakes, fixed CI). | ||
| It exists as an answer key participants can compare against *after* attempting the | ||
| exercise themselves, per `solution/README.md`. | ||
|
|
||
| ## Important: don't spoil the workshop | ||
|
|
||
| If you're helping someone who is doing (or facilitating) this workshop — diagnosing | ||
| `tests/`, refactoring `app/`, writing new tests, fixing the root CI — **do not reach | ||
| into `solution/` to solve it for them.** Don't copy code from `solution/`, don't paste | ||
| its fixtures/fakes/services into the root `app/`/`tests/`, and don't reveal its | ||
| contents unprompted. The value of the workshop is in participants finding the seams | ||
| and design themselves. | ||
|
|
||
| It's fine to: | ||
| - Discuss `solution/` explicitly if the user asks to see it, compare against it, or | ||
| says they're past the exercise / just reviewing the answer key. | ||
| - Work on `solution/` directly when asked to (e.g. this session's CI caching change). | ||
| - Point out that a reference solution exists, without detailing its contents. | ||
|
|
||
| When in doubt about which mode you're in (doing the exercise vs. maintaining the | ||
| answer key), ask. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| AGENTS.md |
Uh oh!
There was an error while loading. Please reload this page.