1. Giriş
Flutter, Google'ın tek bir kod tabanından mobil, web ve masaüstü için yerel olarak derlenmiş, güzel uygulamalar geliştirmeye yönelik kullanıcı arayüzü araç setidir.
Bu codelab'de basit bir Flutter uygulaması derleyip test edeceksiniz. Uygulama, durumu yönetmek için Provider paketini kullanır.
Neler öğreneceksiniz?
- Widget test çerçevesini kullanarak widget testleri oluşturma
integration_test
kitaplığını kullanarak uygulamanın kullanıcı arayüzünü ve performansını test etmek için entegrasyon testi oluşturma- Birim testleri yardımıyla veri sınıflarını (sağlayıcılar) test etme
Neler oluşturacaksınız?
Bu codelab'de öğe listesiyle basit bir uygulama oluşturarak başlayacaksınız. Teste hemen başlayabilmeniz için kaynak kodunu sizin yerinize sağlarız. Uygulama aşağıdaki işlemleri destekler:
- Öğeler favorilere ekleniyor
- Favoriler listesini görüntüleme
- Öğeler favoriler listesinden kaldırılıyor
Uygulama tamamlandıktan sonra aşağıdaki testleri yazacaksınız:
| Android'de çalışan uygulamanın GIF'i |
Bu codelab'den ne öğrenmek istersiniz?
2. Flutter geliştirme ortamınızı kurma
Bu laboratuvarı tamamlamak için iki yazılıma ihtiyacınız vardır: Flutter SDK'sı ve düzenleyici.
Codelab'i aşağıdaki cihazlardan birini kullanarak çalıştırabilirsiniz:
- Bilgisayarınıza bağlı ve Geliştirici moduna ayarlanmış fiziksel bir Android veya iOS cihaz.
- iOS simülatörü (Xcode araçlarının yüklenmesini gerektirir).
- Android Emülatör (Android Studio'da kurulum gerektirir).
- Tarayıcı (hata ayıklama için Chrome gereklidir).
- Windows, Linux veya macOS masaüstü uygulaması olarak Uygulamayı dağıtmayı planladığınız platformda gerçekleştirmeniz gerekir. Bu nedenle, bir Windows masaüstü uygulaması geliştirmek istiyorsanız uygun derleme zincirine erişmek için Windows'da geliştirme yapmanız gerekir. İşletim sistemine özgü gereksinimler docs.flutter.dev/desktop sayfasında ayrıntılı olarak açıklanmıştır.
3. Başlarken
Yeni bir Flutter uygulaması oluşturun ve bağımlılıkları güncelle
Bu codelab'de, Flutter mobil uygulamasını test etme konusu ele alınmaktadır. Kopyaladığınız ve yapıştırdığınız kaynak dosyaları kullanarak test edilecek uygulamayı hızlı bir şekilde oluşturacaksınız. Codelab'in geri kalanında farklı test türlerini öğrenmeye odaklanırsınız.
İlk Flutter uygulamanızı kullanmaya başlama bölümündeki talimatları veya aşağıdaki komut satırını kullanarak basit bir şablonlu Flutter uygulaması oluşturun.
$ flutter create --empty testing_app Creating project testing_app... Resolving dependencies in `testing_app`... Downloading packages... Got dependencies in `testing_app`. Wrote 128 files. All done! You can find general documentation for Flutter at: https://docs.flutter.dev/ Detailed API documentation is available at: https://api.flutter.dev/ If you prefer video documentation, consider: https://www.youtube.com/c/flutterdev In order to run your empty application, type: $ cd testing_app $ flutter run Your empty application code is in testing_app/lib/main.dart.
Komut satırına yayıncı bağımlılıklarını ekleyin.
- Kolay durum yönetimi için
provider
, - Cihazlar ve emülatörlerde Flutter kodunu kendi kendine test eden
integration_test
flutter_driver
: Gerçek cihazlarda ve emülatörlerde çalışan Flutter uygulamalarını test etmek için geliştirilmiş bir gelişmiş API,- Genel test araçları için
test
, - Uygulamada gezinmeyi yönetmek için
go_router
.
$ cd testing_app $ flutter pub add provider go_router dev:test 'dev:flutter_driver:{"sdk":"flutter"}' 'dev:integration_test:{"sdk":"flutter"}' Resolving dependencies... Downloading packages... + _fe_analyzer_shared 67.0.0 (68.0.0 available) + analyzer 6.4.1 (6.5.0 available) + args 2.5.0 + convert 3.1.1 + coverage 1.7.2 + crypto 3.0.3 + file 7.0.0 + flutter_driver 0.0.0 from sdk flutter + flutter_web_plugins 0.0.0 from sdk flutter + frontend_server_client 4.0.0 + fuchsia_remote_debug_protocol 0.0.0 from sdk flutter + glob 2.1.2 + go_router 14.0.2 + http_multi_server 3.2.1 + http_parser 4.0.2 + integration_test 0.0.0 from sdk flutter + io 1.0.4 + js 0.7.1 leak_tracker 10.0.4 (10.0.5 available) leak_tracker_flutter_testing 3.0.3 (3.0.5 available) + logging 1.2.0 material_color_utilities 0.8.0 (0.11.1 available) meta 1.12.0 (1.14.0 available) + mime 1.0.5 + nested 1.0.0 + node_preamble 2.0.2 + package_config 2.1.0 + platform 3.1.4 + pool 1.5.1 + process 5.0.2 + provider 6.1.2 + pub_semver 2.1.4 + shelf 1.4.1 + shelf_packages_handler 3.0.2 + shelf_static 1.1.2 + shelf_web_socket 1.0.4 + source_map_stack_trace 2.1.1 + source_maps 0.10.12 + sync_http 0.3.1 + test 1.25.2 (1.25.4 available) test_api 0.7.0 (0.7.1 available) + test_core 0.6.0 (0.6.2 available) + typed_data 1.3.2 + watcher 1.1.0 + web 0.5.1 + web_socket_channel 2.4.5 + webdriver 3.0.3 + webkit_inspection_protocol 1.2.1 + yaml 3.1.2 Changed 44 dependencies! 9 packages have newer versions incompatible with dependency constraints. Try `flutter pub outdated` for more information.
Aşağıdaki bağımlılıklar pubspec.yaml dosyanıza eklenmiş olmalıdır:
pubspec.yaml
name: testing_app description: "A new Flutter project." publish_to: 'none' version: 0.1.0 environment: sdk: '>=3.4.0-0 <4.0.0' dependencies: flutter: sdk: flutter go_router: ^14.0.2 provider: ^6.1.2 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^3.0.0 test: ^1.25.2 flutter_driver: sdk: flutter integration_test: sdk: flutter flutter: uses-material-design: true
Projeyi istediğiniz kod düzenleyicide açın ve uygulamayı çalıştırın. Alternatif olarak, aşağıdaki gibi komut satırında çalıştırabilirsiniz.
$ flutter run
4. Uygulamayı oluşturma
Ardından, test edebilmeniz için uygulamayı geliştirirsiniz. Uygulama aşağıdaki dosyaları içerir:
lib/models/favorites.dart
- favoriler listesi için model sınıfını oluştururlib/screens/favorites.dart
- sık kullanılanlar listesi düzenini oluştururlib/screens/home.dart
- öğe listesi oluştururlib/main.dart
- uygulamanın başlatılacağı ana dosya
İlk olarak lib/models/favorites.dart
ürününde Favorites
modelini oluşturun
lib
dizininde models
adlı yeni bir dizin, ardından favorites.dart
adlı yeni bir dosya oluşturun. Bu dosyaya aşağıdaki kodu ekleyin:
lib/models/favorites.dart
import 'package:flutter/material.dart';
/// The [Favorites] class holds a list of favorite items saved by the user.
class Favorites extends ChangeNotifier {
final List<int> _favoriteItems = [];
List<int> get items => _favoriteItems;
void add(int itemNo) {
_favoriteItems.add(itemNo);
notifyListeners();
}
void remove(int itemNo) {
_favoriteItems.remove(itemNo);
notifyListeners();
}
}
Favoriler sayfasını lib/screens/favorites.dart
listesine ekleyin
lib
dizininde screens
adlı yeni bir dizin ve bu dizinde favorites.dart
adlı yeni bir dosya oluşturun. Bu dosyaya aşağıdaki kodu ekleyin:
lib/screens/favorites.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/favorites.dart';
class FavoritesPage extends StatelessWidget {
const FavoritesPage({super.key});
static String routeName = 'favorites_page';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Favorites'),
),
body: Consumer<Favorites>(
builder: (context, value, child) => ListView.builder(
itemCount: value.items.length,
padding: const EdgeInsets.symmetric(vertical: 16),
itemBuilder: (context, index) => FavoriteItemTile(value.items[index]),
),
),
);
}
}
class FavoriteItemTile extends StatelessWidget {
const FavoriteItemTile(this.itemNo, {super.key});
final int itemNo;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.primaries[itemNo % Colors.primaries.length],
),
title: Text(
'Item $itemNo',
key: Key('favorites_text_$itemNo'),
),
trailing: IconButton(
key: Key('remove_icon_$itemNo'),
icon: const Icon(Icons.close),
onPressed: () {
Provider.of<Favorites>(context, listen: false).remove(itemNo);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Removed from favorites.'),
duration: Duration(seconds: 1),
),
);
},
),
),
);
}
}
lib/screens/home.dart
uygulamasında ana sayfayı ekleyin
lib/screens
dizininde home.dart
adlı başka bir yeni dosya oluşturun. lib/screens/home.dart
alanına aşağıdaki kodu ekleyin:
lib/screens/home.dart
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import '../models/favorites.dart';
import 'favorites.dart';
class HomePage extends StatelessWidget {
static String routeName = '/';
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Testing Sample'),
actions: <Widget>[
TextButton.icon(
onPressed: () {
context.go('/${FavoritesPage.routeName}');
},
icon: const Icon(Icons.favorite_border),
label: const Text('Favorites'),
),
],
),
body: ListView.builder(
itemCount: 100,
cacheExtent: 20.0,
padding: const EdgeInsets.symmetric(vertical: 16),
itemBuilder: (context, index) => ItemTile(index),
),
);
}
}
class ItemTile extends StatelessWidget {
final int itemNo;
const ItemTile(this.itemNo, {super.key});
@override
Widget build(BuildContext context) {
var favoritesList = Provider.of<Favorites>(context);
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.primaries[itemNo % Colors.primaries.length],
),
title: Text(
'Item $itemNo',
key: Key('text_$itemNo'),
),
trailing: IconButton(
key: Key('icon_$itemNo'),
icon: favoritesList.items.contains(itemNo)
? const Icon(Icons.favorite)
: const Icon(Icons.favorite_border),
onPressed: () {
!favoritesList.items.contains(itemNo)
? favoritesList.add(itemNo)
: favoritesList.remove(itemNo);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(favoritesList.items.contains(itemNo)
? 'Added to favorites.'
: 'Removed from favorites.'),
duration: const Duration(seconds: 1),
),
);
},
),
),
);
}
}
lib/main.dart
içeriğini değiştir
lib/main.dart
içeriğini şu kodla değiştirin:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'models/favorites.dart';
import 'screens/favorites.dart';
import 'screens/home.dart';
void main() {
runApp(const TestingApp());
}
final _router = GoRouter(
routes: [
GoRoute(
path: HomePage.routeName,
builder: (context, state) {
return const HomePage();
},
routes: [
GoRoute(
path: FavoritesPage.routeName,
builder: (context, state) {
return const FavoritesPage();
},
),
],
),
],
);
class TestingApp extends StatelessWidget {
const TestingApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Favorites>(
create: (context) => Favorites(),
child: MaterialApp.router(
title: 'Testing Sample',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple,
),
useMaterial3: true,
),
routerConfig: _router,
),
);
}
}
Uygulama tamamlandı ancak henüz test edilmedi.
Uygulamayı çalıştırın. Aşağıdaki ekran görüntüsü gibi görünmelidir:
Uygulamada bir öğe listesi gösterilir. Herhangi bir satırdaki kalp şeklindeki simgeye dokunarak kalp simgesini doldurun ve öğeyi favoriler listesine ekleyin. AppBar
üzerindeki Favoriler düğmesi sizi favoriler listesini içeren ikinci bir ekrana götürür.
Uygulama artık test edilmeye hazır. Bir sonraki adımda uygulamayı test etmeye başlayacaksınız.
5. Sağlayıcı için birim testi
favorites
modelini birim test ederek başlayacaksınız. Birim testi nedir? Birim testleri, yazılımın her biriminin (işlev, nesne veya widget) amaçlanan görevi doğru şekilde yerine getirdiğini doğrular.
Entegrasyon testleri hariç Flutter uygulamasındaki tüm test dosyaları test
dizinine yerleştirilir.
test/widget_test.dart
bilgisini kaldır
Teste başlamadan önce widget_test.dart
dosyasını silin. Kendi test dosyalarınızı ekleyeceksiniz.
Yeni test dosyası oluşturma
İlk olarak, listeye yeni bir öğenin eklendiğini ve listenin değişikliği yansıttığını doğrulamak için Favorites
modelinde add()
yöntemini test edersiniz. Genel olarak, test
dizinindeki dizin yapısı, lib
dizinindeki dizin yapısını ve Dart dosyalarının adını da _test
eklenmiş olarak taklit eder.
test
dizininde bir models
dizini oluşturun. Bu yeni dizinde, aşağıdaki içeriğe sahip bir favorites_test.dart
dosyası oluşturun:
test/models/favorites_test.dart
import 'package:test/test.dart';
import 'package:testing_app/models/favorites.dart';
void main() {
group('Testing App Provider', () {
var favorites = Favorites();
test('A new item should be added', () {
var number = 35;
favorites.add(number);
expect(favorites.items.contains(number), true);
});
});
}
Flutter test çerçevesi, bir grupta birbirleriyle ilişkili benzer testleri bağlamanızı sağlar. Tek bir test dosyasında, lib
dizinindeki ilgili dosyanın farklı bölümlerini test etmeyi amaçlayan birden fazla grup olabilir.
test()
yöntemi iki konum parametresi alır: testin description
ve testi gerçekte yazdığınız callback
parametresi.
Listeden bir öğeyi kaldırmayı test edin. Aşağıdaki testi aynı Testing App Provider
grubuna ekleyin:
test/models/favorites_test.dart
test('An item should be removed', () {
var number = 45;
favorites.add(number);
expect(favorites.items.contains(number), true);
favorites.remove(number);
expect(favorites.items.contains(number), false);
});
Testi çalıştırma
Komut satırında projenin kök dizinine gidip aşağıdaki komutu girin:
$ flutter test test/models/favorites_test.dart
Her şey çalışırsa aşağıdakine benzer bir mesaj görürsünüz:
00:06 +2: All tests passed!
Test dosyasının tamamı: test/models/favorites_test.dart
.
Birim testi hakkında daha fazla bilgi için Birim testine giriş bölümünü ziyaret edin.
6. Widget testi
Bu adımda, widget'ları test etmek için kod ekleyeceksiniz. Widget testi sadece Flutter'a özeldir. Flutter'de her widget'ı ayrı ayrı test edebilirsiniz. Bu adımda HomePage
ve FavoritesPage
ekranları ayrı ayrı test edilir.
Widget testi, test()
işlevi yerine testWidget()
işlevini kullanır. test()
işlevinde olduğu gibi testWidget()
işlevi de iki parametre alır: description,
ve callback
. Ancak geri çağırma, bağımsız değişkeni olarak bir WidgetTester
parametresi alır.
Widget testleri, çalışan bir uygulamadakilerle aynı kaynakları widget'larınıza sağlayan TestFlutterWidgetsBinding
sınıfını kullanır (ör. animasyonları programlama yeteneği gibi, ancak uygulama içinde çalıştırmadan da ekran boyutu hakkında bilgi edinebilirsiniz. Bunun yerine, widget'ı örneklendirmek için bir sanal ortam kullanılır ve ardından testler sonuçları çalıştırır. Burada pumpWidget
, çerçeveye bir uygulamada olduğu gibi belirli bir widget'ı eklemesini ve ölçmesini söyleyerek süreci başlatır.
Widget test çerçevesi, bulanların text()
, byType()
ve byIcon().
gibi widget'ları bulmasını sağlar. Çerçeve, sonuçları doğrulamak için eşleştiriciler de sağlar.
HomePage
widget'ını test ederek başlayın.
Yeni test dosyası oluşturma
İlk test, HomePage
kaydırma işleminin düzgün şekilde çalışıp çalışmadığını doğrular.
test
dizininde yeni bir dosya oluşturun ve home_test.dart
olarak adlandırın. Yeni oluşturulan dosyaya aşağıdaki kodu ekleyin:
test/home_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:testing_app/models/favorites.dart';
import 'package:testing_app/screens/home.dart';
Widget createHomeScreen() => ChangeNotifierProvider<Favorites>(
create: (context) => Favorites(),
child: const MaterialApp(
home: HomePage(),
),
);
void main() {
group('Home Page Widget Tests', () {
testWidgets('Testing Scrolling', (tester) async {
await tester.pumpWidget(createHomeScreen());
expect(find.text('Item 0'), findsOneWidget);
await tester.fling(
find.byType(ListView),
const Offset(0, -200),
3000,
);
await tester.pumpAndSettle();
expect(find.text('Item 0'), findsNothing);
});
});
}
createHomeScreen()
işlevi, bir MaterialApp'te test edilecek widget'ı ChangeNotifierProvider'a sarmalanmış bir şekilde yükleyen bir uygulama oluşturmak için kullanılır. Ana Sayfa widget'ının, widget ağacında bu iki widget'ın üzerinde bulunması gerekir. Böylece, widget bunlardan devralabilir ve sundukları verilere erişebilir. Bu işlev, pumpWidget()
işlevine parametre olarak iletilir.
Ardından, çerçevenin ekranda oluşturulmuş bir ListView
bulup bulamayacağını test edin.
home_test.dart
alanına şu kod snippet'ini ekleyin:
test/home_test.dart
group('Home Page Widget Tests', () {
// BEGINNING OF NEW CONTENT
testWidgets('Testing if ListView shows up', (tester) async {
await tester.pumpWidget(createHomeScreen());
expect(find.byType(ListView), findsOneWidget);
});
// END OF NEW CONTENT
testWidgets('Testing Scrolling', (tester) async {
await tester.pumpWidget(createHomeScreen());
expect(find.text('Item 0'), findsOneWidget);
await tester.fling(
find.byType(ListView),
const Offset(0, -200),
3000,
);
await tester.pumpAndSettle();
expect(find.text('Item 0'), findsNothing);
});
});
Testi çalıştırma
İlk olarak, birim testi çalıştırdığınız gibi testi şu komutu kullanarak çalıştırın:
$ flutter test test/home_test.dart
Test hızlı bir şekilde çalıştırılır ve şuna benzer bir mesaj görürsünüz:
00:02 +2: All tests passed!
Widget testlerini bir cihaz veya emülatör kullanarak da çalıştırabilirsiniz. Bu testler, testin çalışmasını izlemenize olanak tanır. Çalışırken yeniden başlatma özelliğini de kullanabilirsiniz.
Cihazınızı takın veya emülatörünüzü başlatın. Testi bir masaüstü uygulaması olarak da çalıştırabilirsiniz.
Komut satırından projenin kök dizinine gidin ve aşağıdaki komutu girin:
$ flutter run test/home_test.dart
Testi çalıştıracağınız cihazı seçmeniz gerekebilir. Bu durumda, talimatları uygulayın ve bir cihaz seçin:
Multiple devices found:
Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.1 LTS 5.15.0-58-generic
Chrome (web) • chrome • web-javascript • Google Chrome 109.0.5414.119
[1]: Linux (linux)
[2]: Chrome (chrome)
Please choose one (To quit, press "q/Q"):
Her şey yolundaysa şuna benzer bir çıkış görürsünüz:
Launching test/home_test.dart on Linux in debug mode...
Building Linux application...
flutter: 00:00 +0: Home Page Widget Tests Testing if ListView shows up
Syncing files to device Linux... 62ms
Flutter run key commands.
r Hot reload. 🔥🔥🔥
R Hot restart.
h List all available interactive commands.
d Detach (terminate "flutter run" but leave application running).
c Clear the screen
q Quit (terminate the application on the device).
💪 Running with sound null safety 💪
An Observatory debugger and profiler on Linux is available at: http://127.0.0.1:35583/GCpdLBqf2UI=/
flutter: 00:00 +1: Home Page Widget Tests Testing Scrolling
The Flutter DevTools debugger and profiler on Linux is available at:
http://127.0.0.1:9100?uri=http://127.0.0.1:35583/GCpdLBqf2UI=/
flutter: 00:02 +2: All tests passed!
Ardından, test dosyasında değişiklik yapın ve uygulamayı yeniden başlatıp tüm testleri yeniden çalıştırmak için Shift + R
tuşuna basın. Uygulamayı durdurmayın.
HomePage widget'larını test eden gruba daha fazla test ekleyin. Aşağıdaki testi dosyanıza kopyalayın:
test/home_test.dart
testWidgets('Testing IconButtons', (tester) async {
await tester.pumpWidget(createHomeScreen());
expect(find.byIcon(Icons.favorite), findsNothing);
await tester.tap(find.byIcon(Icons.favorite_border).first);
await tester.pumpAndSettle(const Duration(seconds: 1));
expect(find.text('Added to favorites.'), findsOneWidget);
expect(find.byIcon(Icons.favorite), findsWidgets);
await tester.tap(find.byIcon(Icons.favorite).first);
await tester.pumpAndSettle(const Duration(seconds: 1));
expect(find.text('Removed from favorites.'), findsOneWidget);
expect(find.byIcon(Icons.favorite), findsNothing);
});
Bu test, IconButton
dokunuşunun Icons.favorite_border
(açık kalp) yerine Icons.favorite
(kalp dolu kalp) olduğunu, ardından tekrar dokunulduğunda tekrar Icons.favorite_border
olduğunu doğrular.
Shift + R
girin. Bu işlem, uygulamayı yeniden başlatır ve tüm testleri tekrar çalıştırır.
Test dosyasının tamamı: test/home_test.dart
.
FavoritesPage
öğesini aşağıdaki kod ile test etmek için aynı işlemi uygulayın. Aynı adımları uygulayın ve çalıştırın.
test/favorites_test.dart (test/favorites_test.dart)
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:testing_app/models/favorites.dart';
import 'package:testing_app/screens/favorites.dart';
late Favorites favoritesList;
Widget createFavoritesScreen() => ChangeNotifierProvider<Favorites>(
create: (context) {
favoritesList = Favorites();
return favoritesList;
},
child: const MaterialApp(
home: FavoritesPage(),
),
);
void addItems() {
for (var i = 0; i < 10; i += 2) {
favoritesList.add(i);
}
}
void main() {
group('Favorites Page Widget Tests', () {
testWidgets('Test if ListView shows up', (tester) async {
await tester.pumpWidget(createFavoritesScreen());
addItems();
await tester.pumpAndSettle();
expect(find.byType(ListView), findsOneWidget);
});
testWidgets('Testing Remove Button', (tester) async {
await tester.pumpWidget(createFavoritesScreen());
addItems();
await tester.pumpAndSettle();
var totalItems = tester.widgetList(find.byIcon(Icons.close)).length;
await tester.tap(find.byIcon(Icons.close).first);
await tester.pumpAndSettle();
expect(tester.widgetList(find.byIcon(Icons.close)).length,
lessThan(totalItems));
expect(find.text('Removed from favorites.'), findsOneWidget);
});
});
}
Bu test, kapat (kaldır) düğmesine basıldığında bir öğenin kaybolup kaybolmadığını doğrular.
Widget testi hakkında daha fazla bilgi için şu adresi ziyaret edin:
7. Entegrasyon testleriyle uygulama kullanıcı arayüzünü test etme
Entegrasyon testleri, uygulamanın her bir parçasının bir bütün olarak birlikte nasıl çalıştığını test etmek için kullanılır. integration_test
kitaplığı, Flutter'da entegrasyon testleri yapmak için kullanılır. Bu, Flutter'ın Selenium WebDriver, Protractor, Espresso veya Earl Gray sürümüdür. Paket, bir cihazda testi yürütmek için dahili olarak flutter_driver
kullanır.
Flutter'da entegrasyon testleri yazmak, widget testleri yazmaya benzer. Tek fark, entegrasyon testlerinin hedef cihaz olarak adlandırılan bir mobil cihaz, tarayıcı veya masaüstü uygulamasında çalıştırılmasıdır.
Testi yazın
Projenin kök dizininde integration_test
adlı bir dizin, ardından bu dizinde app_test.dart
adlı yeni bir dosya oluşturun.
integration_test/app_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:testing_app/main.dart';
void main() {
group('Testing App', () {
testWidgets('Favorites operations test', (tester) async {
await tester.pumpWidget(const TestingApp());
final iconKeys = [
'icon_0',
'icon_1',
'icon_2',
];
for (var icon in iconKeys) {
await tester.tap(find.byKey(ValueKey(icon)));
await tester.pumpAndSettle(const Duration(seconds: 1));
expect(find.text('Added to favorites.'), findsOneWidget);
}
await tester.tap(find.text('Favorites'));
await tester.pumpAndSettle();
final removeIconKeys = [
'remove_icon_0',
'remove_icon_1',
'remove_icon_2',
];
for (final iconKey in removeIconKeys) {
await tester.tap(find.byKey(ValueKey(iconKey)));
await tester.pumpAndSettle(const Duration(seconds: 1));
expect(find.text('Removed from favorites.'), findsOneWidget);
}
});
});
}
Testi çalıştırma
Cihazınızı takın veya emülatörünüzü başlatın. Testi bir masaüstü uygulaması olarak da çalıştırabilirsiniz.
Komut satırında projenin kök dizinine gidip aşağıdaki komutu girin:
$ flutter test integration_test/app_test.dart
Her şey yolundaysa şuna benzer bir çıkış görürsünüz:
Multiple devices found:
Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.1 LTS 5.15.0-58-generic
Chrome (web) • chrome • web-javascript • Google Chrome 109.0.5414.119
[1]: Linux (linux)
[2]: Chrome (chrome)
Please choose one (To quit, press "q/Q"): 1
00:00 +0: loading /home/miquel/tmp/testing_app/integration_test/app_test.dart B00:08 +0: loading /home/miquel/tmp/testing_app/integration_test/app_test.dart
00:26 +1: All tests passed!
8. Flutter Driver ile uygulama performansını test etme
Performans testi yazma
integration_test klasöründe aşağıdaki içeriğe sahip perf_test.dart adlı yeni bir test dosyası oluşturun:
integration_test/perf_test.dart
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:testing_app/main.dart';
void main() {
group('Testing App Performance', () {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
testWidgets('Scrolling test', (tester) async {
await tester.pumpWidget(const TestingApp());
final listFinder = find.byType(ListView);
await binding.traceAction(() async {
await tester.fling(listFinder, const Offset(0, -500), 10000);
await tester.pumpAndSettle();
await tester.fling(listFinder, const Offset(0, 500), 10000);
await tester.pumpAndSettle();
}, reportKey: 'scrolling_summary');
});
});
}
ensureInitialized()
işlevi, entegrasyon testi sürücüsünün başlatılıp başlatılmadığını doğrular ve gerekirse cihazı yeniden başlatır. framePolicy
politikasını fullyLive
değerine ayarlamak, animasyonlu kodu test etmek için uygundur.
Bu test, öğe listesinde gerçekten hızlı bir şekilde ilerler ve ardından en fazla yukarı kaydırır. traceAction()
işlevi, işlemleri kaydeder ve zaman çizelgesi özeti oluşturur.
Performans sonuçlarını yakalayın
Sonuçları yakalamak için perf_driver.dart
adlı dosya ile test_driver
adlı bir klasör oluşturun ve aşağıdaki kodu ekleyin:
test_driver/perf_driver.dart
import 'package:flutter_driver/flutter_driver.dart' as driver;
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() {
return integrationDriver(
responseDataCallback: (data) async {
if (data != null) {
final timeline = driver.Timeline.fromJson(
data['scrolling_summary'] as Map<String, dynamic>);
final summary = driver.TimelineSummary.summarize(timeline);
await summary.writeTimelineToFile(
'scrolling_summary',
pretty: true,
includeSummary: true,
);
}
},
);
}
Testi çalıştırma
Cihazınızı takın veya emülatörünüzü başlatın.
Komut satırında projenin kök dizinine gidip aşağıdaki komutu girin:
$ flutter drive \
--driver=test_driver/perf_driver.dart \
--target=integration_test/perf_test.dart \
--profile \
--no-dds
Her şey yolundaysa şuna benzer bir çıkış görürsünüz:
Running "flutter pub get" in testing_app...
Resolving dependencies...
archive 3.3.2 (3.3.6 available)
collection 1.17.0 (1.17.1 available)
js 0.6.5 (0.6.7 available)
matcher 0.12.13 (0.12.14 available)
meta 1.8.0 (1.9.0 available)
path 1.8.2 (1.8.3 available)
test 1.22.0 (1.23.0 available)
test_api 0.4.16 (0.4.18 available)
test_core 0.4.20 (0.4.23 available)
vm_service 9.4.0 (11.0.1 available)
webdriver 3.0.1 (3.0.2 available)
Got dependencies!
Running Gradle task 'assembleProfile'... 1,379ms
✓ Built build/app/outputs/flutter-apk/app-profile.apk (14.9MB).
Installing build/app/outputs/flutter-apk/app-profile.apk... 222ms
I/flutter ( 6125): 00:04 +1: Testing App Performance (tearDownAll)
I/flutter ( 6125): 00:04 +2: All tests passed!
All tests passed.
Test başarıyla tamamlandıktan sonra, projenin kökündeki derleme dizini iki dosya içerir:
scrolling_summary.timeline_summary.json
özeti içeriyor. İçindeki bilgileri incelemek için dosyayı herhangi bir metin düzenleyicide açın.scrolling_summary.timeline.json
, zaman çizelgesi verilerinin tamamını içerir.
Entegrasyon testi hakkında daha fazla bilgi edinmek için şu adresi ziyaret edin:
9. Tebrikler!
Codelab'i tamamladınız ve Flutter uygulamalarını test etmenin farklı yollarını öğrendiniz.
Öğrendikleriniz
- Birim testleri yardımıyla sağlayıcılar nasıl test edilir?
- Widget test çerçevesini kullanarak widget'ları test etme
- Entegrasyon testlerini kullanarak uygulamanın kullanıcı arayüzünü test etme
- Entegrasyon testlerini kullanarak uygulamanın performansını test etme
Flutter'da test yapma hakkında daha fazla bilgi edinmek için şu adresi ziyaret edin: