Initial commit: Complete TDD workshop materials
- Workshop documentation (WORKSHOP_PLAN, FACILITATOR_GUIDE, etc.) - FizzBuzz kata with demo script (git history to be recreated) - Password Validator kata with demo script and solution - Shopping Cart kata with demo script and solution - Setup guide and TDD reference card for participants
This commit is contained in:
commit
c3355063f2
26 changed files with 4725 additions and 0 deletions
161
FACILITATOR_GUIDE.md
Normal file
161
FACILITATOR_GUIDE.md
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# Workshop Facilitator Guide — Quick Reference
|
||||
|
||||
**Duration:** 2 hours
|
||||
**Format:** Live demo + hands-on practice with Password Validator or Shopping Cart katas
|
||||
|
||||
> **Note:** For the complete detailed plan with minute-by-minute timing, scripts, and checklists, see **WORKSHOP_PLAN.md**. This guide focuses on facilitation tips and kata-specific insights.
|
||||
|
||||
---
|
||||
|
||||
## Essential Documents
|
||||
|
||||
Before the workshop, familiarize yourself with:
|
||||
- **WORKSHOP_PLAN.md** — Complete schedule, scripts, and preparation checklist
|
||||
- **fizzbuzz/DEMO_SCRIPT.md** — Step-by-step live demo walkthrough
|
||||
- **TDD_REFERENCE_CARD.md** — Participant handout
|
||||
- **SETUP_GUIDE.md** — For helping participants with technical issues
|
||||
|
||||
---
|
||||
|
||||
## Quick Preparation Checklist
|
||||
|
||||
### 1 Week Before
|
||||
- [ ] Send SETUP_GUIDE.md to participants
|
||||
- [ ] Confirm everyone completes setup and verifies `dart test` works
|
||||
- [ ] Practice FizzBuzz live demo using DEMO_SCRIPT.md
|
||||
|
||||
### Day Of
|
||||
- [ ] Arrive 15 minutes early
|
||||
- [ ] Test projector/screen sharing
|
||||
- [ ] Open fizzbuzz kata with git log ready
|
||||
- [ ] Have solution files ready (but don't share early!)
|
||||
- [ ] Write schedule on whiteboard
|
||||
|
||||
---
|
||||
|
||||
## Updated Session Structure
|
||||
|
||||
| Time | Activity | See |
|
||||
|------|----------|-----|
|
||||
| 0:00-0:10 | Welcome & Setup Check | WORKSHOP_PLAN.md |
|
||||
| 0:10-0:25 | **Live Demo: FizzBuzz TDD** | fizzbuzz/DEMO_SCRIPT.md |
|
||||
| 0:25-0:30 | Exercise Introduction | Section below |
|
||||
| 0:30-1:15 | Hands-on Practice (Part 1) | Circulate & nudge |
|
||||
| 1:15-1:30 | Mid-Point Check-in | WORKSHOP_PLAN.md |
|
||||
| 1:30-2:00 | Hands-on Practice (Part 2) | Circulate & nudge |
|
||||
| 2:00-2:10 | Show & Tell | 2-3 volunteers |
|
||||
| 2:10-2:20 | Retrospective | WORKSHOP_PLAN.md |
|
||||
|
||||
---
|
||||
|
||||
## Live Demo: FizzBuzz (NEW SECTION)
|
||||
|
||||
**Purpose:** Show RED-GREEN-REFACTOR cycle in real-time
|
||||
|
||||
### Setup
|
||||
1. Open `fizzbuzz/` directory
|
||||
2. Have `fizzbuzz/DEMO_SCRIPT.md` open on second screen
|
||||
3. Terminal ready with `dart test`
|
||||
4. Reset git to initial commit: `git reset --hard <first-commit-hash>`
|
||||
|
||||
### Key Points to Emphasize
|
||||
- **Run tests frequently** (every 30 seconds)
|
||||
- **Minimal implementations** (hardcode "1" for first test)
|
||||
- **Test-driven design** (algorithm emerges from tests)
|
||||
- **Order matters** (check 15 before 3 and 5)
|
||||
|
||||
### Timing
|
||||
- 0-2 min: Introduce FizzBuzz rules
|
||||
- 2-4 min: Cycle 1 (input 1 → "1")
|
||||
- 4-6 min: Cycle 2 (input 2 → "2")
|
||||
- 6-9 min: Cycle 3 (input 3 → "Fizz")
|
||||
- 9-11 min: Cycle 4 (input 5 → "Buzz")
|
||||
- 11-14 min: Cycle 5 (input 15 → "FizzBuzz")
|
||||
- 14-15 min: Wrap up, show git log
|
||||
|
||||
**See fizzbuzz/DEMO_SCRIPT.md for complete talking points and what to code at each step.**
|
||||
|
||||
---
|
||||
|
||||
## What to watch for while circulating
|
||||
|
||||
**Good signs:**
|
||||
- Running `dart test` after every small change
|
||||
- Seeing RED before touching `lib/`
|
||||
- Short, focused commits (or at least talking through each step)
|
||||
|
||||
**Gentle interventions:**
|
||||
- *"Have you run the test yet? What did it say?"* — nudge anyone writing too much code before testing
|
||||
- *"Can you make it pass with even less code?"* — push toward minimal Green
|
||||
- *"Now that it's Green, what could you clean up?"* — prompt the Refactor step
|
||||
|
||||
---
|
||||
|
||||
## Feature A: Password Validator — facilitator notes
|
||||
|
||||
**Likely first implementation** (all rules as if-blocks):
|
||||
```dart
|
||||
ValidationResult validate(String password) {
|
||||
final errors = <String>[];
|
||||
if (password.length < 8) errors.add('Must be at least 8 characters long');
|
||||
if (!password.contains(RegExp(r'[A-Z]'))) errors.add('Must contain at least one uppercase letter');
|
||||
// ... etc
|
||||
return ValidationResult(isValid: errors.isEmpty, errors: errors);
|
||||
}
|
||||
```
|
||||
|
||||
**The refactor insight to guide toward (Step 6):**
|
||||
Each rule is just a function `String? Function(String)`. They can live in a list.
|
||||
Adding a new rule = adding one function. No touching existing code.
|
||||
This is the Open-Closed Principle — same insight as Gilded Rose's Strategy pattern.
|
||||
|
||||
**Talking point:** *"If you had 20 rules, how readable would 20 if-blocks be? What would you do?"*
|
||||
|
||||
---
|
||||
|
||||
## Feature B: Shopping Cart — facilitator notes
|
||||
|
||||
**Likely first implementation** (List-based):
|
||||
```dart
|
||||
final List<CartItem> _items = [];
|
||||
|
||||
double subtotal() => _items.fold(0, (s, i) => s + i.price * i.quantity);
|
||||
```
|
||||
|
||||
**The Map insight (Step 3 — remove by name):**
|
||||
When participants try to implement `removeItem(name)` with a List, they'll write a `.removeWhere()`.
|
||||
This works, but nudge them: *"What data structure makes 'find by name' really natural?"*
|
||||
Let the remove-by-name test drive them toward `Map<String, CartItem>`.
|
||||
|
||||
**CartItem validation (Step 5):**
|
||||
Many will put validation in `addItem()`. Ask: *"What if someone creates a CartItem and passes it somewhere else? Who validates it then?"*
|
||||
This conversation leads naturally to Value Objects.
|
||||
|
||||
**Bonus design question:**
|
||||
The duplicate name test has no right answer. Both "replace" and "accumulate" are valid.
|
||||
The point is: TDD forces you to decide, and the test documents the decision permanently.
|
||||
|
||||
---
|
||||
|
||||
## Closing discussion questions
|
||||
|
||||
1. *"What was the first test you wrote? Why that one?"*
|
||||
2. *"Did your design change as you added more tests? How?"*
|
||||
3. *"Did you ever feel tempted to skip the Red step and just write the code?"*
|
||||
4. *"What would have been different if you'd designed the class first, then written tests?"*
|
||||
|
||||
---
|
||||
|
||||
## Common questions and answers
|
||||
|
||||
**"Can I write all the tests first, then implement?"**
|
||||
Not quite — TDD is one test at a time. Write one, watch it fail, make it pass, then the next.
|
||||
Writing all tests upfront is a different practice (it's fine, but it's not TDD).
|
||||
|
||||
**"What if I don't know what test to write next?"**
|
||||
Ask: *"What's the simplest behavior this thing should have that it doesn't have yet?"*
|
||||
Start with the empty/zero case. Then one item. Then two. Then edge cases.
|
||||
|
||||
**"Is this realistic? Do people actually do this for real code?"**
|
||||
Yes — especially for domain logic (pricing, validation, calculations).
|
||||
It's less common for framework glue code, and that's okay. Apply it where behavior matters most.
|
||||
Loading…
Add table
Add a link
Reference in a new issue