ð¥Golden Testãå°å ¥ããŠUIéçºã®äžå®ã解æ¶ãã
ã¯ããã«
Flutter奜ãã®çããããã«ã¡ã¯ïŒ
ã¢ã«ãµãŒã¬ããŒãããŒãºæ ªåŒäŒç€Ÿã§Flutterãšã³ãžãã¢ãããŠããtaiseiã§ãïŒ
çªç¶ã§ããçãããFlutterã§UIã®éçºãé²ããäžã§ãããã®UIã¯ã©ããªããã€ã¹ã§ãé©åã«è¡šç€ºãããã®ã ããã..?ããšäžå®ã«æããããšã¯ãããŸãããïŒ
ã¬ã¹ãã³ã·ããã¶ã€ã³ã¯ãã¡ããã®ããšãããã¹ãã®ãã©ã³ããè²ãããŒã¯ã¢ãŒãã®è¡šç€ºãªã©è€æ°ã®ããã€ã¹ã§è€æ°ã®ç»é¢ãäžåäžåãã§ãã¯ããã®ã¯éªšã®æããäœæ¥ã§ãããéçºãé²ããäžã§å¯äœçšã«ãã£ãŠUIãå€æŽãããæ°ä»ããªããã¡ã«éçºãé²ãã§ããŸããšãã£ãããšããããŸãã
ããã§ããããã®åé¡ã解決ããæ¹æ³ãšããŠãGolden TestãšããUIãã¹ãææ³ããããŸãïŒïŒ
ä»åã¯ãã®Golden Testã«ã€ããŠãèšå®ããåºæ¬çãªäœ¿ãæ¹ãç§ãå®éã«ééãããšã©ãŒã«å¯Ÿãããã©ãã«ã·ã¥ãŒãã£ã³ã°çã解説ããŠããããšæããŸãïŒ
ãã®èšäºãçããã®éçºã®äžå©ã«ãªãã°å¬ããã§ãïŒ
察象è
ã»Golden Testã«ã€ããŠèå³ãããæ¹
ã»UIãã¹ãæ¹æ³ãè¿·ã£ãŠããæ¹
ã§ã¯ã解説ããŠããŸãð
Golden Testãšã¯ïŒ
Widgetãã¹ãã®äžçš®ã§ãéåžžã®Widgetãã¹ããã³ãŒããæ¢çŽ¢çã«æ€èšŒããã®ã«å¯ŸããGolden Testã¯éçºååŸã®ç»é¢ã®ã¹ã¯ãªãŒã³ã·ã§ãããæ¯èŒããŠãå·®åãæ€åºãããã¹ãææ³ã§ãããã¯ã»ã«åäœã§ã®å·®åã®æ€åºãå¯èœãªãããç®èŠã§ç¢ºèªãããããæ£ç¢ºãã€å¹ççã«UIã®ãã¹ããè¡ãããšãã§ããŸãã
Golden Testã§ã¯ãGolden Imageãšããã¢ããªã®UIãã©ã®ããã«èŠããã¹ããã®åºæºãšãªãç»åãå ã«ãã¹ããè¡ããŸãããã¹ãå®æœæã«ã¯ããã¹ãå®è¡äžã«çæãããã¹ã¯ãªãŒã³ã·ã§ãããšåºæºã§ããGolden Imageãæ¯èŒãããå®å šã«äžèŽããå Žåã¯ãã¹ããæåãããšã¿ãªãããŸããäžæ¹ã§ãäžèŽããªãå Žåã¯ãã¹ãã倱æãããšã¿ãªãããUIã®ã©ã®éšåã§å·®åãçºçããŠãããã®è©³çŽ°ãªæ å ±ãæäŸãããŸãã
Golden Testã®ã¡ãªãã
Golden Testãå®æœããã¡ãªãããšããŠã¯äžèšãæããããŸãã
- UIã®å質æ
ä¿:
â ãŠã£ãžã§ãããã¬ã€ã¢ãŠãããã¶ã€ã³éãã«å®è£
ãããŠãããã©ãããã¹ã¯ãªãŒã³ã·ã§ãããéããŠç¢ºèªã§ããŸãã
- ããžã¥ã¢ã«ãªã°ã¬ãã·ã§ã³ã®æ€åº:
â ãã¯ã»ã«åäœã§ã®å·®åãæ€åºããŠããããããUIã®æå³ããªãå€æŽã«ããã«æ°ã¥ãããšãã§ããŸãã
- å¹ççãªUIã®ç¢ºèª
â è€æ°ã®ã·ããªãª[1]ãäžã€ã®ã¹ã¯ãªãŒã³ã·ã§ããã§äžæ¬ã§ç¢ºèªã§ãããããç®èŠã§ç¢ºèªããããå¹ççã§ãã
ããšã¯éãšã³ãžãã¢ã«éçºäžã®UIãããã«å ±æããããšãã§ããç¹ã倧ããªã¡ãªããããªãšæããŸãã
Golden Testã®éçš
Golden Testã®éçšã«ã€ããŠãç§ãåç»ããŠããPJã§ã¯äžèšã®ããã«éçšããŠããŸãã
- ãã©ã³ããåã£ãŠUIéçº
-
flutter test --update-goldens
ã³ãã³ãã§åºæºãšãªãGolden Imageãäœæã»æŽæ° - å·®åã確èªããŠãæå³ããªãç»é¢ã®Golden ImageãæŽæ°ãããŠããå Žåã¯ä¿®æ£
- æŽæ°ããGolden Imageãå«ããŠPRãäœæ
ããŒã«ã«ã§ã¯ãã¹ããè¡ããšããããã¯ãæ°èŠç»é¢äœæãç»é¢æŽæ°æã«Golden ImageãæŽæ°ããæå³ããªãå€æŽãå«ãŸããŠããªããããã§ãã¯ãããããªéçšãããŠããŸãããŸããCIã®ã¯ãŒã¯ãããŒã§golden testãå®æœããããšã§ãç»é¢æŽæ°åŸã®Golden Imageã®æŽæ°å¿ããé²ãã§ããŸãã
PRæã«ã¹ã¯ã€ãããŠéçºååŸã®æ¯èŒããããšãåºæ¥ãŸãã
å°å ¥
ããã§ã¯ãGolden Testãå°å
¥ããŠãããŸãããïŒ
æ¬èšäºã§ã¯ãFlutterã§Golden Testãè¡ãéã«äŸ¿å©ãªããã±ãŒãžã§ããgolden_toolkitã«çŠç¹ãåœãŠãŸãã
1. ã€ã³ã¹ããŒã«
äžèšã³ãã³ããå®è¡
flutter pub add golden_toolkit
ãããã¯pubspec.yaml
ã«çŽæ¥golden_toolkitã®ããŒãžã§ã³ãæå®ããŠãã ããã
dependencies:
golden_toolkit: ^0.15.0
以äžã§ã€ã³ã¹ããŒã«ã¯å®äºã§ãïŒ
2. ãã£ãŠããã¹ãèšå®
golden_toolkitã䜿çšããŠGolden Testãå®æœããããã«ãã£ãŠããã¹ãèšå®ãããã€ããããŸãã
1. failuresãã©ã«ãã.gitignore
ã«è¿œå
ãã¹ã倱ææã«failuresãã£ã¬ã¯ããªã«å€±æããã¹ã¯ãªãŒã³ã·ã§ãããæ ŒçŽãããŸãããã¡ãã®ç»åã¯gitã§ç®¡çããçç±ããªãã®ã§gitç£èŠå¯Ÿè±¡å€ã«èšå®ããŠãããŸãããã
**/failures/*.png
2. ãgoldenãã¿ã°ã®è¿œå
dart_test.yaml
ãã¡ã€ã«ã«ãgoldenãã¿ã°ãè¿œå ããŸãã
tags:
golden:
dart_test.yamlãšã¯ïŒ
ãã¹ãã®èšå®ãã«ã¹ã¿ãã€ãºããããã®èšå®ãã¡ã€ã«ã§ãã
詳ããèšå®æ¹æ³ã«ã€ããŠã¯äžèšåç
§ãã ããã
Golden Testãèšè¿°ããtestGoldens
é¢æ°ã«ã¯ãããã©ã«ãã§ãgoldenãã¿ã°ãèšå®ãããŠãããããäŸãã°flutter test --tags=golden
ãšãã£ãã³ãã³ããå®è¡ãããšãgoldenã¿ã°ãèšå®ãããŠãããã¹ãã®ã¿å®è¡ãããããã«ãªãããã¹ãã®å¹çåã«ã€ãªãããŸãã
3. VScodeã®èšå®
ãšãã£ã¿ã«VSCodeã䜿çšããŠããå Žåã.vscode/launch.json
ã«äžèšèšå®ãè¿œå ããŠãããšäŸ¿å©ã§ãã
{
"version": "0.2.0",
"configurations": [
{
"name": "Golden",
"request": "launch",
"type": "dart",
"codeLens": {
"for": ["run-test", "run-test-file"]
},
"args": ["--update-goldens"]
}
]
}
4. ãã©ã³ãã®èªã¿èŸŒã¿ïŒéèŠïŒ
Flutterã®ãã¹ãã§ã¯ãããã©ã«ãã§ãAhemããšãããã¹ãå°çšã®ãã©ã³ãã䜿çšãããŸãããã®ãã©ã³ãã¯ããã¹ãŠã®æåãšã¢ã€ã³ã³ã«é»ãã¹ããŒã¹ã衚瀺ããããã«èšèšãããŠãããã¢ããªã®èŠãç®ãæ£ç¢ºã«ãã¹ãããGolden Testã«ã¯é©ããŠããŸããã
ãã¡ãã解決ããããã«ã¯æäŸãããŠããäžèšãã«ããŒã¡ãœããããã¹ãåã«å®è¡ããå¿ èŠããããŸãã
await loadAppFonts();
ãã¹ãæã«æ¯åãã¡ãã®ã¡ãœãããå®è¡ããŠãããã§ãããæãæŒããå¯èœæ§ãããã®ã§ããã¹ãå®è¡åã«èªåã§ãã©ã³ããèªã¿èŸŒãã§ããããããå°çšã®flutter_test_config.dart
ãã¡ã€ã«ãäœæããŸãã
import 'dart:async';
import 'package:golden_toolkit/golden_toolkit.dart';
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
await loadAppFonts();
return testMain();
}
åºæ¬çãªèšå®ã¯ä»¥äžã§å®äºã§ãïŒ
Golden Testã®åºæ¬
äžèšã®ç»é¢ã䜿ã£ãŠGolden Testã®åºæ¬ã«ã€ããŠè§£èª¬ããŠãããŸãã
ãœãŒã¹ã³ãŒã
import 'package:flutter/material.dart';
enum Weather {
sunny(
'æŽã',
Icons.sunny,
),
cloudy(
'æã',
Icons.cloud,
),
rain(
'éš',
Icons.grain,
),
snow(
'éª',
Icons.ac_unit,
);
const Weather(this.text, this.icon);
final String text;
final IconData icon;
}
class WeatherScreen extends StatelessWidget {
const WeatherScreen({super.key});
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromARGB(255, 241, 241, 241),
appBar: AppBar(
title: const Text('Golden Test'),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: GridView.builder(
itemCount: Weather.values.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
),
itemBuilder: (_, index) => WeatherScreenItem(
weather: Weather.values[index],
),
),
),
);
}
}
class WeatherScreenItem extends StatelessWidget {
const WeatherScreenItem({super.key, required this.weather});
final Weather weather;
Widget build(BuildContext context) {
return SizedBox(
width: 200,
height: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Stack(
clipBehavior: Clip.hardEdge,
children: <Widget>[
Container(
alignment: Alignment.center,
decoration: const BoxDecoration(
color: Colors.amber,
),
width: 200,
height: 200,
),
Positioned(
left: -80,
top: -80,
child: Icon(
weather.icon,
color: Colors.white,
size: 200,
),
),
Padding(
padding: const EdgeInsets.all(16),
child: Align(
alignment: Alignment.bottomRight,
child: Text(
weather.text,
style: const TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.w900,
),
),
),
),
],
),
),
);
}
}
ãã¹ãäœæ
éåžžã®ãã¹ããšåæ§ã«ä»»æã®åå_test.dart
ãšãããã¡ã€ã«ãäœæãããã¹ããæžããŠãããŸãã
void main() {
// ãŽãŒã«ãã³ãã¹ããå®çŸ©ããããã®é¢æ°
testGoldens(
'Weather Screen Test',
(tester) async {
// ç°ãªãããã€ã¹ãµã€ãºã§Widgetããã¹ãããããã«äœ¿çš
final builder = DeviceBuilder()
// ããã€ã¹ã®çš®é¡ãæå®ãæå®ããçš®é¡åã¹ã¯ãªãŒã³ã·ã§ãããäœæãããŸãã
..overrideDevicesForAllScenarios(devices: [
Device.phone,
Device.iphone11,
])
// ãã¹ãããã·ããªãªãè¿œå ãä»åã¯WeatherScreenå
šäœããã¹ãã
..addScenario(
widget: testableWidget(
child: const WeatherScreen(),
)
);
// addScenarioã§æå®ããWidgetãã¬ã³ããªã³ã°
await tester.pumpDeviceBuilder(
builder,
);
// ã¬ã³ããªã³ã°ãããWidgetã®ã¹ã¯ãªãŒã³ã·ã§ãããäœæãã第äºåŒæ°ã§æå®ãããã¡ã€ã«ãšæ¯èŒããŸãã
await screenMatchesGolden(tester, 'weather_screen_test');
},
);
}
testableWidget
ã¯ããã©ã³ãã®èªã¿èŸŒã¿ãThemeã®èšå®ãé©çšããããããMaterialAppãè¿åŽããé¢æ°ãäœæããŠããŸããThemeã®éšåã¯ãå®éã«å©çšããMaterialAppãšå
±éã®Themeãæå®ããŠãããšè¯ãã§ãããã
Widget testableWidget({required Widget child}) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
fontFamily: 'Murecho',
),
debugShowCheckedModeBanner: false,
home: child,
);
}
Golden Imageãäœæ
ãã¹ããäœæãããäžèšã³ãã³ããå®è¡ããŠGolden ImageãäœæããŸãã
flutter test --update-goldens
以äžã§goldens/ãã£ã¬ã¯ããªé äžã«ã¹ã¯ãªãŒã·ã§ãããäœæãããããšæããŸãïŒ
å šãŠã®Golden Testã§è€æ°ã®ããã€ã¹ãèšå®ãã
overrideDevicesForAllScenarios
ã§åºåãããããã€ã¹ã®èšå®ãè¡ãããšãã§ããŸããããã¹ãæ¯ã§æå®ããã®ãåé·ãªã®ã§å
±éåããããšããã§ããgolden_toolkitã§ã¯GoldenToolkit.runWithConfiguration()
ãšããèšå®çšã¯ã©ã¹ãæäŸãããŠããããããã¡ãã®èšå®ãflutter_test_config.dart
ã«è¿œå ããŸãã
import 'dart:async';
import 'dart:io';
import 'package:golden_toolkit/golden_toolkit.dart';
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
return GoldenToolkit.runWithConfiguration(
() async {
// ãã©ã³ãã®èªã¿èŸŒã¿
await loadAppFonts();
await testMain();
},
config: GoldenToolkitConfiguration(
// åºåããããã€ã¹ãæå®
defaultDevices: const [
Device.phone,
Device.iphone11,
],
skipGoldenAssertion: () => !Platform.isMacOS,
),
);
}
ã³ã³ããŒãã³ãåäœã§Golden Testãè¡ã
å
ã»ã©ã¯DeviceBuilder
ã䜿çšããŠã端æ«ããšã®Golden Imageã®çæãè¡ããŸããããGoldenBuilder
ã䜿çšããããšã«ãã£ãŠã³ã³ããŒãã³ãåäœã§ã¹ã¯ãªãŒã³ã·ã§ãããäœæããããšãã§ããŸãã
testGoldens(
'Weather Screen Item Test',
(tester) async {
final builder = GoldenBuilder.grid(
// 暪ã«é
眮ããã³ã³ããŒãã³ãã®æ°
columns: 2,
// ã«ã©ã æ°ãšå¹
ãšé«ãã®æ¯ç
widthToHeightRatio: 1,
)
// åEnumã®å€ã§ã·ããªãªãäœæ
..addScenario(
'Sunny',
const WeatherScreenItem(weather: Weather.sunny),
)
..addScenario(
'Cloudy',
const WeatherScreenItem(weather: Weather.cloudy),
)
..addScenario(
'Raining',
const WeatherScreenItem(weather: Weather.rain),
)
..addScenario(
'Snow',
const WeatherScreenItem(weather: Weather.snow),
);
await tester.pumpWidgetBuilder(
builder.build(),
wrapper: (child) => TestUtils.buildTestMaterialApp(child),
);
await screenMatchesGolden(
tester,
'weather_types_grid',
autoHeight: true,
);
},
);
åºåããã³ã³ããŒãã³ãã«ãã£ãŠã¯ãã¹ã¯ãªãŒã³ã·ã§ãããèŠåããŠããŸãå Žåãããã®ã§autoHeight: true
ãèšå®ããããšã«ãã£ãŠãèªåçã«é«ããåãããŠãããŸãã
Golden Imageã®åºåå ãå€æŽãã
ããã©ã«ãã§ã¯ãã¹ããã¡ã€ã«ãšåéå±€ã«goldens/ãã£ã¬ã¯ããªãäœæããããã®é
äžã«Golden Imageãæ ŒçŽãããŸããããGolden Imageã®åºåå
ãå€æŽãããå Žåã¯ãGoldenToolkitConfiguration
ã®fileNameFactory
ã§å€æŽããããšãå¯èœã§ãã
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
return GoldenToolkit.runWithConfiguration(
() async {
// çç¥
},
config: GoldenToolkitConfiguration(
fileNameFactory: (name) {
return 'goldens/$name.png'; â Golden Imageã®ä¿åå
ãå€æŽ
},
// çç¥
),
);
}
åŒæ°ã§åãåãname
ã¯ãã¹ãå®è¡æã®await screenMatchesGolden(tester, 'counter_screen');
ã®ç¬¬äºåŒæ°ã«æå®ããååãæž¡ãããŸãã
ãã©ãã«ã·ã¥ãŒãã£ã³ã°
ãã®ç« ã§ã¯ãç§ãå®éã«ééãããšã©ãŒãšããããã解決ããæ¹æ³ã«ã€ããŠè§£èª¬ããŠãããŸãã
Golden Imageã«é»ãæ ç·ã衚瀺ããã
äžèšç»åã®ããã«Widgetã«é»è²ã®æ ç·ãã€ãããšããããŸãã
ããã¯Flutterã®ããŒãžã§ã³éïŒãŸãã¯å®è¡ç°å¢ïŒã«ãã£ãŠåœ±ã®è¡šç€ºãå€ããå¯èœæ§ããããããããã©ã«ãã§ã¯åœ±ãé»ãæ ç·ã«çœ®ãæããããŠè¡šç€ºãããŸãã
ãã®é»ãæ ç·ãåé€ãããå Žåã¯GoldenToolkit.runWithConfiguration
ã«äžèšèšå®ãå ããããšã§åé€ããããšãã§ããŸãã
Future<void> testExecutable(FutureOr<void> Function() testMain) async {
return GoldenToolkit.runWithConfiguration(
() async {
// çç¥
},
config: GoldenToolkitConfiguration(
enableRealShadows: true,ãâ è¿œå
// çç¥
),
);
}
flutter_screenutilããã±ãŒãžäœ¿çšæã®ãšã©ãŒ
ã¬ã¹ãã³ã·ã察å¿ãç°¡åã«å®çŸã§ããããã±ãŒãžãšããŠãflutter_screenutilããããŸãã
ãã¡ãã®ããã±ãŒãžã䜿çšããç»é¢ã§Golden Testãå®æœãããšäžèšã®ãããªãšã©ãŒãçºçããŸãã
âââ¡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
The following LateError was thrown building WeatherScreenItem(dirty):
LateInitializationError: Field '_data@32084504' has not been initialized.
The relevant error-causing widget was:
WeatherScreenItem
WeatherScreenItem:file://zenn.dev/Users/t-z/workspace/flutter/advent_calendar_2023/test/ui/weather_screen_test.dart:46:17
ãšã©ãŒå
容ãèªããšãweather_screen_test.dartã®46è¡ç®ã§_data@32084504
ãšãããã£ãŒã«ããåæåãããŠããªããšãããšã©ãŒå
容ã«ãªããŸããã46è¡ç®ã«ã¯ãã¹ã察象ç»é¢ãæå®ããããããã¹ã察象ã®ç»é¢ã§ã¯flutter_screenutilããã±ãŒãžã䜿çšããŠããŸãã
flutter_screenutilããã±ãŒãžã䜿çšããéã«ã¯ãScreenUtilInitãŠã£ãžã§ãããçšããŠãã¢ããªã±ãŒã·ã§ã³ã®ç»é¢ãæç»ãããåã«ScreenUtilãåæåããå¿ èŠããããŸããGolden Testã§ãåæ§ã«ãã¹ãå®è¡åã«ScreenUtilã®åæåãããå¿ èŠããããããåé ã§äœæããWrapperé¢æ°ãäžèšã®ããã«ä¿®æ£ããŸãã
class _Wrapper extends StatelessWidget {
final Widget child;
const _Wrapper(this.child);
Widget build(BuildContext context) {
ScreenUtil.init(
context,
designSize: const Size(430.0, 932.0),
);
return child;
}
}
Widget testableWidget({required Widget child}) {
return _Wrapper(MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
fontFamily: 'Murecho',
),
debugShowCheckedModeBanner: false,
home: child,
));
}
èªåã®ç°å¢ã§ã¯çºçããŸããã§ãããããFlutterãscreenutilã«å¯Ÿå¿ããGolden Testã®å®è£
ã®èšäºã®éãã¹ã¯ãªãŒã³ã·ã§ãã解å床ããããããªãå Žåã¯ãããã®ã§ããã®å Žåã¯MediaQuery
ã§ã©ããããŠãããå¿
èŠããããŸãã
Widget testableWidget({required Widget child}) {
return MediaQuery(
data: const MediaQueryData(),
child: _Wrapper(MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
fontFamily: 'Murecho',
),
debugShowCheckedModeBanner: false,
home: child,
)),
);
}
ãŸãšã
ä»åã¯golden_toolkitã䜿ã£ãGolden Testã«ã€ããŠè§£èª¬ããŸããïŒ
ãŸã ãŸã çºå±éäžãªéšåããããŸãããå°å
¥ãç°¡åãªã®ã§çãããããžã§ã¯ãã«ããã²åãå
¥ããŠã¿ãŠãã ããïŒ
ã¡ãªã¿ã«Flutterå ¬åŒã®UI testææ³ãšããŠã玹ä»ãããŠããã®ã§ããããã®é²åã楜ãã¿ã§ãïŒ
ããã§ã¯è¯ãGoldenã©ã€ãã!!
åè
ã»FutureCon2022 Flutter Golden Testã®ããã
ã»Flutter ã§CI/CDã®åãçµãåã«ç¥ã£ãŠããããã£ããã¹ãé¢é£ã®èŠãæžã
ã»Flutterããã±ãŒãžã管çããéã«åœ¹ç«ã€CI/CD (GitHub Actions)
ã»Flutterã«Golden Testãå°å
¥ããŸãã
äœè«
ä»åã®èšäºãæžãã«ããã£ãŠããªãGolden Testã¯Goldenãšããã®ãïŒãã«ã€ããŠæ°ã«ãªã£ãã®ã§ChatGPTã«èããŠã¿ãŸããã
ããªã
Golden Testã®Goldenãšã¯ã©ãããæå³ã§äœ¿çšãããŠããŸããïŒïŒ
ChatGPT
ããŽãŒã«ãã³ãã¹ãããŸãã¯ããŽãŒã«ãã³ãã¡ã€ã«ãã¹ãããšããçšèªã¯ããœãããŠã§ã¢ãã¹ãã®åéã§äœ¿ãããèšèã§ãããã®çšèªã®ããŽãŒã«ãã³ããšããéšåã¯ããã¹ãã®åºæºãšãªãåºåãçµæããéã®ããã«äŸ¡å€ãããããã€ãŸãéåžžã«ä¿¡é Œæ§ãé«ããæ£ç¢ºã§ããããšãæå³ããŠããŸãããŽãŒã«ãã³ãã¡ã€ã«ã¯ããã¹ãã®æ£ç¢ºãªåºæºç¹ãšããŠæ©èœããæ°ãããã¹ãçµæããã®åºæºãšã©ã®ããã«ç°ãªãããè©äŸ¡ããããã«äœ¿çšãããŸãã
ãã®çšèªã®ç±æ¥ã¯ãäžè¬çã«ããŽãŒã«ãã³ã¹ã¿ã³ããŒãããŸãã¯ãé»éåºæºããšããè¡šçŸã«ç±æ¥ããŠããŸããããã¯ãäœããæé«æ°ŽæºãŸãã¯æãä¿¡é Œæ§ã®é«ãäŸãšããŠèªèãããããšãæå³ããŸãããœãããŠã§ã¢ãã¹ãã®æèã§ã¯ããŽãŒã«ãã³ãã¡ã€ã«ã¯ãã®ãããªæé«æ°Žæºã®äŸãšèŠãªããããã¹ãã®ä¿¡é Œæ§ãšæ£ç¢ºæ§ãä¿èšŒããããã®åºæºç¹ãšããŠæ©èœããŸãã
â»äžéšæ¹å€ããŠããŸãã
ããŽãŒã«ãã³ããšããéšåã¯ããã¹ãã®åºæºãšãªãåºåãçµæããéã®ããã«äŸ¡å€ãããããã€ãŸãéåžžã«ä¿¡é Œæ§ãé«ããæ£ç¢ºã§ããããšãæå³ããŠããŸã
ãªãã»ã©ïŒïŒçŽåŸïŒïŒ
-
äŸãã°ããŠãŒã¶ã®æš©éã«ãã£ãŠè¡šç€ºããUIãå€æŽããå Žåããã¹ãã³ãŒãã«ããããã®ã±ãŒã¹ãæžãããšã«ãã£ãŠãäžã€ã®ã¹ã¯ãªãŒã³ã·ã§ããã§å šãŠã®ã±ãŒã¹ã®ç»é¢ã確èªããããšãã§ããŸãã â©ïž
-
ãã®ãããŒãã£ãŒãã¯ChatGPTã§çæããŠããããŸãããæ®éã«ãããã â©ïž
Discussion