private void ImportProject(StreamWriter streamWriter, SpiraSoapService.SoapServiceClient spiraClient, TestLink testLinkApi) { try { streamWriter.WriteLine(String.Format("Importing Test Link project '{0}' to Spira...", this.testLinkProjectName)); //Get the project info from the TestLink API TestProject tlProject = testLinkApi.GetProject(this.testLinkProjectName); if (tlProject == null) { throw new ApplicationException(String.Format("Empty project data returned by TestLink for project '{0}' so aborting import", this.testLinkProjectId)); } RemoteProject remoteProject = new RemoteProject(); remoteProject.Name = tlProject.name; remoteProject.Website = tlProject.notes; remoteProject.Active = tlProject.active; //Reconnect and import the project spiraClient.Connection_Authenticate2(Properties.Settings.Default.SpiraUserName, Properties.Settings.Default.SpiraPassword, "TestLinkImporter"); remoteProject = spiraClient.Project_Create(remoteProject, null); streamWriter.WriteLine("New Project '" + remoteProject.Name + "' Created"); int projectId = remoteProject.ProjectId.Value; this.newProjectId = remoteProject.ProjectId.Value; } catch (Exception exception) { streamWriter.WriteLine("General error importing data from TestLink to Spira The error message is: " + exception.Message); throw; } }
private void ImportProject(StreamWriter streamWriter, SpiraSoapService.SoapServiceClient spiraClient, APIClient testRailApi) { try { streamWriter.WriteLine(String.Format("Importing Test Rail project {0} to Spira...", this.testRailProjectId)); //Get the project info from the TestRail API JObject project = (JObject)testRailApi.SendGet("get_project/" + this.testRailProjectId); if (project == null) { throw new ApplicationException(String.Format("Empty project data returned by TestRail for project '{0}' so aborting import", this.testRailProjectId)); } RemoteProject remoteProject = new RemoteProject(); remoteProject.Name = project["name"].Value <string>(); remoteProject.Website = project["url"].Value <string>(); remoteProject.Active = !project["is_completed"].Value <bool>(); //Reconnect and import the project spiraClient.Connection_Authenticate2(Properties.Settings.Default.SpiraUserName, Properties.Settings.Default.SpiraPassword, "TestRailImporter"); remoteProject = spiraClient.Project_Create(remoteProject, null); streamWriter.WriteLine("New Project '" + remoteProject.Name + "' Created"); int projectId = remoteProject.ProjectId.Value; this.newProjectId = remoteProject.ProjectId.Value; } catch (APIException exception) { streamWriter.WriteLine("Unable to access the TestRail API. The error message is: " + exception.Message); throw; } catch (Exception exception) { streamWriter.WriteLine("General error importing data from TestRail to Spira The error message is: " + exception.Message); throw; } }
/// <summary> /// This method is responsible for actually importing the data /// </summary> /// <param name="stateInfo">State information handle</param> /// <remarks>This runs in background thread to avoid freezing the progress form</remarks> public void ImportData(object stateInfo) { //First open up the textfile that we will log information to (used for debugging purposes) string debugFile = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\Spira_TestRail_Import.log"; StreamWriter streamWriter = File.CreateText(debugFile); try { streamWriter.WriteLine("Starting import at: " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString()); //Create the mapping hashtables this.testCaseMapping = new Dictionary <int, int>(); this.testSuiteMapping = new Dictionary <int, int>(); this.testSuiteSectionMapping = new Dictionary <int, int>(); this.testStepMapping = new Dictionary <int, int>(); this.usersMapping = new Dictionary <int, int>(); this.testRunStepMapping = new Dictionary <int, int>(); this.testRunStepToTestStepMapping = new Dictionary <int, int>(); this.testSetMapping = new Dictionary <int, int>(); this.testSetTestCaseMapping = new Dictionary <int, int>(); //Connect to Spira streamWriter.WriteLine("Connecting to Spira..."); SpiraSoapService.SoapServiceClient spiraClient = new SpiraSoapService.SoapServiceClient(); //Set the end-point and allow cookies string url = Properties.Settings.Default.SpiraUrl + ImportForm.IMPORT_WEB_SERVICES_URL; spiraClient.Endpoint.Address = new EndpointAddress(url); BasicHttpBinding httpBinding = (BasicHttpBinding)spiraClient.Endpoint.Binding; ConfigureBinding(httpBinding, spiraClient.Endpoint.Address.Uri); bool success = spiraClient.Connection_Authenticate2(Properties.Settings.Default.SpiraUserName, Properties.Settings.Default.SpiraPassword, "TestRailImporter"); if (!success) { string message = "Failed to authenticate with Spira using login: '******' so terminating import!"; streamWriter.WriteLine(message); streamWriter.Close(); //Display the exception message this.progressForm.ProgressForm_OnError(message); return; } //Connect to TestRail APIClient testRailApi = new APIClient(Properties.Settings.Default.TestRailUrl); testRailApi.User = Properties.Settings.Default.TestRailUserName; testRailApi.Password = Properties.Settings.Default.TestRailPassword; //1) Create a new project ImportProject(streamWriter, spiraClient, testRailApi); //2) Get the users and import - if we don't want to import user, map all TestRail users to single SpiraId int userId = -1; string newPassword = Properties.Settings.Default.NewUserPassword; if (!Properties.Settings.Default.Users) { RemoteUser remoteUser = new RemoteUser(); remoteUser.FirstName = "Test"; remoteUser.LastName = "Rail"; remoteUser.UserName = "******"; remoteUser.EmailAddress = "*****@*****.**"; remoteUser.Active = true; remoteUser.Approved = true; remoteUser.Admin = false; userId = spiraClient.User_Create(remoteUser, newPassword, "What was my default email address?", remoteUser.EmailAddress, PROJECT_ROLE_ID).UserId.Value; } ImportUsers(streamWriter, spiraClient, testRailApi, userId); //**** Show that we've imported users **** if (Properties.Settings.Default.Users) { streamWriter.WriteLine("Users Imported"); this.progressForm.ProgressForm_OnProgressUpdate(1); } //3) Get the releases and import if (Properties.Settings.Default.Releases) { ImportReleases(streamWriter, spiraClient, testRailApi); } //**** Show that we've imported releases **** streamWriter.WriteLine("Releases Imported"); this.progressForm.ProgressForm_OnProgressUpdate(2); //3-4) Import the test suites and test cases if (Properties.Settings.Default.TestCases) { ImportTestSuites(streamWriter, spiraClient, testRailApi); //**** Show that we've imported test cases and test steps **** streamWriter.WriteLine("Test Suites Imported"); this.progressForm.ProgressForm_OnProgressUpdate(3); ImportTestCases(streamWriter, spiraClient, testRailApi); //**** Show that we've imported test cases and test steps **** streamWriter.WriteLine("Test Cases and Custom Steps Imported"); this.progressForm.ProgressForm_OnProgressUpdate(4); } //5) Import the test plans (check for case import) if (Properties.Settings.Default.TestCases) { ImportTestPlans(streamWriter, spiraClient, testRailApi); //**** Show that we've imported test cases and test steps **** streamWriter.WriteLine("Test Plans Imported"); this.progressForm.ProgressForm_OnProgressUpdate(5); } //6) Import the test runs (have to have case as well!) if (Properties.Settings.Default.TestCases && Properties.Settings.Default.TestRuns) { ImportTestRuns(streamWriter, spiraClient, testRailApi); //**** Show that we've imported test cases and test steps **** streamWriter.WriteLine("Test Runs Imported"); this.progressForm.ProgressForm_OnProgressUpdate(6); } //**** Mark the form as finished **** streamWriter.WriteLine("Import completed at: " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString()); this.progressForm.ProgressForm_OnFinish(); //Close the debugging file streamWriter.Close(); } catch (Exception exception) { //Log the error streamWriter.WriteLine("*ERROR* Occurred during Import: '" + exception.Message + "' at " + exception.Source + " (" + exception.StackTrace + ")"); streamWriter.Close(); //Display the exception message this.progressForm.ProgressForm_OnError(exception); } }
/// <summary> /// This method is responsible for actually importing the data /// </summary> /// <param name="stateInfo">State information handle</param> /// <remarks>This runs in background thread to avoid freezing the progress form</remarks> public void ImportData(object stateInfo) { //First open up the textfile that we will log information to (used for debugging purposes) string debugFile = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\Spira_TestLink_Import.log"; StreamWriter streamWriter = File.CreateText(debugFile); try { streamWriter.WriteLine("Starting import at: " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString()); //Create the mapping hashtables this.testCaseMapping = new Dictionary <int, int>(); this.testSuiteMapping = new Dictionary <int, int>(); this.testSuiteSectionMapping = new Dictionary <int, int>(); this.testStepMapping = new Dictionary <int, int>(); this.usersMapping = new Dictionary <int, int>(); this.testRunStepMapping = new Dictionary <int, int>(); this.testRunStepToTestStepMapping = new Dictionary <int, int>(); this.testSetMapping = new Dictionary <int, int>(); this.testSetTestCaseMapping = new Dictionary <int, int>(); //Connect to Spira streamWriter.WriteLine("Connecting to Spira..."); SpiraSoapService.SoapServiceClient spiraClient = new SpiraSoapService.SoapServiceClient(); //Set the end-point and allow cookies string spiraUrl = Properties.Settings.Default.SpiraUrl + ImportForm.IMPORT_WEB_SERVICES_URL; spiraClient.Endpoint.Address = new EndpointAddress(spiraUrl); BasicHttpBinding httpBinding = (BasicHttpBinding)spiraClient.Endpoint.Binding; ConfigureBinding(httpBinding, spiraClient.Endpoint.Address.Uri); bool success = spiraClient.Connection_Authenticate2(Properties.Settings.Default.SpiraUserName, Properties.Settings.Default.SpiraPassword, "TestLinkImporter"); if (!success) { string message = "Failed to authenticate with Spira using login: '******' so terminating import!"; streamWriter.WriteLine(message); streamWriter.Close(); //Display the exception message this.progressForm.ProgressForm_OnError(message); return; } //Connect to TestLink string apiKey = Properties.Settings.Default.TestLinkApiKey; string testLinkUrl = Properties.Settings.Default.TestLinkUrl + Utils.TESTLINK_URL_SUFFIX_XML_RPC; TestLink testLink = new TestLink(apiKey, testLinkUrl); //1) Create a new project ImportProject(streamWriter, spiraClient, testLink); //**** Show progress **** streamWriter.WriteLine("Project Created"); this.progressForm.ProgressForm_OnProgressUpdate(1); //2) Import test suites //Get the test suites from the TestLink API List <TestSuite> testSuites = testLink.GetFirstLevelTestSuitesForTestProject(this.testLinkProjectId); ImportTestSuites(streamWriter, spiraClient, testLink, testSuites); //**** Show progress **** streamWriter.WriteLine("Imported Test Suites"); this.progressForm.ProgressForm_OnProgressUpdate(2); //**** Show progress **** streamWriter.WriteLine("Imported Test Cases and Steps"); this.progressForm.ProgressForm_OnProgressUpdate(3); //3) Import test cases and test steps ImportTestCasesAndSteps(streamWriter, spiraClient, testLink); //**** Show progress **** streamWriter.WriteLine("Completed Import"); this.progressForm.ProgressForm_OnProgressUpdate(4); //**** Mark the form as finished **** streamWriter.WriteLine("Import completed at: " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString()); this.progressForm.ProgressForm_OnFinish(); //Close the debugging file streamWriter.Close(); } catch (Exception exception) { //Log the error streamWriter.WriteLine("*ERROR* Occurred during Import: '" + exception.Message + "' at " + exception.Source + " (" + exception.StackTrace + ")"); streamWriter.Close(); //Display the exception message this.progressForm.ProgressForm_OnError(exception); } }
/// <summary> /// Imports test cases and associated steps /// </summary> private void ImportTestCasesAndSteps(StreamWriter streamWriter, SpiraSoapService.SoapServiceClient spiraClient, TestLink testLinkApi) { //Loop through all the mapped, imported test suites foreach (KeyValuePair <int, int> kvp in this.testSuiteMapping) { //Get the test cases from the TestLink API int testSuiteId = kvp.Key; int testFolderId = kvp.Value; streamWriter.WriteLine(String.Format("Getting test cases in test suite: {0}", testSuiteId)); List <TestCaseFromTestSuite> testCasesInSuite = testLinkApi.GetTestCasesForTestSuite(testSuiteId, true); if (testCasesInSuite != null) { foreach (TestCaseFromTestSuite testCaseInSuite in testCasesInSuite) { //Extract the user data int tlTestCaseId = testCaseInSuite.id; string tlTestCaseExternalId = testCaseInSuite.external_id; streamWriter.WriteLine(String.Format("Finding test case: {0} - {1}", tlTestCaseId, tlTestCaseExternalId)); //Get the actual test case object (with steps) try { TestCase testCase = testLinkApi.GetTestCase(tlTestCaseId); if (testCase != null) { streamWriter.WriteLine(String.Format("Importing test case: {0}", tlTestCaseId)); string description = ""; if (!String.IsNullOrEmpty(testCase.summary)) { description += "<p>" + testCase.summary + "</p>"; } if (!String.IsNullOrEmpty(testCase.preconditions)) { description += "<p>" + testCase.preconditions + "</p>"; } //Reauthenticate at this point, in case disconnected spiraClient.Connection_Authenticate2(Properties.Settings.Default.SpiraUserName, Properties.Settings.Default.SpiraPassword, "TestLinkImporter"); spiraClient.Connection_ConnectToProject(this.newProjectId); //Create the new SpiraTest test case RemoteTestCase remoteTestCase = new RemoteTestCase(); remoteTestCase.Name = testCase.name; remoteTestCase.Description = description; remoteTestCase.TestCaseTypeId = /* Functional */ 3; remoteTestCase.TestCaseStatusId = (testCase.active) ? /* Ready For Test */ 5 : /* Draft*/ 1; remoteTestCase.CreationDate = testCase.creation_ts; if (testCase.importance >= 1 && testCase.importance <= 4) { remoteTestCase.TestCasePriorityId = testCase.importance; } //We don't import the author currently //remoteTestCase.AuthorId = this.usersMapping[createdById.Value]; //Map to the folder remoteTestCase.TestCaseFolderId = testFolderId; int newTestCaseId = spiraClient.TestCase_Create(remoteTestCase).TestCaseId.Value; streamWriter.WriteLine("Added test case: " + tlTestCaseId); //See if we have any test steps for this test case if (testCase.steps != null && testCase.steps.Count > 0) { streamWriter.WriteLine("Adding " + testCase.steps.Count + " test steps to test case: " + tlTestCaseId); foreach (TestStep testStep in testCase.steps) { RemoteTestStep remoteTestStep = new RemoteTestStep(); remoteTestStep.Description = testStep.actions; remoteTestStep.ExpectedResult = testStep.expected_results; spiraClient.TestCase_AddStep(remoteTestStep, newTestCaseId); } streamWriter.WriteLine("Added test steps to test case: " + tlTestCaseId); } //Add to the mapping hashtables if (!this.testCaseMapping.ContainsKey(tlTestCaseId)) { this.testCaseMapping.Add(tlTestCaseId, newTestCaseId); } } } catch (Exception ex) { streamWriter.WriteLine(String.Format("Error importing test case {0}: {1} ({2})", tlTestCaseId, ex.Message, ex.StackTrace)); } } } } }