SDK to connect to the Zephyr Scale app using Zephyr Scale's Rest endpoints. Manage your communication and easily retrieve and publish test cases, test cycle and execution results to Zephyr Scale. You can integrate with you existing automation solution or process that will manage these process. Support both Server and Cloud hosted Zephyr Scale application. For more information on Cloud: https://support.smartbear.com/zephyr-scale-cloud/api-docs/ For more information on Server: https://support.smartbear.com/zephyr-scale-server/api-docs/v1/ The request and response objects are having proper DTOS (data transfer or model objects) defined within this package. How to use: //Connect to cloud hosted Zephyr Scale service var zService = new ZephyrScaleCloudService("app url", "user api token"); //Connect to server hosted Zephyr Scale service var zService = new ZephyrScaleOnPremService("app url", "username", "password"); //Get a test case by Key var testCase = zService.TestCasesGet("POC-T1"); //Create a new Test case var newTestCase = ZephyrOnPremService.TestCaseCreate(new TestCaseCreateRequest { ProjectKey = "PCO", Folder = "/Automation", Name = "Verify the integration between app and zyphr", IssueLinks = new[] { "PCO-1432", "PCO-23" }.ToList(), Owner = "peterjoseph", Labels = new[] { "Automation", "Integration", "Api" }.ToList(), Status = "Approved" });
$ dotnet add package ZephyrScale.Rest.SdkComprehensive C# SDK to connect to the Zephyr Scale app using Zephyr Scale's REST endpoints. Manage your communication and easily retrieve and publish test cases, test cycles, test executions, test plans, and execution results to Zephyr Scale. You can integrate with your existing automation solution or process that will manage these operations.
** Full Support** for both Server and Cloud hosted Zephyr Scale applications with complete API coverage.
** Latest Version Features:**
For more information on Zephyr Scale cloud REST endpoints: https://support.smartbear.com/zephyr-scale-cloud/api-docs/
For more information on Zephyr Scale server REST endpoints: https://support.smartbear.com/zephyr-scale-server/api-docs/v1/
The request and response objects have proper DTOs (data transfer or model objects) defined within this package with full JSON serialization support.
NuGet Package: https://www.nuget.org/packages/ZephyrScale.Rest.Sdk
//Connect to cloud hosted Zephyr Scale service
var zService = new ZephyrScaleCloudService("app url", "user api token");
//Connect to server hosted Zephyr Scale service
var zService = new ZephyrScaleOnPremService("app url", "username", "password");
//Get a test case by Key
var testCase = zService.TestCasesGet("POC-T1");
//Create a new Test case
var newTestCase = ZephyrOnPremService.TestCaseCreate(new TestCaseCreateRequest
{
ProjectKey = "PCO",
Folder = "/Automation",
Name = "Verify the integration between app and zyphr",
IssueLinks = new[] { "PCO-1432", "PCO-23" }.ToList(),
Owner = "peterjoseph",
Labels = new[] { "Automation", "Integration", "Api" }.ToList(),
Status = "Approved"
});
// Create a comprehensive test plan
var testPlan = await zService.TestPlanCreate(new TestPlanCreateRequest
{
ProjectKey = "PROJ",
Name = "Sprint 1 Test Plan",
Description = "Comprehensive testing for Sprint 1 features",
Owner = "test.manager@company.com"
});
// Retrieve test plans with advanced search
var plans = await zService.TestPlansGetFull(new TestSearchRequest
{
ProjectKey = "PROJ",
Query = "name ~ 'Sprint'"
});
// Update test execution with status and detailed results
var updatedExecution = await zService.TestExecutionUpdate("EXEC-123", new TestExecutionCreateRequest
{
StatusName = "Pass",
Comment = "All assertions passed successfully",
ExecutionTime = 45000,
ExecutedById = "automation.user@company.com"
});
// Manage test execution links to JIRA issues
var links = await zService.TestExecutionLinksGet("EXEC-123");
await zService.TestExecutionLinkCreate("EXEC-123", "JIRA-456");
// Create test environments for different stages
var stagingEnv = await zService.EnvironmentCreate(new EnvironmentCreateRequest
{
ProjectKey = "PROJ",
Name = "Staging Environment",
Description = "Pre-production testing environment"
});
// Update environment configurations
await zService.EnvironmentUpdate("ENV-123", new EnvironmentCreateRequest
{
Name = "Updated Staging Environment",
Description = "Enhanced staging environment with new features"
});
// Create recursive folder structure in one call
var folder = await zService.FolderCreateRecursive("PROJ", "/Automation/API/Integration/Critical");
// Get folders with full path information
var foldersWithPaths = await zService.FolderWithFullPath("PROJ");
foreach (var folder in foldersWithPaths)
{
Console.WriteLine($"Folder: {folder.Name}, Full Path: {folder.FullPath}");
}
// Link test cases to JIRA issues
await zService.TestCaseLinkCreate("TC-123", "JIRA-456");
// Link test cycles to JIRA issues
await zService.TestCycleLinkCreate("CYCLE-789", "JIRA-456");
// Link test executions to JIRA issues (NEW)
await zService.TestExecutionLinkCreate("EXEC-123", "JIRA-456");
// Get all issue links for comprehensive traceability
var testCaseLinks = await zService.IssueLinksTestCases("JIRA-456");
var testCycleLinks = await zService.IssueLinksTestCycles("JIRA-456");
var testExecutionLinks = await zService.IssueLinksTestExecutions("JIRA-456"); // NEW
*GetFull methods support advanced predicate-based searching - TestCaseById
- TestCasesByNames
- TestCasesByNamesInFolder
- TestCaseByIdsInFolder
- TestCaseByIds
- TestCaseByTestCaseName
- TestCaseGetTopNInFolder
- TestCaseGetTopN
- TestCaseByJql
- TestCaseCreate
- TestCaseUpdate
- TestCaseGetCustomMetadata
- TestCycleGetById
- TestCycleGetByKey
- TestCycleGetByKey
- TestCycleGetByName
- TestCycleGetByName
- TestCycleGetByProjectInFolder
- TestCycleGetByFolder
- TestCycleGetByProjectKeys
- TestCycleGetByJql
- TestCycleCreate
- TestExecutionResultCreateByTestCaseInTestCycle
- TestExecutionResultUpdateByTestCaseInTestCycle
- TestExecutionResultCreateByTestCycle
- TestExecutionResultGetByTestCycle
- FolderCreate
- ProjectsInTestGet
- ProjectsInJiraGet
There are some level of custom customization available on the service that can be passed on via the constuctor.
A scenario where you have network issues and you want to retry operation, then try this
//Connect to cloud hosted Zephyr Scale service
var zService = new ZephyrScaleCloudService("app url", "user api token",
requestRetryTimes: 10,
timeToSleepBetweenRetryInMilliseconds: 1500,
assertResponseStatusOk: true,
listOfResponseCodeOnFailureToRetry: new System.Net.HttpStatusCode [] { System.Net.HttpStatusCode.ProxyAuthenticationRequired },
retryOnRequestTimeout: false
);
The above will apply an automatic retry of a maximum 20 times, giving itself a break of 1500 milliseconds between each request made to Zeyhpr that fails with a response code of HttpStatusCode.ProxyAuthenticationRequired
With the cloud version there are some limitations on the folder, where the service by default
FolderCreateRecursive - this option will create the full path and also checks if the folder already exists on any level of the path. For example, '/Automation/A/B/C', this method will create the full path in a single request and also if any of the folder available will be skipped and only required will be created
FolderWithFullPath - this option will return you the list of folder but along with that, one of the additional property on the model is "FullPath", that build the full path of each folder in the list
var testcase = zService.TestCaseById(testCaseId).ToTestCaseUpdate();
testcase.CustomFields.YouCustomFieldName = "YourCustomFieldValue";
zService.TestCaseUpdate(testCaseId, new TestCaseCreateRequest { CustomFields = testcase.CustomFields });
Proxy_IsProxyRequired: Determines whether proxy is required
Configurations.JiraZephyrProxyConfigName: Name of the proxy key that will be used as a reference, you can have multiple proxy information with different keys
Proxy_{Configurations.JiraZephyrProxyConfigName}_Host: Proxy host url
Proxy_{Configurations.JiraZephyrProxyConfigName}_Port: Proxy port
Proxy_{Configurations.JiraZephyrProxyConfigName}_ByPassProxyOnLocal: true/false based on whether you want to by pass porxy on local
Proxy_{Configurations.JiraZephyrProxyConfigName}_UseDefaultCredentials: true/false based on whether you want to use the defaul creds
Proxy_{Configurations.JiraZephyrProxyConfigName}_UseOnlyInPipeline: true/false (upcoming feature), for now keep it false, this wil help in using the proxy only to be used in the CI pipelines or remote machines
Proxy_{Configurations.JiraZephyrProxyConfigName}_UsernameEnvironmentKeyName: Does not hold the username instead you need to create an environment variables which will hold the username to the proxy. The value for this is the [key] name that is used in the environment variable. The process will automatically fetch the value during runtime
Proxy_{Configurations.JiraZephyrProxyConfigName}_PasswordEnvironmentKeyName: Does not hold the password instead you need to create an environment variables which will hold the password to the proxy. The value for this is the [key] name that is used in the environment variable. The process will automatically fetch the value during runtime
public static void EnableProxyOnJiraZephyrService()
{
if (Configurations.RequestProxyIsEnabled)
{
Pj.Library.PjUtility.EnvironmentConfig.AppSettingsConfigData.AddOrUpdate("Proxy_IsProxyRequired", Configurations.RequestProxyIsEnabled.ToString());
Pj.Library.PjUtility.EnvironmentConfig.AppSettingsConfigData.AddOrUpdate($"Proxy_{Configurations.JiraZephyrProxyConfigName}_Host", Configurations.RequestProxyHost);
Pj.Library.PjUtility.EnvironmentConfig.AppSettingsConfigData.AddOrUpdate($"Proxy_{Configurations.JiraZephyrProxyConfigName}_Port", Configurations.RequestProxyPort.ToString());
Pj.Library.PjUtility.EnvironmentConfig.AppSettingsConfigData.AddOrUpdate($"Proxy_{Configurations.JiraZephyrProxyConfigName}_ByPassProxyOnLocal", Configurations.RequestProxyByPassProxyOnLocal.ToString());
Pj.Library.PjUtility.EnvironmentConfig.AppSettingsConfigData.AddOrUpdate($"Proxy_{Configurations.JiraZephyrProxyConfigName}_UseDefaultCredentials", Configurations.RequestProxyUseDefaultCredentials.ToString());
Pj.Library.PjUtility.EnvironmentConfig.AppSettingsConfigData.AddOrUpdate($"Proxy_{Configurations.JiraZephyrProxyConfigName}_UseOnlyInPipeline", Configurations.RequestProxyUseOnlyInPipeline.ToString());
Pj.Library.PjUtility.EnvironmentConfig.AppSettingsConfigData.AddOrUpdate($"Proxy_{Configurations.JiraZephyrProxyConfigName}_UsernameEnvironmentKeyName", "Request.Proxy.Username");
Pj.Library.PjUtility.EnvironmentConfig.AppSettingsConfigData.AddOrUpdate($"Proxy_{Configurations.JiraZephyrProxyConfigName}_PasswordEnvironmentKeyName", "Request.Proxy.Password");
}
}
// Create comprehensive test plans
var testPlan = await zService.TestPlanCreate(new TestPlanCreateRequest
{
ProjectKey = "PROJ",
Name = "Sprint 1 Test Plan",
Description = "Comprehensive testing for Sprint 1 features"
});
// Retrieve and search test plans
var plans = await zService.TestPlansGetFull(new TestSearchRequest
{
ProjectKey = "PROJ"
});
// Update test execution status and metadata
var updatedExecution = await zService.TestExecutionUpdate("EXEC-123", new TestExecutionCreateRequest
{
StatusName = "Pass",
Comment = "All assertions passed successfully",
ExecutionTime = 45000
});
// Manage test execution links
var links = await zService.TestExecutionLinksGet("EXEC-123");
await zService.TestExecutionLinkCreate("EXEC-123", "JIRA-456");
// Create and manage test environments
var environment = await zService.EnvironmentCreate(new EnvironmentCreateRequest
{
ProjectKey = "PROJ",
Name = "Staging Environment",
Description = "Pre-production testing environment"
});
// Update existing environments
await zService.EnvironmentUpdate("ENV-123", updateRequest);
[JsonProperty] attributes for all DTOs// All services are thoroughly tested with real API validation
[Test]
public async Task Should_Create_And_Retrieve_TestPlan()
{
// Create test plan
var created = await _service.TestPlanCreate(request);
// Verify with separate GET request (verification fetch pattern)
var retrieved = await _service.TestPlanGet(created.Key);
// Comprehensive validation
Assert.AreEqual(request.Name, retrieved.Name);
Assert.IsTrue(retrieved.Project.Id > 0);
}
Testing Innovations:
[JsonProperty] attributes for all DTOs// NEW: Test Plans Service
var testPlan = await zService.TestPlanCreate(request);
var plans = await zService.TestPlansGetFull(searchRequest);
// NEW: Test Execution Updates
var updated = await zService.TestExecutionUpdate("EXEC-123", updateRequest);
// NEW: Environment Management
var env = await zService.EnvironmentCreate(envRequest);
await zService.EnvironmentUpdate("ENV-123", updateRequest);
// NEW: Enhanced Issue Linking
await zService.TestExecutionLinkCreate("EXEC-123", "JIRA-456");
var links = await zService.IssueLinksTestExecutions("JIRA-456");
*GetFull methods support advanced filteringTest Framework Integration Modules
Advanced Control Features
Business Logic Enhancements
Performance & Scalability
Transformation Achievement: From 74% test failure rate to 100% test success rate!
The ZephyrScale.RestApi SDK is now the most comprehensive, reliable, and feature-complete C# wrapper for Zephyr Scale Cloud API available.