- Zephyr Scale Server documentation
- Test Automation
- Migration Scripts
Migration Scripts
When migrating complex sets of data from a different test management tool or Excel document, Zephyr Scale’s self-service import options may not meet your specific needs. In this event, we have a REST API with an extensive list of endpoints for tasks such as creating new test results and retrieving test cases. This allows you to seamlessly import your data into Zephyr Scale by pulling data from a file source, making any relevant changes, and then using the API to push the data to Zephyr Scale.
The following sections present sample migration scripts that use Zephyr Scale’s REST API:
Migrate test cases with custom fields
Migrate test cases with attachments
Migrate test-execution results
Migrate test cases with custom fields
This script takes a list of test cases with custom fields and creates new test cases in Zephyr Scale that include the custom fields.
Note
Custom fields must be created in Zephyr Scale prior to running the migration script.
// Migrate test cases with custom fieldsconst fetch = require('node-fetch'); class TestCaseMigrator { constructor(jiraSettings, testCasesToMigrate) { this._jiraSettings = jiraSettings; this._testCasesToMigrate = testCasesToMigrate; this._authString = 'Basic ' + Buffer.from(this._jiraSettings.user + ':' + this._jiraSettings.password).toString('base64'); } async migrateTestCases() { for(let testCase of this._testCasesToMigrate) { await this._createTestCase(testCase); } } async _createTestCase(testCase) { const request = this._buildRequest(testCase); 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: ' + testCase.name; const jsonResponse = await response.json(); console.log('Test case created: ' + jsonResponse.key + ' - ' + testCase.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>>'; // These test cases could have been read from any source // and transformed to have this exact format. Custom fields // need to exist prior to running this script const testCasesToMigrate = [{ 'projectKey': projectKey, 'name': 'First test case', 'folder': '/Import from legacy system', 'customFields': { 'A checkbox custom field': true, 'A number custom field': 12, 'A text custom field': 'Some text here' } }, { 'projectKey': projectKey, 'name': 'Another test case', 'folder': '/Import from legacy system', 'customFields': { 'A user custom field': 'my.user.key', 'A decimal number custom field': 1.2, 'A select list custom field': 'This is the option label' } }]; await new TestCaseMigrator(settings, testCasesToMigrate).migrateTestCases(); } run();
Migrate test cases with attachments
This script takes a list of test cases with attachments and creates new test cases in Zephyr Scale with the attachments included.
// Migrate test cases with attachmentconst fetch = require('node-fetch'); const fs = require('fs'); const FormData = require('form-data'); class TestCaseMigrator { constructor(jiraSettings, testCasesToMigrate) { this._jiraSettings = jiraSettings; this._testCasesToMigrate = testCasesToMigrate; this._authString = 'Basic ' + Buffer.from(this._jiraSettings.user + ':' + this._jiraSettings.password).toString('base64'); } async migrateTestCases() { for(let testCase of this._testCasesToMigrate) { const filePath = testCase.attachment; delete(testCase.attachment); const testCaseKey = await this._createTestCase(testCase); await this._uploadAttachment(testCaseKey, filePath); } } async _createTestCase(testCase) { const request = this._buildRequest(testCase); const url = encodeURI(this._jiraSettings.url + '/rest/atm/1.0/testcase'); const response = await fetch(url, request); const jsonResponse = await response.json(); if(response.status !== 201) throw 'Error creating test case: ' + testCase.name; console.log('Test case created: ' + jsonResponse.key + ' - ' + testCase.name); return jsonResponse.key; } async _uploadAttachment(testCaseKey, filePath) { const formData = new FormData(); formData.append('file', fs.createReadStream(filePath)); const request = { method: 'POST', body: formData, headers: formData.getHeaders() }; request.headers.Authorization = this._authString; const url = encodeURI(this._jiraSettings.url + '/rest/atm/1.0/testcase/' + testCaseKey + '/attachments'); const response = await fetch(url, request); if(response.status !== 201) throw 'Error uploading attachment ' + filePath + ' to test case ' + testCaseKey; console.log('Attachment uploaded: ' + testCaseKey + ' - ' + filePath); } _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>>'; // These test cases could have been read from any source // and transformed to have this exact format. const testCasesToMigrate = [{ 'projectKey': projectKey, 'name': 'Test case with attachment', 'attachment': './aDocument.pdf' }, { 'projectKey': projectKey, 'name': 'Another test case with attachment', 'attachment': './anImage.png' }]; await new TestCaseMigrator(settings, testCasesToMigrate).migrateTestCases(); } run();
Migrate test-execution results
This script takes a list of test cases and creates a new test case in Zephyr Scale for each one, prior to creating any executions related to any test case.
// Migrate test cases with test executionsconst fetch = require('node-fetch'); class TestCaseMigrator { constructor(jiraSettings, testCasesToMigrate) { this._jiraSettings = jiraSettings; this._testCasesToMigrate = testCasesToMigrate; this._authString = 'Basic ' + Buffer.from(this._jiraSettings.user + ':' + this._jiraSettings.password).toString('base64'); } async migrateTestCases() { for(let testCase of this._testCasesToMigrate) { await this._createTestCase(testCase); } } async _createTestCase(testCase) { const executions = testCase.executions; delete(testCase.executions); const request = this._buildRequest(testCase); 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: ' + testCase.name; const jsonResponse = await response.json(); console.log('Test case created: ' + jsonResponse.key + ' - ' + testCase.name); await this._createTestExecutions(testCase.projectKey, jsonResponse.key, executions); } async _createTestExecutions(projectKey, testCaseKey, executions) { for(let execution of executions) { execution.projectKey = projectKey; execution.testCaseKey = testCaseKey; const request = this._buildRequest(execution); const url = encodeURI(this._jiraSettings.url + '/rest/atm/1.0/testresult'); const response = await fetch(url, request); if(response.status !== 201) throw 'Error creating test execution: ' + testCaseKey; console.log('Test execution created: ' + testCaseKey); } } _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>>'; // These test cases could have been read from any source // and transformed to have this exact format. const testCasesToMigrate = [{ 'projectKey': projectKey, 'name': 'Test case with executions', 'executions': [{ 'status': 'Pass', 'environment': 'Firefox', 'executionTime': 180000, 'executionDate': '2018-12-13T15:22:00-0300', }, { 'status': 'Fail', 'environment': 'Chrome', 'executionTime': 365000, 'executionDate': '2018-12-13T18:11:00-0300', }] }, { 'projectKey': projectKey, 'name': 'Test case with simpler executions', 'executions': [{ 'status': 'Pass' }, { 'status': 'Fail' }] }]; await new TestCaseMigrator(settings, testCasesToMigrate).migrateTestCases(); } run();
See Also
Test Automation and APITest Automation and API