slow_net_simulator
테스트 목적을 위해 다양한 네트워크 조건을 시뮬레이션하는 Flutter 패키지입니다.
앱 성능을 테스트하기 위해 다양한 인터넷 연결 속도 및 조건(느린 연결 또는 연결 없음)을 시뮬레이션합니다. 특히 동일한 기기에서 백엔드 인터페이스를 개발하는 개발자에게 유용합니다.
{"sdk":"flutter"}{"sdk":"flutter"}^5.0.0아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.
SlowNetSimulator is a powerful Flutter package designed to help developers simulate different network speeds and conditions directly within their Flutter apps. This is especially useful for testing how your app behaves under various network conditions, such as 2G, 3G, 4G, or when there is a chance of network failures.
To use this package, add slow_net_simulator as a dependency in your pubspec.yaml file:
dependencies:
slow_net_simulator: ^1.0.0
Then run:
flutter pub get
main.dartIn your main function, configure the simulator with a predefined network speed and failure probability:
void main() {
SlowNetSimulator.configure(
speed: NetworkSpeed.EDGE_2G, // Choose a predefined speed or custom speed
failureProbability: 0.2, // 20% chance of failure
);
runApp(MyApp());
}
simulateTo simulate network behavior for any asynchronous request, wrap your request inside SlowNetSimulator.simulate. This works not only with Dio but also with any async operation:
final response = await SlowNetSimulator.simulate(() async {
return await dio.get('https://jsonplaceholder.typicode.com/posts/1');
});
You can replace the dio.get call with any other request or async operation:
final result = await SlowNetSimulator.simulate(() async {
// Perform any async task here
return await someAsyncFunction();
});
The failure probability parameter allows you to define the likelihood of a request failing. This is useful for testing how your app handles sudden request failures. For example:
SlowNetSimulator.configure(
speed: NetworkSpeed.HSPA_3G, // Simulating 3G speed
failureProbability: 0.5, // 50% chance of failure
);
With this setup, you can test your app's error handling capabilities and ensure it behaves gracefully under adverse conditions.
To enable the real-time adjustment of network conditions, you must ensure the overlay button is displayed on the screen. Place the following code at the top of your **build** method in your main widget or any widget where you want the overlay to appear:
@override
Widget build(BuildContext context) {
//-----to show overlay button---------------------
WidgetsBinding.instance.addPostFrameCallback((_) {
SlowNetOverlay.showOverlay(context);
});
return MaterialApp(
home: ExamplePage(),
);
}
Below is an example of how to integrate the SlowNetSimulator with a Flutter app:
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:slow_net_simulator/slow_net_simulator.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const ExamplePage(),
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
);
}
}
class ExamplePage extends StatefulWidget {
const ExamplePage({super.key});
@override
_ExamplePageState createState() => _ExamplePageState();
}
class _ExamplePageState extends State<ExamplePage> {
double failureProbability = 0.0;
NetworkSpeed speed = NetworkSpeed.HSPA_3G;
Post? _data;
String? errorResponse;
bool _isLoading = false;
bool _isSuccess = false;
final Dio dio = Dio();
@override
void initState() {
super.initState();
_configureSimulator(NetworkSpeed.HSPA_3G, 0.0);
}
void _configureSimulator(NetworkSpeed speed, double failureProbability) {
SlowNetSimulator.configure(
speed: speed, failureProbability: failureProbability);
setState(() {});
}
Future<void> _fetchData() async {
setState(() => _isLoading = true);
try {
final response = await SlowNetSimulator.simulate(() async {
return await dio.get('https://jsonplaceholder.typicode.com/posts/1');
});
setState(() {
_data = Post.fromJson(response.data);
_isSuccess = true;
errorResponse = null;
});
} catch (e) {
setState(() {
errorResponse = e.toString();
_isSuccess = false;
});
} finally {
setState(() => _isLoading = false);
}
}
@override
Widget build(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) {
SlowNetOverlay.showOverlay(context);
});
return Scaffold(
appBar: AppBar(
title: const Text('SlowNetSimulator Example'),
backgroundColor: Colors.red,
foregroundColor: Colors.white,
),
body: SafeArea(
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(child: _buildResponseDisplay()),
_buildFetchButton(),
],
),
),
),
);
}
Widget _buildResponseDisplay() {
if (_isLoading) {
return const Center(child: CircularProgressIndicator());
} else if (!_isSuccess && errorResponse != null) {
return Center(
child: Container(
height: 100,
width: 300,
padding: EdgeInsets.all(10),
color: Colors.red[100],
child: Column(
children: [
Icon(
Icons.error_rounded,
color: Colors.red[500],
size: 45,
),
Text(
errorResponse!,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 16, color: Colors.red[500]),
),
],
),
),
);
} else if (_data != null) {
return SizedBox(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Post Detail",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
Text(
_data!.title,
style: const TextStyle(fontSize: 17, fontWeight: FontWeight.bold),
),
Text(
_data!.body,
style: const TextStyle(fontSize: 16),
),
],
),
);
} else {
return const SizedBox.shrink();
}
}
Widget _buildFetchButton() {
return ElevatedButton(
autofocus: false,
style: ButtonStyle(
backgroundColor: WidgetStatePropertyAll(Colors.red),
foregroundColor: WidgetStatePropertyAll(Colors.white)),
onPressed: _isLoading ? null : _fetchData,
child: const Text('Fetch Data'),
);
}
}
class Post {
final int id;
final String title;
final String body;
Post({required this.id, required this.title, required this.body});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
id: json["id"],
title: json["title"],
body: json["body"],
);
}
}
Contributions are welcome! If you encounter issues or have feature requests, please open an issue or submit a pull request on the slow_net_simulator repository.
This project is licensed under the MIT License. See the LICENSE file for details.
Find this package on Pub.dev: slow_net_simulator