Applies to TM4J Server/Data Center 7.1, last modified on August 12, 2020

Saving time and effort by automating tasks can lead to great improvements through the development cycle, and testing is no exception. Test Management for Jira provides functionality that enables you to automate tasks that take considerable time to complete manually.

Using the REST API, you can automate tasks such as creating a test cycle from test cases that are associated to a list of Jira issues, creating folders for every sprint of all your Jira projects, or simply creating new test cases from a list of Jira issues. Many other tasks can be automated by writing your own scripts and utilizing the REST API.

Here are a few useful automation script examples that use Test Management for Jira’s REST API:

Learn more about Test Management for Jira’s API by reviewing the API documentation.

Create a test cycle with test cases associated to a list of issues

This script first retrieves the Jira issue specified in the JQL provided, followed by any test cases associated with the issue. A test cycle is then created with the set of test cases included.

JavaScript / Node.js

// Create test cycles from issues

const fetch = require('node-fetch');

class TestCaseCreator {
constructor(jiraSettings, jql, projectKey) {
this._jiraSettings = jiraSettings;
this._jql = jql;
this._projectKey = projectKey;
this._authString = 'Basic ' + Buffer.from(this._jiraSettings.user + ':' + this._jiraSettings.password).toString('base64');
}

    async createTestCases() {
        const issues = await this._searchIssues(this._jql);
        const linkedTestCaseKeys = await this._getLinkedTestCases(issues.map(issue => issue.key));
        await this._createTestCycle('Cycle from issues', linkedTestCaseKeys, this._projectKey);
    }

    async _searchIssues(jql) {
        const url = encodeURI(this._jiraSettings.url + '/rest/api/2/search?jql=' + jql);
        const response = await fetch(url, {headers: {'Authorization': this._authString}});
        if(response.status !== 200) throw 'Error searching for issues: ' + jql;
        let searchResults = await response.json();
        return searchResults.issues;
    }

    async _getLinkedTestCases(issueKeys) {
        const url = encodeURI(this._jiraSettings.url + '/rest/atm/1 .0/testcase/search?query=issueKeys IN ("' + issueKeys.join('", "') + '")');
        const response = await fetch(url, {headers: {'Authorization': this._authString}});
        if(response.status !== 200) throw 'Error searching for test cases: ' + issueKeys;
        let testCases = await response.json();
        return testCases.map(testCase => testCase.key);
    }

    async _createTestCycle(name, testCaseKeys, projectKey) {
        const request = this._buildRequest({
            name: name,
            projectKey: projectKey,
            items: testCaseKeys.map(key => {return {testCaseKey: key}})
        });
        const url = encodeURI(this._jiraSettings.url + '/rest/atm/1.0/testrun');
        const response = await fetch(url, request);
        if(response.status !== 201) throw 'Error creating test cycle: ' + name;
        const jsonResponse = await response.json();
        console.log('Test cycle created: ' + jsonResponse.key + ' - ' + name);
    }

    _buildRequest(body) {
        return {
            method: 'POST',
            body: JSON.stringify(body),
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': this._authString
            }
        };
    }
}

async function run() {
// Your settings
const settings = {
'url': '<<your-jira-url>>',
'user': '<<your-user>>',
'password': '<<your-password>>'
};

    const jql = '<<Some JQL e.g. project = PROJ>>';
    const projectKey = '<<A project key e.g. PROJ>>';
    await new TestCaseCreator(settings, jql, projectKey).createTestCases();
}

run();

Create a folder for each sprint available in the available board

This script first retrieves the board for your Jira project, followed by any sprints associated with the board. It then creates a test cycle folder for each of the sprints.

JavaScript / Node.js

// Create test cycle folders from sprints

const fetch = require('node-fetch');

class TestCycleFolderCreator {
constructor(jiraSettings, projectKey) {
this._jiraSettings = jiraSettings;
this._projectKey = projectKey;
this._authString = 'Basic ' + Buffer.from(this._jiraSettings.user + ':' + this._jiraSettings.password).toString('base64');
}

