marcglasberg / bdd_framework

Dart package: BDD framework for Dart/Flutter. Lets you create BDD tests in code, and gives you easy to read error messages when assertions fail. Exports to Gherkin/Cucumber feature files.
BSD 3-Clause "New" or "Revised" License
12 stars 1 forks source link

Support for integration tests using patrol #2

Open peer-f opened 1 year ago

peer-f commented 1 year ago

Hi, thank you for creating this great framework for BDD. I have a lot of tests that I'm planning to write documentation for. After reading through the extensive documentation provided by you I'm fully commited to document all of our tests using BDD.

I currently use patrol by LeanCode for integration tests since the original integration_test package lacked some of the features that we needed in our project. Because of that I was wondering if support for integration tests for example using patrol is planned. I tried running some of my patrol tests in bdd_framework which didn't work.

marcglasberg commented 1 year ago

Hi, glad you like it!

At the moment there are no planned extra features for this package. I have no experience with patrol and can't currently help with that, unfortunately. Maybe you could try forking the repo and adapting it? If you end up doing that, please let me know how it goes.

I'll leave this issue open and mark it as a new feature request. Thank you!

peer-f commented 1 year ago

Thanks for the quick response, I can look into it if I find the time!

The issue seems to be calling test() of flutter_test inside of the integration test. I'm not sure what is the best way to make this work.

Essentially what I want to achieve is a separation of each step of the integration test with documentation for each scenario.

Our app involves a long and time consuming onboarding process with lots of edge cases and user inputs. Because of that each scenario that happens inside patrolTest() is separated into methods to improve readability. Some of our tests contain 20 or more scenarios including navigating through different screens, confirming emails, MFA and so on.

I can give you a short example of this structure:

integration_test/create_account_test.dart

void main() {
  patrolTest(
    'Test account creation',
    ($) async {
      await createApp($);

      await initializePermissions($);
      await signUp($);
      await confirmEmail($);
      await signIn($);
      await signOut($);
    },
  );
}

Future<void> initializePermissions(PatrolIntegrationTester $) async {
  if (await $.native.isPermissionDialogVisible()) {
    await $.native.grantPermissionWhenInUse();
  }
}

Future<void> signUp(PatrolIntegrationTester $) async {
  const emailFormField = const ValueKey<String>('email_form_field');
  const passwordFormField = const ValueKey<String>('password_form_field');

  expect($(emailFormField), findsOneWidget);

  await $(emailFormField).enterText('test@example.com');

  expect($(passwordFormField), findsOneWidget);

  await $(passwordFormField).enterText('test1234');

  expect($(TextButton), findsOneWidget);

  await $(TextButton).scrollTo().tap();  // Navigates to email-confirmation page
}

...
marcglasberg commented 1 year ago

I'm not sure what is the best way to make this work.

Probably the framework should let you inject the function call, so that you can configure it to call patrolTest() (or any other function) instead of test().

Something along the lines of:

static TestCall testCall = test;

The, instead of calling test() of flutter_test inside of the integration test, it would call testCall.

And then before running your tests you would configure it to use your function:

testCall = patrolTest;

This would work for any testCall functions with the same signature.