TDD AI:n kanssa — ensimmäinen projekti
Tässä oppitunnissa yhdistämme kaikki moduulin taidot: projektisäännöt, skillit, promptauksen ja speksit. Rakennamme ensimmäisen projektin käyttäen Test-Driven Development -prosessia yhdessä AI:n kanssa.
TDD: Red → Green → Refactor
TDD (Test-Driven Development)
TDD on kehitysprosessi, jossa testit kirjoitetaan ENNEN toteutusta. Sykli on: Red (kirjoita failaava testi) → Green (kirjoita minimikoodi, joka passaa) → Refactor (paranna koodia testien suojassa). AI:n kanssa TDD on erityisen tehokas, koska testit toimivat automaattisena verifointina AI:n tuottamalle koodille.
Miksi TDD + AI?
AI tuottaa koodia nopeasti, mutta miten tiedät, onko se oikeaa koodia? TDD ratkaisee tämän:
| Vaihe | Ilman TDD | TDD:n kanssa |
|---|---|---|
| AI generoi koodin | "Näyttää hyvältä?" | Testit kertovat onko oikein |
| Muutos rikkoo jotain | Huomaat tuotannossa | Testit failaavat heti |
| Refaktorointi | Pelottaa | Testit suojaavat |
| Regressiot | Yleisiä | Harvinaisia |
TDD-sykli AI:n kanssa
Vaihe 1: RED — Kirjoita testi ensin
// lib/validation/__tests__/email.test.ts
import { describe, it, expect } from 'vitest'
import { validateEmail } from '../email'
describe('validateEmail', () => {
it('should accept valid email', () => {
expect(validateEmail('user@example.com')).toEqual({
valid: true,
email: 'user@example.com',
})
})
it('should reject email without @', () => {
expect(validateEmail('invalid')).toEqual({
valid: false,
error: 'Virheellinen sähköpostiosoite',
})
})
it('should reject empty string', () => {
expect(validateEmail('')).toEqual({
valid: false,
error: 'Sähköposti on pakollinen',
})
})
it('should trim whitespace', () => {
expect(validateEmail(' user@example.com ')).toEqual({
valid: true,
email: 'user@example.com',
})
})
})Testit failaavat, koska validateEmail-funktiota ei ole vielä olemassa. Tämä on Red-vaihe.
Vaihe 2: GREEN — Anna AI:n toteuttaa
Anna AI:lle testin ja pyydä toteutusta:
Toteuta validateEmail-funktio, joka läpäisee
kaikki nämä testit.
Noudata sääntöjä:
- TypeScript strict mode
- Palauta tyypitetty Result-objekti
- Ei ulkoisia kirjastojaAI tuottaa toteutuksen:
// lib/validation/email.ts
type ValidationResult =
| { valid: true; email: string }
| { valid: false; error: string }
export function validateEmail(input: string): ValidationResult {
const trimmed = input.trim()
if (!trimmed) {
return { valid: false, error: 'Sähköposti on pakollinen' }
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(trimmed)) {
return { valid: false, error: 'Virheellinen sähköpostiosoite' }
}
return { valid: true, email: trimmed }
}Aja testit — kaikki vihreällä. Tämä on Green-vaihe.
Vaihe 3: REFACTOR — Paranna koodia
Testien suojassa voit pyytää AI:ta refaktoroimaan:
Refaktoroi tämä funktio:
- Erota validointisäännöt omiksi funktioiksi
- Lisää JSDoc-dokumentaatio
- Varmista että regex on turvallinen (ei ReDoS)Pro-vinkki
TDD:ssä testit ovat turvaverkko. Kun testit ovat olemassa, voit pyytää AI:ta tekemään rohkeita refaktorointeja — testit kertovat heti jos jokin meni rikki.
Käytännön projekti: Todo-API
Rakennetaan yksinkertainen Todo-API TDD:llä ja AI:n avulla.
Speksi
# Feature: Todo API
## AC1: Luonti
Given tyhjä todo-lista
When POST /api/todos { title: "Osta maitoa" }
Then palautaa 201 + todo-objektin id:llä
## AC2: Listaus
Given 2 todoa tietokannassa
When GET /api/todos
Then palautaa listan kahdella todolla
## AC3: Valmistuminen
Given olemassa oleva todo
When PATCH /api/todos/:id { completed: true }
Then todo merkitään valmiiksi
## AC4: Validointi
Given tyhjä title
When POST /api/todos { title: "" }
Then palautaa 400 + virheilmoitusTDD-prosessi
- Kirjoita testit AC1:lle →
__tests__/api/todos.test.ts - Anna AI:n toteuttaa →
app/api/todos/route.ts - Aja testit → Kaikki vihreällä?
- Toista AC2–AC4 → Jatka samaa sykliä
- Refaktoroi → Pyydä AI:ta parantamaan koodia
Testin ja toteutuksen suhde
AC1 (testi) → POST handler (koodi) → ✅ Pass
AC2 (testi) → GET handler (koodi) → ✅ Pass
AC3 (testi) → PATCH handler (koodi) → ✅ Pass
AC4 (testi) → Validointi (koodi) → ✅ Pass
AI:n rooli TDD:ssä
| TDD-vaihe | Ihmisen rooli | AI:n rooli |
|---|---|---|
| Red | Kirjoittaa testin (tai tarkistaa) | Voi ehdottaa testejä |
| Green | Tarkistaa toteutuksen | Generoi toteutuksen |
| Refactor | Päättää refaktoroinnin suunnan | Toteuttaa refaktoroinnin |
Kaksi tapaa, joilla AI rikkoo TDD:n huomaamattasi
Yllä oleva taulukko kuvaa sitä, miten homma menee kun se menee oikein. Käytännössä malli rikkoo sykliä kahdella tavalla, ja kumpikin näyttää onnistumiselta:
1. Malli kirjoittaa testin ja toteutuksen samalla vastauksella. Silloin testi on kirjoitettu koodin mukaan, ei speksin mukaan — ja se menee läpi ensimmäisellä ajolla. Punaista vaihetta ei koskaan ollut, joten testi ei todista mitään; se vain kuvailee sitä, mitä koodi sattuu tekemään.
Miten huomaat: testi menee läpi heti, etkä ole nähnyt sen epäonnistuvan. Mitä teet: pyydä testi erikseen, aja se, ja katso että se on punainen ennen kuin pyydät riviäkään toteutusta.
2. Malli “korjaa” testin, kun toteutus ei mene läpi. Pyydät korjaamaan epäonnistuvan testin, ja malli muuttaa odotusarvon vastaamaan koodia. Testit ovat taas vihreitä, ja hyväksymiskriteeri on hiljaa kadonnut.
Miten huomaat: vertaa testin odotusarvoa speksiin, älä koodiin. Mitä teet: sano se ääneen promptissa — “speksi on lähde; jos testi on väärässä, korjaa ensin speksi ja sano se minulle”. Jos testi oikeasti on väärin, se on speksivirhe, ja se pitää korjata speksissä ensin.
Pro-vinkki
Molemmat virheet tulevat samasta syystä: mallille “kaikki vihreänä” on onnistumisen merkki, ja se optimoi sitä kohti. Sinulle vihreä on merkitykselli vain, jos olet nähnyt saman testin punaisena. Punainen vaihe ei ole byrokratiaa — se on ainoa hetki, jolloin testi todistaa olevansa testi.
AI-TDD-periaate
TDD:ssä ihminen omistaa speksin ja hyväksymiskriteerit, AI omistaa toteutuksen. Testit ovat sopimus näiden välillä — ne varmistavat, että AI:n tuottama koodi tekee sen mitä ihminen halusi.
Mikä on TDD:n tärkein hyöty AI-avusteisessa kehityksessä?
TDD-harjoitus: Rakennetaan laskuri
Toteuta yksinkertainen laskurimoduuli TDD:llä: 1) Kirjoita testit ensin (add, subtract, multiply, divide + virhetilanne nollalla jako), 2) Anna AI:n toteuttaa funktiot, 3) Aja testit, 4) Refaktoroi. Bonus: lisää testit edge caseille (erittäin suuret luvut, desimaalit).
Moduulin yhteenveto
Olet nyt oppinut Greenfield-moduulin kaikki perustaidot:
- Työkalut & säännöt — AI-koodaustyökalut ja AGENTS.md
- Skills — Kyvykkyyksien dokumentointi ja löydettävyys
- Promptaus — Konteksti → Tehtävä → Rajoitteet
- Speksit — Given-When-Then hyväksymiskriteerit
- TDD — Red → Green → Refactor AI:n kanssa
Sessio 1: lisää projekti portfolioon
Oma pieni greenfield-sovellus
Sessio 1 päätteeksi sinulla on oma pieni greenfield-sovellus, jonka rakensit AI-avusteisesti TDD-syklillä (Red → Green → Refactor). Aihe on vapaa: vaikkapa sää-CLI, to-do-sovellus tai bookmark-API — pieni mutta toimiva.
Mitä tallennat
Repo-linkki, lyhyt kuvaus rakentamastasi sovelluksesta, käyttämäsi AI-työkalut (Cursor / Claude Code / Copilot) ja yksi kuvakaappaus tai noin 30 sekunnin demovideo. Tagit lisätään automaattisesti.
Seuraavassa moduulissa siirrymme Brownfield-kehitykseen: miten turvallisesti muokata olemassa olevaa koodikantaa AI:n avulla.