    async createFolders() {
        const board = await this._getBoardForProject(this._projectKey);
        const sprints = await this._getSprintsForBoard(board);
        for(let sprint of sprints) {
            await this._createTestCycleFolder(sprint.name, this._projectKey)
        }
    }

    async _getBoardForProject(projectKey) {
        const url = encodeURI(this._jiraSettings.url + '/rest/agile/1.0/board?projectKeyOrId=' + projectKey);
        const response = await fetch(url, {headers: {'Authorization': this._authString}});
        if(response.status !== 200) throw 'Error retrieving boards for project: ' + projectKey;
        let searchResults = await response.json();
        return searchResults.values[0];
    }

    async _getSprintsForBoard(board) {
        const url = encodeURI(this._jiraSettings.url + '/rest/agile/1.0/board/' + board.id + '/sprint');
        const response = await fetch(url, {headers: {'Authorization': this._authString}});
        if(response.status !== 200) throw 'Error retrieving sprints for board: ' + board.name;
        let searchResults = await response.json();
        return searchResults.values;
    }

    async _createTestCycleFolder(name, projectKey) {
        const reqHeadersObj = this._buildRequest({
            'projectKey': projectKey,
            'name': name,
            'type': 'TEST_RUN'
        });
        const url = encodeURI(this._jiraSettings.url + '/rest/atm/1.0/folder');
        const response = await fetch(url, reqHeadersObj);
        if(response.status !== 201) throw 'Error creating test cycle folder: ' + name;
        console.log('Created test cycle folder: ' + name);
    }

    _buildRequest(body) {
        return {
            method: 'POST',
            body: JSON.stringify(body),
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': this._authString
            }
        };
    }
}

async function run() {
// Your settings
const settings = {
'url': '<<your-jira-url>>',
'user': '<<your-user>>',
'password': '<<your-password>>'
};

    const projectKey = '<<A project key e.g. PROJ>>';
    await new TestCycleFolderCreator(settings, projectKey).createFolders();
}

run();

Create new test cases from a list of issues

This script first retrieves the Jira issues specified in the JQL provided, and then it creates a test case for each of these issues, using the Summary field values as the test case names.

JavaScript / Node.js

// Create test cases from issues

const fetch = require('node-fetch');

class TestCaseCreator {
constructor(jiraSettings, jql, projectKey) {
this._jiraSettings = jiraSettings;
this._jql = jql;
this._projectKey = projectKey;
this._authString = 'Basic ' + Buffer.from(this._jiraSettings.user + ':' + this._jiraSettings.password).toString('base64');
}

    async createTestCases() {
        const issues = await this._searchIssues(this._jql);
        for(let issue of issues) {
            await this._createTestCase(issue.fields.summary, issue.key, this._projectKey);
        }
    }

    async _searchIssues(jql) {
        const url = encodeURI(this._jiraSettings.url + '/rest/api/2/search?jql=' + jql);
        const response = await fetch(url, {headers: {'Authorization': this._authString}});
        if(response.status !== 200) throw 'Error searching for issues:' + jql;
        let searchResults = await response.json();
        return searchResults.issues;
    }

    async _createTestCase(name, issueLink, projectKey) {
        const request = this._buildRequest({
            name: name,
            projectKey: projectKey,
            issueLinks: [issueLink]
        });
        const url = encodeURI(this._jiraSettings.url + '/rest/atm/1.0/testcase');
        const response = await fetch(url, request);
        if(response.status !== 201) throw 'Error creating test case: ' + name;
        const jsonResponse = await response.json();
        console.log('Test case created: ' + jsonResponse.key + ' - ' + name);
    }

    _buildRequest(body) {
        return {
            method: 'POST',
            body: JSON.stringify(body),
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'Authorization': this._authString
            }
        };
    }
}

async function run() {
// Your settings
const settings = {
'url': '<<your-jira-url>>',
'user': '<<your-user>>',
'password': '<<your-password>>'
};

    const jql = '<<Some JQL e.g. project = PROJ>>';
    const projectKey = '<<A project key e.g. PROJ>>';
    await new TestCaseCreator(settings, jql, projectKey).createTestCases();
}

run();

See Also

Test Automation and API

Highlight search results