Flutter+Providerでウィジェットのテストを書く/widget-test-with-provider

 Flutter+Providerでウィジェットのテストを書く/widget-test-with-provider

23190387d424e33d6a1a807cea1e0469?s=128

Osamtimizer

August 07, 2020
Tweet

Transcript

  1. ࣌ాཧ(.01FQBCP *OD %BSU.FFUVQ0TBLB 'MVUUFS 1SPWJEFSͰ ΢ΟδΣοτͷςετΛॻ͘

  2. ϞόΠϧ8FCΞϓϦέʔγϣϯΤϯδχΞ ࣌ాཧ!PTBNUJNJ[FS 46;63*ࣄۀ෦ϓϩμΫτνʔϜ IUUQTPTBNUJNJ[FSIBUFOBCMPHDPN

  3. None
  4. ΦϦδφϧάοζ͕࡞ΕΔɺചΕΔɺങ͑Δɻ ը૾Λ1ຕΞοϓ ͢Δ͚ͩ ࣗಈతʹ঎඼͕ Ͱ͖·͢ ࣗ෼Ͱ΋ങ͑Δ͠ ചΔ͜ͱ΋Ͱ͖·͢

  5. None
  6. None
  7. ͸͡Ίʹ wࢿྉ͸ޙ΄ͲΠϯλʔωοτ্Ͱެ։͠·͢ wIUUQTTQFBLFSEFDLDPNPTBNUJNJ[FS

  8. ࠓ೔࿩͢͜ͱ w'MVUUFSͷ8JEHFU5FTU w1SPWJEFSʹґଘͨ͠΢ΟδΣοτͷ8JEHFU5FTUΛॻ͘ w·ͱΊ

  9. 8JEHFU5FTU

  10. ΢ΟδΣοτʹର͢Δςετ

  11. 'MVUUFSʹ͓͚Δςετ w6OJU5FTU୯Ұͷϝιου΍Ϋϥεʹର͢Δςετ w*OUFHSBUJPO5FTUΞϓϦશମʹର͢Δςετ w8JEHFU5FTU୯Ұͷ΢ΟδΣοτʹର͢Δςετ

  12. 'MVUUFSʹ͓͚Δςετ w6OJU5FTU୯Ұͷϝιου΍Ϋϥεʹର͢Δςετ w*OUFHSBUJPO5FTUΞϓϦશମʹର͢Δςετ w8JEHFU5FTU୯Ұͷ΢ΟδΣοτʹର͢Δςετ

  13. ΢ΟδΣοτͷԿΛ ςετ͢Δʁ

  14. ΢ΟδΣοτͷ ݟͨ໨ͱڍಈ

  15. 8JEHFU5FTU͕Χόʔ͢Δ΋ͷ w΢ΟδΣοτ͸એݴతʹهड़ ˠঢ়ଶΛ༩͑ͨͱ͖ɺ૝ఆͨ͠ݟͨ໨ʹͳΔ͔ʁ wϢʔβʔͷೖྗΠϕϯτͳͲΛड͚ͯԿ͔Λ͢Δ΢ΟδΣοτ΋͋Δ ˠΠϕϯτ͕ൃՐͨ͠ͱ͖ɺ૝ఆͨ͠ڍಈΛ͢Δ͔ʁ

  16. 8JEHFU5FTUΛॻ͍ͯΈΔ void main() { testWidgets('MyWidget has a title and message',

    (WidgetTester tester) async { // ςετͷ४උ await tester.pumpWidget(MyWidget(title: 'T', message: 'M')); // ΢ΟδΣοτͷ୳ࡧ final titleFinder = find.text('T'); final messageFinder = find.text('M'); // ϚονϟͰ΢ΟδΣοτΛݕূ expect(titleFinder, findsOneWidget); expect(messageFinder, findsOneWidget); }); } ࢀߟIUUQTqVUUFSEFWEPDTDPPLCPPLUFTUJOHXJEHFUJOUSPEVDUJPO
  17. 8JEHFU5FTUΛॻ͍ͯΈΔ void main() { testWidgets('MyWidget has a title and message',

    (WidgetTester tester) async { // ςετͷ४උ await tester.pumpWidget(MyWidget(title: 'T', message: 'M')); // ΢ΟδΣοτͷ୳ࡧ final titleFinder = find.text('T'); final messageFinder = find.text('M'); // ϚονϟͰ΢ΟδΣοτΛݕূ expect(titleFinder, findsOneWidget); expect(messageFinder, findsOneWidget); }); } ࢀߟIUUQTqVUUFSEFWEPDTDPPLCPPLUFTUJOHXJEHFUJOUSPEVDUJPO
  18. 8JEHFU5FTUΛॻ͍ͯΈΔ void main() { testWidgets('MyWidget has a title and message',

    (WidgetTester tester) async { // ςετͷ४උ await tester.pumpWidget(MyWidget(title: 'T', message: 'M')); // ΢ΟδΣοτͷ୳ࡧ final titleFinder = find.text('T'); final messageFinder = find.text('M'); // ϚονϟͰ΢ΟδΣοτΛݕূ expect(titleFinder, findsOneWidget); expect(messageFinder, findsOneWidget); }); } ࢀߟIUUQTqVUUFSEFWEPDTDPPLCPPLUFTUJOHXJEHFUJOUSPEVDUJPO
  19. 8JEHFU5FTUΛॻ͍ͯΈΔ void main() { testWidgets('MyWidget has a title and message',

    (WidgetTester tester) async { // ςετͷ४උ await tester.pumpWidget(MyWidget(title: 'T', message: 'M')); // ΢ΟδΣοτͷ୳ࡧ final titleFinder = find.text('T'); final messageFinder = find.text('M'); // ϚονϟͰ΢ΟδΣοτΛݕূ expect(titleFinder, findsOneWidget); expect(messageFinder, findsOneWidget); }); } ࢀߟIUUQTqVUUFSEFWEPDTDPPLCPPLUFTUJOHXJEHFUJOUSPEVDUJPO
  20. 8JEHFU5FTUΛॻ͍ͯΈΔ void main() { testWidgets('Add and remove a todo', (WidgetTester

    tester) async { await tester.pumpWidget(TodoList()); // WidgetTesterܦ༝Ͱ΢ΟδΣοτΛૢ࡞ await tester.enterText(find.byType(TextField), 'hi'); await tester.tap(find.byType(FloatingActionButton)); // ΢ΟδΣοτΛϦϏϧυ await tester.pump(); expect(find.text('hi'), findsOneWidget); await tester.drag(find.byType(Dismissible), Offset(500.0, 0.0)); await tester.pumpAndSettle(); expect(find.text('hi'), findsNothing); }); } ࢀߟIUUQTqVUUFSEFWEPDTDPPLCPPLUFTUJOHXJEHFUJOUSPEVDUJPO
  21. 8JEHFU5FTUΛॻ͍ͯΈΔ void main() { testWidgets('Add and remove a todo', (WidgetTester

    tester) async { await tester.pumpWidget(TodoList()); // WidgetTesterܦ༝Ͱ΢ΟδΣοτΛૢ࡞ await tester.enterText(find.byType(TextField), 'hi'); await tester.tap(find.byType(FloatingActionButton)); // ΢ΟδΣοτΛϦϏϧυ await tester.pump(); expect(find.text('hi'), findsOneWidget); await tester.drag(find.byType(Dismissible), Offset(500.0, 0.0)); await tester.pumpAndSettle(); expect(find.text('hi'), findsNothing); }); } ࢀߟIUUQTqVUUFSEFWEPDTDPPLCPPLUFTUJOHXJEHFUJOUSPEVDUJPO
  22. 8JEHFU5FTUΛॻ͍ͯΈΔ void main() { testWidgets('Add and remove a todo', (WidgetTester

    tester) async { await tester.pumpWidget(TodoList()); // WidgetTesterܦ༝Ͱ΢ΟδΣοτΛૢ࡞ await tester.enterText(find.byType(TextField), 'hi'); await tester.tap(find.byType(FloatingActionButton)); // ΢ΟδΣοτΛϦϏϧυ await tester.pump(); expect(find.text('hi'), findsOneWidget); await tester.drag(find.byType(Dismissible), Offset(500.0, 0.0)); await tester.pumpAndSettle(); expect(find.text('hi'), findsNothing); }); } ࢀߟIUUQTqVUUFSEFWEPDTDPPLCPPLUFTUJOHXJEHFUJOUSPEVDUJPO
  23. 8JEHFU5FTUͷ࣮ߦ $ flutter test 00:05 +1: All tests passed! ࢀߟIUUQTqVUUFSEFWEPDTDPPLCPPLUFTUJOHXJEHFUJOUSPEVDUJPO

  24. 8JEHFU5FTU wݕূ͍ͨ͠΢ΟδΣοτΛ5FTUFSʹ౉͢ wίʔυʹΑͬͯ΢ΟδΣοτΛૢ࡞ͯ͠ݕূ wཁૉ͕ଘࡏ͢Δ͔ wΠϕϯτൃՐ࣌ʹ૝ఆͨ͠ڍಈʹͳΔ͔

  25. 8JEHFU5FTUͷࠔΓͲ͜Ζ w6OJU5FTUͱൺֱ͢Δͱɺมߋʹऑ͍ w6*͸ͦ΋ͦ΋มߋ͞Ε΍͍͢ wςετ͸ͳΔ΂͘$*Ͱࣗಈ࣮ߦ͍ͤͨ͞ w͋·Γڽͬͨ8JEHFU5FTUΛॻ͖͗͢Δͱɺςετͷमਖ਼ʹ௥ΘΕΔ

  26. 1SPWJEFSʹґଘͨ͠ ΢ΟδΣοτͷςετ

  27. 1SPWJEFSʹґଘͨ͠΢ΟδΣοτͷςετ w1SPWJEFS w'MVUUFSͰͷঢ়ଶ؅ཧΛ͠΍͘͢͢Δύοέʔδ wґଘ͍ͯ͠Δ΢ΟδΣοτͷ8JEHFU5FTUʹ͸޻෉͕ඞཁ w͔͠͠ɺϝϦοτ΋͋Δ

  28. αϯϓϧΞϓϦ

  29. ˠ

  30. αϯϓϧΞϓϦ wϝʔϧΞϓϦ wΞϓϦΛىಈ͢Δͱ࠷৽ͷϝʔϧΛऔಘͯ͠දࣔ wϦετΛλοϓ͢Δͱϝʔϧͷৄࡉը໘ʹϓογϡભҠ

  31. αϯϓϧΞϓϦ .BUFSJBM"QQ )PNF 4DB⒎PME .BJM-JTU -JTU5JMF 1SPWJEFS -JTU5JMF -JTU5JMF

  32. αϯϓϧΞϓϦ .BUFSJBM"QQ )PNF 4DB⒎PME .BJM-JTU -JTU5JMF 1SPWJEFS -JTU5JMF -JTU5JMF

  33. αϯϓϧΞϓϦ class MailList extends StatefulWidget { … } class _MailListState

    extends State<MailList> { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { // initState׬ྃޙʹϝʔϧΛऔಘ͢ΔΞΫγϣϯΛൃߦ context.read<MailStore>().fetchMails(); }); } …
  34. αϯϓϧΞϓϦ class MailList extends StatefulWidget { … } class _MailListState

    extends State<MailList> { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { // initState׬ྃޙʹϝʔϧΛऔಘ͢ΔΞΫγϣϯΛൃߦ context.read<MailStore>().fetchMails(); }); } …
  35. αϯϓϧΞϓϦ Widget build(BuildContext context) { // Providerܦ༝Ͱදࣔ͢΂͖ϝʔϧҰཡΛऔಘ final mails =

    context.watch<MailStore>().mails; return Container( child: ListView.builder( itemBuilder: (context, index) { return ListTile( … onTap: () async { // ListTileλοϓ࣌ʹϝʔϧৄࡉʹભҠ Navigator.of(context).pushNamed( MailDetail.routeName, arguments: mails[index], );
  36. αϯϓϧΞϓϦͰςετ͍ͨ͠ϙΠϯτ w΢ΟδΣοτͷॳճϏϧυ࣌ʹϦΫΤετΛ࣮ߦͯ͠ϝʔϧΛऔಘ wϝʔϧΛλοϓ͢Δͱɺͦͷϝʔϧͷৄࡉը໘΁ભҠ

  37. αϯϓϧΞϓϦͰςετ͍ͨ͠ϙΠϯτ w΢ΟδΣοτͷॳճϏϧυ࣌ʹϦΫΤετΛ࣮ߦͯ͠ϝʔϧΛऔಘ wϝʔϧΛλοϓ͢Δͱɺͦͷϝʔϧͷৄࡉը໘΁ભҠ

  38. αϯϓϧΞϓϦͷ8JEHFU5FTU void main() { testWidgets("initialization", (WidgetTester tester) async { //ςετ༻ͷStoreΛ༻ҙ

    final store = MailStore(); expect(store.mails.length, 0); await tester.pumpWidget( // testerʹ౉͢΢ΟδΣοτΛProviderͰϥοϓ ChangeNotifierProvider.value( value: store, child: Home(), ), ); // Storeͷঢ়ଶΛݕূ expect(store.mails.length, 20);
  39. αϯϓϧΞϓϦͷ8JEHFU5FTU void main() { testWidgets("initialization", (WidgetTester tester) async { //ςετ༻ͷStoreΛ༻ҙ

    final store = MailStore(); expect(store.mails.length, 0); await tester.pumpWidget( // testerʹ౉͢΢ΟδΣοτΛProviderͰϥοϓ ChangeNotifierProvider.value( value: store, child: Home(), ), ); // Storeͷঢ়ଶΛݕূ expect(store.mails.length, 20);
  40. αϯϓϧΞϓϦͷ8JEHFU5FTU void main() { testWidgets("initialization", (WidgetTester tester) async { //ςετ༻ͷStoreΛ༻ҙ

    final store = MailStore(); expect(store.mails.length, 0); await tester.pumpWidget( // testerʹ౉͢΢ΟδΣοτΛProviderͰϥοϓ ChangeNotifierProvider.value( value: store, child: Home(), ), ); // Storeͷঢ়ଶΛݕূ expect(store.mails.length, 20);
  41. αϯϓϧΞϓϦͷ8JEHFU5FTU void main() { testWidgets("initialization", (WidgetTester tester) async { //ςετ༻ͷStoreΛ༻ҙ

    final store = MailStore(); expect(store.mails.length, 0); await tester.pumpWidget( // testerʹ౉͢΢ΟδΣοτΛProviderͰϥοϓ ChangeNotifierProvider.value( value: store, child: Home(), ), ); // Storeͷঢ়ଶΛݕূ expect(store.mails.length, 20);
  42. 1SPWJEFSΛ൐͏8JEHFU5FTU wςετͷର৅͸6*Ͱ͸ͳ͘ɺ΢ΟδΣοτͷৼΔ෣͍ w௨ৗͷ8JEHFU5FTUͱൺֱ͢Δͱɺมߋʹڧ͍ wςετΛॻ͘ෛՙΛ཈͑ͭͭɺมߋʹڧ͍ΞϓϦΛ࡞Γ΍͘͢ͳΔ

  43. ·ͱΊ w8JEHFU5FTU͸໊લͷ௨Γ΢ΟδΣοτʹର͢Δςετ wίʔυͰ΢ΟδΣοτͷૢ࡞Λهड़Ͱ͖Δ wมߋʹऑ͍͕ɺ1SPWJEFSͱ૊Έ߹ΘͤΔͱৼΔ෣͍ͷςετ͕Ͱ͖Δ wৼΔ෣͍ͷςετ͸มߋʹڧ͍