Guia minimalista para testes no Flutter — Parte 4 Pacotes úteis
Esta é a última parte da série Flutter Testing, eu só queria mostrar a você pacotes úteis para testes que você vai adorar!
Conteudo
Golden Toolkit
golden_toolkit
é um kit de ferramentas para testes de ouro que tornam seus testes muito mais fáceis e legíveis, e também é feito pelo eBay!
Exemplo
testGoldens('Weather types should look correct', (tester) async { final builder = GoldenBuilder.grid( columns:2, widthToHeightRatio: 1, )..addScenario('Sunny', WeatherCard(Weather.sunny)) ..addScenario('Cloudy', WeatherCard(Weather.cloudy)) ..addScenario('Raining', WeatherCard(Weather.rain)) ..addScenario('Cold', WeatherCard(Weather.cold)); await tester.pumpWidgetBuilder(builder.build()); await screenMatchesGolden(tester, 'weather_types_grid'); });
Alchemist
alchemist
também é um pacote de teste de ouro inspirado no golden_toolkit
, mas feito por equipes betterment
e Very Good Ventures
🦄 !
Exemplo
goldenTest( 'renders correctly', fileName: 'list_tile', builder: () => GoldenTestGroup( scenarioConstraints: const BoxConstraints(maxWidth: 600), children: [ GoldenTestScenario( name: 'with title', child: ListTile( title: Text('ListTile.title'), ), ), GoldenTestScenario( name: 'with title and subtitle', child: ListTile( title: Text('ListTile.title'), subtitle: Text('ListTile.subtitle'), ), ), GoldenTestScenario( name: 'with trailing icon', child: ListTile( title: Text('ListTile.title'), trailing: Icon(Icons.chevron_right_rounded), ), ), ], ), );
Patrol
patrol
é uma estrutura de teste de interface do usuário que elimina as limitações de flutter_test
, integration_test
e flutter_driver
.
Ele nos permite escrever testes mais legíveis, fáceis e avançados.
Exemplo
patrolTest( nativeAutomation: true, 'counter state is the same after going to Home and going back', ($) async { await $.pumpWidgetAndSettle(const MyApp()); await $(FloatingActionButton).tap(); expect($(#counterText).text, '1'); await $.native.pressHome(); await $.native.pressDoubleRecentApps(); expect($(#counterText).text, '1'); await $(FloatingActionButton).tap(); expect($(#counterText).text, '2'); await $.native.openNotifications(); await $.native.pressBack(); }, );
Fluttium
fluttium
é uma estrutura de teste de fluxo de usuário que nos permite escrever testes usando mágica! pelo autor dos pacotes flame
e umbra
!
Honey
honey
é um pacote que nos ajuda a escrever facilmente testes de ponta a ponta, feito por ClickUp
e Simon (o autor de Hive
e Isar
).
Convenient Test
convenient_test
, nos ajuda a gerenciar nossos testes usando uma bela GUI, do autor de flutter_portal
Spec
spec
é um framework de testes simplificado que torna os testes mais fáceis e seguros, feito pela invertase
!
import 'package:spec/spec.dart'; void main() { test('future example', () async { final future = Future.value(42); expect(future).toEqual(future); await expect(future).completion.toEqual(42); await expect(future).throws.isArgumentError(); }); test('stream example', () async { final stream = Stream.value(42); await expect(stream).emits.toEqual(42); await expect(stream).emits.isNull(); await expect(stream).emits.not.isNull(); await expect(stream).emitsError.isArgumentError(); }); test('function example', () { void throwsFn() => throw Error(); expect(throwsFn).returnsNormally(); expect(throwsFn).throws.isArgumentError(); }); }
Mockingjay
mockingjay
torna os testes de navegação ainda mais fáceis! por Very Good Ventures
🦄
Mocktail
Uma biblioteca mocking
sem geração de código, do autor do bloco!
class MockCat extends Mock implements Cat {} class Cat {...} final cat = MockCat();
Mockito
mockito
é uma biblioteca mocking com geração de código, feita pela equipe dart
!
@GenerateMocks([Cat]) class Cat {...} final cat = MockCat();
Faker
faker
nos dá valores falsos para adicionar aos nossos objetos de teste.
Exemplo
final faker = Faker(); faker.internet.email(); // francisco_lebsack@buckridge.com faker.internet.userName(); // fiona-ward faker.person.name(); // Fiona Ward
Flutter Gherkin
flutter_gherkin
nos permite dar valores e personalizar os testes usando BDD/Gherkin.
Feature: Hello World Hello World feature test Scenario: Check App Title And Content Given I expect the "firstTabTitle" to be "Jeresy Cool!" Then I expect the "textField" to be "Hello, Jersey!" Scenario: Check App Title When Switch Page Given I go to second page Then I expect second page title to be "Jersey Second Tab" When I go to landing page Then I expect landing page title to be "Jeresy Cool!" Feature: Counter Check counter is correct after tap add button Scenario: Check Counter Number Given I expect the "counterTextField" to be "0" When I tap the "addBtn" button 20 times Then I expect the "counterTextField" to be "20"
BDD Widget Test (BDD to Dart)
bdd_widget_test
nos ajuda a gerar testes apenas usando BDD!
Exemplo
Feature: Counter Background: Given the app is running After: And I do not see {'surprise'} text Scenario: Initial counter value is 0 Then I see {'0'} text Scenario: Add button increments the counter When I tap {Icons.add} icon Then I see {'1'} text Scenario Outline: Plus button increases the counter Given the app is running When I tap {Icons.add} icon <times> times Then I see <result> text Examples: | times | result | | 0 | '0' | | 1 | '1' | | 42 | '42' |
Para
Future<void> bddSetUp(WidgetTester tester) async { await theAppIsRunning(tester); } Future<void> bddTearDown(WidgetTester tester) async { await iDoNotSeeText(tester, 'surprise'); } group('''Counter''', () { testWidgets('''Initial counter value is 0''', (tester) async { try { await bddSetUp(tester); await iSeeText(tester, '0'); } finally { await bddTearDown(tester); } }); testWidgets('''Add button increments the counter''', (tester) async { try { await bddSetUp(tester); await iTapIcon(tester, Icons.add); await iSeeText(tester, '1'); } finally { await bddTearDown(tester); } }); testWidgets('''Outline: Plus button increases the counter (0, '0')''', (tester) async { try { await bddSetUp(tester); await theAppIsRunning(tester); await iTapIconTimes(tester, Icons.add, 0); await iSeeText(tester, '0'); } finally { await bddTearDown(tester); } }); testWidgets('''Outline: Plus button increases the counter (1, '1')''', (tester) async { try { await bddSetUp(tester); await theAppIsRunning(tester); await iTapIconTimes(tester, Icons.add, 1); await iSeeText(tester, '1'); } finally { await bddTearDown(tester); } }); testWidgets('''Outline: Plus button increases the counter (42, '42')''', (tester) async { try { await bddSetUp(tester); await theAppIsRunning(tester); await iTapIconTimes(tester, Icons.add, 42); await iSeeText(tester, '42'); } finally { await bddTearDown(tester); } }); });
BDD Framework (Dart to BDD)
bdd_framework
basicamente, converte seus códigos Dart em recursos BDD
Exemplo
final feature = BddFeature('Buying amount'); Bdd(feature) .scenario('Buying amount for stock orders, with zero fees.') // .given('The user has 120 dollars.') .and('IBM bid-price is 3 dollars, ask-price is 10.') .and('Fees are zero.') // .when('The user opens the order.') // .then('The buying amount is 12 shares.') .and('It costs 120 dollars.') // .run((ctx) async { // Given: setCashBalance(120); setQuote(IBM, bid: 3, ask: 10); setFees(0); // When: var buyingAmount = openOrder(IBM); // Then: expect(buyingAmount.shares, 12); expect(buyingAmount.dollars, 120); });
Saida
Feature: Buying amount Scenario: Buying amount for stock orders, with zero fees. Given the user has 120 dollars. And IBM bid-price is 3 dollars, ask-price is 10. And fees are zero. When the user opens the order. Then the buying amount is 12 shares. And it costs 120 dollars.
Obrigado por ler!