Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2201.9.0] Add test parallelisation document #8821

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
layout: ballerina-testing-code-left-nav-pages-swanlake
title: Execute tests in parallel
description: Learn how to execute tests in parallel.
keywords: ballerina, programming language, testing, test execution
permalink: /learn/test-ballerina-code/execute-tests-in-parallel/
active: execute-tests-in-parallel
intro: Ballerina test framework allows developers to execute test cases in parallel, which can significantly reduce the overall test execution time, especially for large codebases with a large number of test cases.
---

## Enable parallel execution of tests

Tests are executed serially by default. The user has to explicitly activate the parallel execution by providing the `--parallel` flag as follows.

```bash
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
bal test --parallel
```

Before running tests concurrently, it's crucial to ensure concurrency safety. Ballerina inherently evaluates the concurrency safety of tests to some extent using a predefined set of rules. Tests that don't comply with these rules are executed sequentially, regardless of the parallel flag being enabled.
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved

## Exclude a specific test from parallel execution

Certain tests may have dependencies or requirements that make them incompatible with parallel execution, such as shared resources or specific environment setups. If such a requirement is identified, the user may need to set the `serialExecution` flag to `true` as follows.
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved

```ballerina
@test:Config {serialExecution: true}
function testAssertEquals6() {
test:assertEquals(100, 100);
}
```

## Write a concurrent safe test case

A set of rules should be followed while writing a parallel test.

1) The test function should be isolated. In some instances, the compiler infers the test functions as isolated automatically if there are sufficient conditions to make them concurrently safe.
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
2) If it is a data provider test,
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
- The data provider of the test function should be isolated.
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
- The test function parameters should be read-only type.
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
3) Respective set-up and tear-down functions (`before`, `after`, `BeforeEach`, `AfterEach`, `BeforeGroups`, `AfterGroups`) of the test function should be isolated.
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved

Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
A warning related to unparallelized tests is printed at the beginning of the parallel test execution with the reasons.
Consider the following example.

```ballerina
import ballerina/lang.runtime;
import ballerina/test;

int a = 0;

@test:Config {
dataProvider: mapDataProvider
}
function mapDataProviderTest(int value1, int value2, string fruit) returns error? {
test:assertEquals(value1, value2, msg = "The provided values are not equal");
runtime:sleep(0.1);
a = 8;
}

function mapDataProvider() returns map<[int, int, string]>|error {
a = 10;
map<[int, int, string]> dataSet = {
"banana": [10, 10, "banana"],
"cherry": [5, 5, "cherry"],
"apple": [5, 5, "apple"],
"orange": [5, 5, "orange"]
};
return dataSet;
}
```

The above code results in the following warning.

```bash
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved
WARNING: Test function 'mapDataProviderTest' cannot be parallelized, reason: non-isolated test function, non-isolated data-provider function
```
Based on the warning, we can correct the code as follows.
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved

```ballerina
import ballerina/lang.runtime;
import ballerina/test;

isolated int a = 0;

@test:Config {
dataProvider: mapDataProvider
}
isolated function mapDataProviderTest(int value1, int value2, string fruit) returns error? {
test:assertEquals(value1, value2, msg = "The provided values are not equal");
runtime:sleep(0.1);
lock {
a = 8;
}
}

isolated function mapDataProvider() returns map<[int, int, string]>|error {
lock {
a = 10;
}
map<[int, int, string]> dataSet = {
"banana": [10, 10, "banana"],
"cherry": [5, 5, "cherry"],
"apple": [5, 5, "apple"],
"orange": [5, 5, "orange"]
};
return dataSet;
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ The formats below can be used for excluding.
$ bal test --test-report --code-coverage --coverage-format=xml --excludes='./generated'
```

Execute tests in parallel
Thevakumar-Luheerathan marked this conversation as resolved.
Show resolved Hide resolved

```
$ bal test --parallel
```

For more options of the test command, run the following.

```
Expand Down
11 changes: 8 additions & 3 deletions utils/learn-lm.json
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,14 @@
"url": "/learn/test-ballerina-code/execute-tests",
"id": "execute-tests"
},
{
"dirName": "Execute tests in parallel",
"level": 4,
"position": 11,
"isDir": false,
"url": "/learn/test-ballerina-code/execute-tests-in-parallel/",
"id": "execute-tests-in-parallel"
},
{
"dirName": "Define data-driven tests",
"level": 4,
Expand Down Expand Up @@ -872,8 +880,6 @@
}
]
},


{
"dirName": "other",
"level": 1,
Expand Down Expand Up @@ -1238,7 +1244,6 @@
}
]
},

{
"dirName": "slides",
"level": 1,
Expand Down