Nemanja Knežević
Nemanja Knežević

Reputation: 522

Can I run multiple integration tests with one single config file in Flutter?

I am trying to write Flutter integration tests and to run them all with one config file instead of making config file for every single test. Is there any way to do that?

For now I have login.dart and login_test.dart and so on, for every single test. I know its convention that every config and test file must have the same name, but that's not what I need, more configurable things are welcomed. Thanks in advance.

This is my config file: login.dart

import 'package:flutter_driver/driver_extension.dart';
import 'package:seve/main.dart' as app;

void main() {
  enableFlutterDriverExtension();
  app.main();
}

And test: login_test.dart looks something like this

import ...

FlutterDriver driver;

void main() {
  setUpAll(() async {
    driver = await FlutterDriver.connect();
  });

  tearDownAll(() async {
    if (driver != null) {
      driver.close();
    }
  });

  test('T001loginAsDriverAndVerifyThatDriverIsLogedInTest', () async {
    some_code...
  });
}

Now I want to make new test file e.g login_warning.dart and be able to start both tests by calling single config file login.dart. Is that even possible?

Upvotes: 10

Views: 7351

Answers (6)

dariowskii
dariowskii

Reputation: 315

I found a way to get this working!

File structure:

integration_test/
  e2e_tests/
      test_1.dart
      test_2.dart
  app_test.dart

app_test.dart:

import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:flutter/foundation.dart';

import 'e2e_tests/test_1.dart' as test1;
import 'e2e_tests/test_2.dart' as test2;

void main() {
  final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
  binding.framePolicy = LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
  
  // IMPORTANT: The setUpAll need to be only in main file!

  setUpAll(() async {
    TestWidgetsFlutterBinding.ensureInitialized();

    // Not mandatory, I was testing on web..
    if (kIsWeb) {
      usePathUrlStrategy();
    }
  });

  test1.main();
  test2.main();
}

test_1.dart:

import 'package:flutter_test/flutter_test.dart';

void main() {
  group('Test Group 1 - ', () {
    testWidgets(
      'test 1',
      (tester) async {
        // ...
      },
    );
  });
}

test_2.dart:

import 'package:flutter_test/flutter_test.dart';

void main() {
  group('Test Group 2 - ', () {
    testWidgets(
      'test 2',
      (tester) async {
        // ...
      },
    );
  });
}

Run the tests

Using flutter drive:

flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart --web-browser-flag="--disable-web-security --disable-gpu" -d chrome --headless --no-pub

Using simulator:

flutter test integration_test/app_test.dart --no-pub

Upvotes: 1

erluxman
erluxman

Reputation: 19385

We can use shell command to automate this process.

The following solution will work even with any new test files without manually adding its name to any of the files.

  1. Create a shell script with name integrationTestRunner.sh inside the root directory. You can use the command

    touch integrationTestRunner.sh

  2. Inside integrationTestRunner.sh file, paste the following code.

#!/bin/bash

# Declare an array to store the file names and paths
declare -a targets

# Find all .dart files in the current directory and subdirectories
while IFS= read -r -d $'\0' file; do
  targets+=("$file")
done < <(find integration_test -name "*.dart" -type f -print0)

# Loop through the array and run the flutter drive command for each target
for target in "${targets[@]}"
do
    flutter drive \
      --driver=test_driver/integation_test_driver.dart \
      --target=$target
done

  1. Run the integrationTestRunner.sh file with any methods:
  • Pressing the ▶️ button in that file (if you are in VS Code)
  • Running the script from command line ./integrationTestRunner.sh

Upvotes: 1

Kieran
Kieran

Reputation: 117

Like vzurd's answer my favourit and cleanest is to create a single test file and call all main methods from within:

import './first_test.dart' as first;
import './second_test.dart' as second;

void main() {
  first.main();
  second.main();
}

Then just run driver on the single test file:

flutter drive --driver=test/integration/integration_test_driver.dart --target=test/integration/run_all_test.dart

Upvotes: 6

to expand on to @sceee 's answer:

you can put the multiple commands into a shell script named integration_tests.sh for example and run them with a single command that way.

#!/bin/sh

flutter drive --target=test_driver/app.dart --driver=test_driver/app_test.dart
flutter drive --target=test_driver/app.dart --driver=test_driver/start_screen_test.dar 

make executable:
$chmod a+rx integration_tests.sh
run it:
$./integration_tests.sh

Upvotes: 3

vzurd
vzurd

Reputation: 1526

You can always have one main test file that you initiate, like say

flutter drive --target=test_driver/app_test.dart

Then in that call your test groups as functions, like so -

void main() {
  test1();
}
void test1() {
  group('test 1', () {});}

So with one command you get to execute all the cases mentioned in the main()

Upvotes: 7

sceee
sceee

Reputation: 2163

Yes, running multiple "test" files with the same "config" is possible.

In the flutter jargon, your config file is your target and your test file is your driver. Your target is always login.dart but you have the two drivers login_test.dart and login_warning.dart.

With the flutter drive command, you can specify the target as well as the driver.

So in order to run both drivers, simply execute the following commands

flutter drive --target=test_driver/login.dart --driver=test_driver/login_test.dart
flutter drive --target=test_driver/login.dart --driver=test_driver/login_warning.dart

This executes first the login_test.dart and then the login_warning.dart driver.

Upvotes: 11

Related Questions