bdd_widget_test 0.1.4

  • Readme
  • Changelog
  • Example
  • Installing
  • new61

bdd_widget_test Build Status Coverage Status #

A BDD-style widget testing library

Why? #

Isn't it cool to develop mobile apps in natural language? A language each of your team members can read and understand so that it involves everyone working on the project productively. While Dart is on its way to this goal, for tests there is a language for that! It's called Gherkin.

The aim of this library is in combining two effective and easy-to-use techniques: BDD(Gherkin) and widget testing.

Getting Started #

Add the dependency #

Add build_runner and bdd_widget_test dependcies to dev_dependencies section of the pubspec.yaml file.

dev_dependencies:
  build_runner:
  bdd_widget_test: <put the latest version here>
  ...

You may get the actual version from installation instructions on Pub site.

Write features #

Create *.feature file inside test folder. Let's say you're testing the default Flutter counter app, the content might be:

Feature: Counter
    Scenario: Initial counter value is 0
        Given the app is running
        Then I see {0} text

Now ask built_value to generate Dart files for you. You may do this with the command:

flutter packages pub run build_runner watch --delete-conflicting-outputs

After that, the corresponding dart file will be generated for each of your feature files. Do not change the code inside these dart files as they will be recreated each time you change something in feature files.

During feature-to-dart generation additional step folder will be created. It will contain all steps required to run the scenario. These files will not be updated hence feel free to adapt the content according to your needs.

Run tests #

You're good to go! bdd_widget_test generated plain old Dart tests, so feel free to run you tests within your IDE or using the following command

flutter test

Feature file syntax #

Feature file sample:

// comment here

Feature: Counter

  Background:
    Given the answer is {42}

  Scenario: Initial counter value is 0
    Given the app is running
    Then I see {0} text

  Scenario: Plus button increases the counter
    Given the app is running
    When I tap {Icons.add} icon
    Then I see {1} text

Backround keyword is optional. A Background allows you to add some context to the scenarios that follow it. It can contain one or more Given steps, which are run before each scenario.

Each feature file must have one or more Feature:s. Features become test groups in Flutter tests.

Each feature group must have one or more Scenario:s (or Example:s). Scenario become widget tests.

Each scenario must have one or more lines with steps. Each of them must start with Given, When, Then, And, or But keywords. Conventionally Given steps are used for test arrangements, When — for interaction, Then — for asserts. Keywords are not taken into account when looking for a step definition. You can have as many steps as you like, but it's recommended you keep the number at 3-5 per scenario. Having too many steps will cause it to lose it’s expressive power as specification and documentation.

Predefined steps #

This library comes with a list of predefined steps. They will be auto-generated for you, but you may want to adjust their implementation according to your needs.

List of predefined steps:

  • Dismiss the page
  • I don't see {..} icon
  • I don't see {..} text
  • I see {..} icon
  • I see {..} text
  • I tap {..} icon
  • I tap {..} text
  • The app is running

FAQ #

How to pass a parameter? #

You may use curly brackets to pass the parameter into a step. The syntax is following:

  When I see {42} number
  And I see {Icons.add} icon

Notice, that the value inside brackets is copied to the Dart test file without changes hence it must be a valid Dart code. In the example above first step will have an int value. In order to pass a valid Dart string use '42' or "42".

You may call methods in step parameters, but most probably it's not what you want.

How to add additional imports to test files? #

Most of the time you shouldn't do that, as the BDD tests simulate user's behavior and it's just not possible for users to know the implementation details. Nevertheless, sometimes it might be in hand, i.e. when you have custom domain models or components. For example, if you need to check Cupertino icons in the test, you may have:

import 'package:flutter/cupertino.dart';

Feature: ...
  Then I see {CupertinoIcons.back} cupertino icon

How to adjust linter for auto-generated tests? #

Use the same trick as above, just write linter rules you wish to ignore at the beginning of the feature file:

// ignore_for_file: avoid_as, prefer_is_not_empty

Feature: ...

Contributing #

If you find a bug or would like to request a new feature, just open an issue. Your contributions are always welcome!

License #

bdd_widget_test is released under a MIT License. See LICENSE for details.

[0.1.4] - More Gherkin keywords #

  • Minor bug fixes
  • Add more Tap events
  • Add 'I Wait' step

[0.1.3] - More Gherkin keywords #

  • Add Background keyword
  • Add directives_ordering linter exception

[0.1.2] - More Gherkin keywords #

  • Add Example and But keywords

[0.1.1] - Hotfix #

  • Fix regular expressions for parameters parsing

[0.1.0] - First release #

  • Basic feature and steps generation
  • A few most common pre-built steps added

example/README.md

Create a *.feature file in you lib folder. The minimal file might be:

Feature: Counter
    Scenario: Initial counter value is 0
        Given the app is running
        Then I see {'0'} text

Run

flutter packages pub run build_runner watch --delete-conflicting-outputs

The output Dart file would be:

// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_import

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import './step/the_app_is_running.dart';
import './step/i_see_text.dart';

void main() {
  group('Counter app', () {
    testWidgets('Initial counter value is 0', (WidgetTester tester) async {
      await theAppIsRunning(tester);
      await iSeeText(tester, '0');
    });
  });
}

Refer to step folder to get familiar with steps implementation.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  bdd_widget_test: ^0.1.4

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:bdd_widget_test/bdd_widget_test.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
21
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
61
Learn more about scoring.

We analyzed this package on Jul 9, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.14
  • Flutter: 1.17.5

Analysis suggestions

Package not compatible with SDK dart

Because:

  • bdd_widget_test that is a package requiring null.

Package not compatible with runtime flutter-web on web

Because:

  • package:bdd_widget_test/bdd_widget_test.dart that imports:
  • package:build/build.dart that imports:
  • package:build/src/generate/run_post_process_builder.dart that imports:
  • package:build/src/builder/post_process_builder.dart that imports:
  • package:build/src/builder/builder.dart that imports:
  • package:build/src/builder/build_step.dart that imports:
  • package:build/src/asset/reader.dart that imports:
  • package:glob/glob.dart that imports:
  • package:glob/src/list_tree.dart that imports:
  • package:glob/src/io.dart that imports:
  • package:glob/src/io_export.dart that imports:
  • dart:io

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.7.0 <3.0.0
build ^1.3.0 1.3.0
build_config ^0.4.2 0.4.2
flutter 0.0.0
path ^1.6.4 1.7.0
strings ^0.1.2 0.1.2
Transitive dependencies
_fe_analyzer_shared 5.0.0
analyzer 0.39.12
args 1.6.0
async 2.4.2
charcode 1.1.3
checked_yaml 1.0.2
collection 1.14.12 1.14.13
convert 2.1.1
crypto 2.1.5
csslib 0.16.1
glob 1.2.0
html 0.14.0+3
js 0.6.2
json_annotation 3.0.1
lists 0.1.6
logging 0.11.4
meta 1.1.8 1.2.2
node_interop 1.1.1
node_io 1.1.1
package_config 1.9.3
pub_semver 1.4.4
pubspec_parse 0.1.5
sky_engine 0.0.99
source_span 1.7.0
string_scanner 1.0.5
term_glyph 1.1.0
typed_data 1.1.6 1.2.0
unicode 0.2.4
vector_math 2.0.8 2.1.0-nullsafety
watcher 0.9.7+15
yaml 2.2.1
Dev dependencies
build_runner ^1.10.0
build_web_compilers ^2.11.0
flutter_test
pedantic ^1.9.0 1.9.0 1.9.2