Testing
test สี่แบบ หนึ่ง pyramid
หัวข้อที่มีชื่อว่า “test สี่แบบ หนึ่ง pyramid”Flutter ให้เครื่องมือ test สี่แบบ ซึ่งแลกความเร็วกับความสมจริง ใช้แบบเร็วเยอะ ๆ และแบบช้าน้อย ๆ
flowchart TB integ["Integration tests (whole app, real device) — few, slow"] --> widget["Widget tests (one widget tree, no device) — many, fast"] widget --> unit["Unit tests (pure Dart logic) — most, fastest"]
- Unit test ตรวจ Dart ล้วน ๆ — function, class, logic ของ Cubit ไม่มี UI ไม่มี device เร็วระดับ millisecond
- Widget test pump widget เข้า test harness แล้วโต้ตอบกับ widget นั้น (tap, พิมพ์, expect) — ไม่ต้องมี device จริง ยังเร็วอยู่ นี่คือจุด sweet spot เฉพาะของ Flutter
- Integration test รันทั้งแอปบน device หรือ emulator จริง ขับแอปแบบ end to end — ช้า แต่สมจริงที่สุด
- Golden test เก็บ pixel ที่ render ของ widget แล้วเทียบกับ reference image ที่ save ไว้ จับ visual regression
unit test
หัวข้อที่มีชื่อว่า “unit test”import 'package:test/test.dart';
test('cart total sums item prices', () { final cart = Cart()..add(Item(price: 10))..add(Item(price: 5)); expect(cart.total, 15);});Dart ล้วน ๆ, expect ล้วน ๆ logic ส่วนใหญ่ของคุณ — pricing, validation, parsing, state transition — ควรเข้าถึงได้ด้วย test ที่ง่ายแบบนี้ นั่นคือเหตุผลที่ดีในการเก็บ logic ออกจาก widget
widget test
หัวข้อที่มีชื่อว่า “widget test”widget test ใช้ WidgetTester เพื่อ build widget, find element, act และ assert — ทั้งหมดอยู่ใน memory
import 'package:flutter/material.dart';import 'package:flutter_test/flutter_test.dart';
testWidgets('tapping + increments the counter', (WidgetTester tester) async { await tester.pumpWidget(const MyApp()); // build the widget tree
expect(find.text('0'), findsOneWidget); // initial state
await tester.tap(find.byIcon(Icons.add)); // interact await tester.pump(); // rebuild after setState
expect(find.text('1'), findsOneWidget); // assert the new state});call สำคัญ: pumpWidget build tree, find หา widget, tap/enterText โต้ตอบ และ pump (หรือ pumpAndSettle สำหรับ animation) เดินหน้า frame เพื่อให้ rebuild เกิดขึ้น ไม่ต้องมี emulator — อันนี้รันในไม่กี่วินาที
golden test
หัวข้อที่มีชื่อว่า “golden test”testWidgets('button matches golden', (tester) async { await tester.pumpWidget(const MyButton()); await expectLater( find.byType(MyButton), matchesGoldenFile('goldens/my_button.png'), );});golden (snapshot) test ทรงพลังสำหรับ design system แต่เปราะข้าม platform และ font version — pin ให้ดีและ regenerate อย่างตั้งใจด้วย --update-goldens