1. Napisz testy najpierw
AI generuje kompleksowe przypadki testowe z wymagań
Testowanie to miejsce gdzie pomoc AI naprawdę błyszczy. Zamiast ręcznego pisania powtarzalnych przypadków testowych lub zmagania się z celami pokrycia, AI Cursor może generować kompleksowe pakiety testów, debugować awarie, a nawet wykonywać testy end-to-end poprzez automatyzację przeglądarki.
Tradycyjny cykl TDD (Czerwony → Zielony → Refaktor) zostaje naładowany pomocą AI. Oto ulepszony przepływ pracy:
1. Napisz testy najpierw
AI generuje kompleksowe przypadki testowe z wymagań
2. Uruchom testy (czerwony)
Testy początkowo zawodzą - to waliduje że testują prawdziwe zachowanie
3. Implementuj kod (zielony)
AI pisze kod aby testy przeszły, iterując automatycznie
4. Refaktoryzuj (niebieski)
AI optymalizuje kod zapewniając że testy nadal przechodzą
Włącz tryb YOLO aby odblokować automatyczne wykonywanie testów:
Ustawienia → Ogólne → Tryb YOLO → Włącz
Zalecany prompt:wszelkiego rodzaju testy są zawsze dozwolone jak vitest, npm test,nr test, itp. także podstawowe komendy build jak build, tsc, itp.tworzenie plików i katalogów (jak touch, mkdir, itp)też jest zawsze ok
Z trybem YOLO Agent może:
Zaimplementujmy złożoną funkcję używając TDD wspomaganego przez AI:
Agent: Utwórz funkcję która konwertuje markdown na HTML.Napisz testy najpierw, potem kod, następnie uruchom testyi aktualizuj kod aż testy przejdą.
Obserwuj jak Agent:
Tworzy kompleksowy plik testowy
describe('markdownToHtml', () => { it('powinien konwertować nagłówki', () => { expect(markdownToHtml('# Tytuł')).toBe('<h1>Tytuł</h1>'); expect(markdownToHtml('## Podtytuł')).toBe('<h2>Podtytuł</h2>'); });
it('powinien konwertować pogrubiony tekst', () => { expect(markdownToHtml('**pogrubiony**')).toBe('<strong>pogrubiony</strong>'); });
it('powinien obsługiwać bloki kodu', () => { expect(markdownToHtml('`kod`')).toBe('<code>kod</code>'); });
// AI generuje wiele więcej przypadków brzegowych...});
Implementuje funkcję
function markdownToHtml(markdown) { // Początkowa implementacja}
Uruchamia testy i widzi awarie
✗ 6 testów zawiodło
Iteracyjnie naprawia kod
Aktualizuję implementację aby obsłużyć nagłówki...Uruchamiam testy ponownie...✗ 3 testy zawiodły
Dodaję wsparcie dla pogrubionego tekstu...Uruchamiam testy ponownie...✓ Wszystkie testy przeszły!
Agent: Utwórz testy jednostkowe dla tego komponentu UserProfile.Testuj wszystkie propsy, interakcje użytkownika i przypadki brzegowe.Używaj React Testing Library.
Agent generuje:
describe('UserProfile', () => { it('renderuje nazwę użytkownika i awatar', () => { const user = { name: 'Jan', avatar: 'url' }; render(<UserProfile user={user} />); expect(screen.getByText('Jan')).toBeInTheDocument(); expect(screen.getByRole('img')).toHaveAttribute('src', 'url'); });
it('obsługuje brakujący awatar z gracją', () => { // Testowanie przypadków brzegowych });
it('wywołuje onEdit gdy przycisk edycji zostanie kliknięty', () => { // Testowanie interakcji });});
Agent: Napisz kompleksowe testy dla tego endpointu API.Dołącz przypadki sukcesu, obsługę błędów i przypadki brzegowe.
Agent tworzy:
describe('POST /api/users', () => { it('tworzy użytkownika z prawidłowymi danymi', async () => { const response = await request(app) .post('/api/users') .send({ name: 'Test', email: 'test@example.com' });
expect(response.status).toBe(201); expect(response.body).toHaveProperty('id'); });
it('waliduje format email', async () => { const response = await request(app) .post('/api/users') .send({ name: 'Test', email: 'nieprawidłowy' });
expect(response.status).toBe(400); expect(response.body.error).toContain('email'); });
// Więcej przypadków testowych...});
Agent: Utwórz testy dla tej funkcji pobierania danych asynchronicznych.Dołącz stany ładowania, sukces, błędy i retry.
AI obsługuje złożone scenariusze async:
describe('fetchUserData', () => { it('zwraca dane użytkownika przy sukcesie', async () => { const mockUser = { id: 1, name: 'Test' }; fetch.mockResolvedValueOnce({ ok: true, json: async () => mockUser });
const result = await fetchUserData(1); expect(result).toEqual(mockUser); });
it('powtarza przy awarii sieci', async () => { fetch.mockRejectedValueOnce(new Error('Błąd sieci')); fetch.mockResolvedValueOnce({ ok: true, json: async () => ({ id: 1 }) });
const result = await fetchUserData(1); expect(fetch).toHaveBeenCalledTimes(2); expect(result).toBeDefined(); });});
Wykorzystaj Puppeteer/Playwright MCP do kompleksowego testowania E2E:
Agent: Skonfiguruj testy E2E dla naszego przepływu logowania używając Puppeteer.Testuj pomyślne logowanie, nieprawidłowe poświadczenia i zapomniałem hasła.
Agent tworzy kompleksowe testy E2E:
describe('Przepływ logowania E2E', () => { it('pomyślne logowanie przekierowuje do dashboardu', async () => { // Agent używa Puppeteer MCP await page.goto('http://localhost:3000/login'); await page.type('#email', 'user@example.com'); await page.type('#password', 'correct-password'); await page.click('button[type="submit"]');
await page.waitForNavigation(); expect(page.url()).toContain('/dashboard');
// Rób zrzut ekranu dla weryfikacji wizualnej await page.screenshot({ path: 'login-success.png' }); });
it('pokazuje błąd dla nieprawidłowych poświadczeń', async () => { await page.goto('http://localhost:3000/login'); await page.type('#email', 'user@example.com'); await page.type('#password', 'wrong-password'); await page.click('button[type="submit"]');
const error = await page.waitForSelector('.error-message'); const text = await error.evaluate(el => el.textContent); expect(text).toContain('Nieprawidłowe poświadczenia'); });});
Agent: Dodaj testy regresji wizualnej dla naszych kluczowych stron.Porównuj zrzuty ekranu i oznaczaj wszelkie zmiany wizualne.
Gdy testy zawodzą, AI staje się twoim partnerem debugowania:
1. Analizuj awarię
Agent: Ten test zawodzi. Dodaj console.logsaby zrozumieć co się dzieje.
2. Uruchom z logami
Agent uruchamia test z dodanym logowaniem,przechwytuje output do analizy
3. Zidentyfikuj problem
Na podstawie logów: "Problem to format datynie pasuje do oczekiwanego wzorca"
4. Napraw i zweryfikuj
Agent naprawia kod i ponownie uruchamia testyaby potwierdzić rozwiązanie
Użytkownik: Test uwierzytelniania użytkownika zawodzi sporadycznie
Agent: Debuguję tę sporadyczną awarię. Dodam logowaniei informacje o czasie aby zrozumieć problem.
[Dodaje strategiczne console.logs i marki wydajności][Uruchamia test wiele razy]
Znalazłem! Test zawodzi gdy pula połączeń bazy danychjest wyczerpana. Poprzedni test nie czyści połączeń.Naprawię to dodając odpowiednie czyszczenie...
[Dodaje hook afterEach czyszczenia][Uruchamia test 10 razy - wszystkie przechodzą]
Sporadyczna awaria jest teraz rozwiązana.
Agent: Przeanalizuj nasze pokrycie testów i napisz testyaby osiągnąć 90% pokrycia dla modułu auth.
Agent wykona:
Plik | % Stmts | % Branch | % Funcs | % Lines |-------------------|---------|----------|---------|---------|auth/login.js | 75.00 | 66.67 | 100.00 | 75.00 |auth/register.js | 90.00 | 85.00 | 100.00 | 88.89 |auth/reset.js | 45.00 | 33.33 | 66.67 | 45.00 |
Agent: Skupię się na auth/reset.js który ma niskie pokrycie.Tworzę testy dla przypadków brzegowych resetowania hasła...
Agent: Mockuj wszystkie wywołania zewnętrznych API w naszych testach płatności.Dołącz scenariusze sukcesu i awarii.
// AI generuje kompleksowe mockijest.mock('@/services/stripe', () => ({ createPaymentIntent: jest.fn(), confirmPayment: jest.fn(), handleWebhook: jest.fn()}));
describe('Przetwarzanie płatności', () => { beforeEach(() => { // Resetuj mocki między testami jest.clearAllMocks(); });
it('obsługuje błędy API Stripe z gracją', async () => { const stripeError = new Error('Karta odrzucona'); stripeError.code = 'card_declined';
createPaymentIntent.mockRejectedValueOnce(stripeError);
// Testuj obsługę błędów... });});
Agent: Utwórz testy sterowane danymi dla naszej logiki walidacji.Testuj z różnymi kombinacjami input.
describe('Walidacja input', () => { const testCases = [ { input: 'valid@email.com', expected: true, description: 'prawidłowy email' }, { input: 'invalid.email', expected: false, description: 'brakujący @' }, { input: '@example.com', expected: false, description: 'brakująca część lokalna' }, { input: 'test@', expected: false, description: 'brakująca domena' }, // AI generuje wiele więcej przypadków... ];
testCases.forEach(({ input, expected, description }) => { it(`waliduje ${description}`, () => { expect(isValidEmail(input)).toBe(expected); }); });});
Agent: Utwórz testy wydajności dla naszych endpointów API.Zmierz czasy odpowiedzi i zidentyfikuj wąskie gardła.
describe('Wydajność API', () => { it('odpowiada w ciągu 200ms dla listy użytkowników', async () => { const start = performance.now(); const response = await request(app).get('/api/users'); const duration = performance.now() - start;
expect(response.status).toBe(200); expect(duration).toBeLessThan(200); });
it('obsługuje 100 jednoczesnych żądań', async () => { const requests = Array(100).fill(null).map(() => request(app).get('/api/users') );
const responses = await Promise.all(requests); const successCount = responses.filter(r => r.status === 200).length;
expect(successCount).toBeGreaterThan(95); // 95% wskaźnik sukcesu });});
Agent: Skonfiguruj bramy jakości które zapobiegają mergowaniu jeśli:- Pokrycie testów spadnie poniżej 80%- Jakiekolwiek testy zawodzą- Benchmarki wydajności nie są spełnione
Testuj zachowanie, nie implementację
Skup się na tym co kod robi, nie jak to robi
Utrzymuj niezależność testów
Każdy test powinien działać w izolacji bez zależności
Używaj opisowych nazw
Nazwy testów powinny jasno opisywać co weryfikują
Trzymaj testy proste
Jedna asercja na test gdy możliwe
Problem: Testy przechodzą czasem, czasem zawodzą
Rozwiązanie:Agent: Debuguj ten chwiejny test uruchamiając go 20 razyi identyfikując co się różni między uruchomieniami.
Problem: Pakiet testów trwa za długo
Rozwiązanie:Agent: Profiluj nasz pakiet testów i zidentyfikujnajwolniejsze testy. Zasugeruj optymalizacje.
Problem: Testy przechodzą ale funkcja jest zepsuta
Rozwiązanie:Agent: Przejrzyj te testy i zidentyfikuj dlaczego niewykrywają faktycznego błędu. Wzmocnij asercje.
Twoja gra testowania jest teraz transformowana pomocą AI: