Forum Discussion

chandreshp's avatar
chandreshp
Occasional Contributor
10 years ago

TestComplete integration with TestRail

Hi, 



I am using TestRail to manage my Test suites and I am using TestComplete to perform automation testing of my application.





TestComplete allows to set log defects to JIRA. But does it provide any kind of API or Plugin which can help me to integrate TestComplete execution result to TestRail ? I mean is there any way in which I can update my test case result directly from TestComplete ?



Thanks,

Chandresh Parmar
  • schef's avatar
    schef
    New Contributor

    I implemented a solution (in JScript) using the .NET api bindings from the testrail website:

     

    // Note: this functionality depends on 3rd party .NET libraries that needed to be compiled by you. We downloaded the testrail .NET api bindings
    // from the testrail website, along with the Json.NET library. Using visual Studio 2010, we built the Gurock.TestRail library, referencing the Newtonsoft.Json
    // library. We built x86 and x64 versions using .NET 3.5. In this project, the libraries are stored in a folder next to the project, and have 
    // already been linked to the project via the CLR bridge.
    
    
    testrail = {};
    
    // Use these methods for updating test case statuses in TestRail
    // Use the methods testrail.passCase, testrail.failCase, testrail.blockedCase, and testrail.retestCase to add case results.
    // The methods require the run id and the case id
    // A run id in test rail is formatted like 'R4683'. Remove the letter R from the beginning and just supply the integer.
    // A case id in test rail is formatted like 'C866870'. Remove the letter C from the beginning and just supply the integer.
    //
    // Supplying the additionalFields json object is optional. The request fields can be found in the add_result method definition 
    // of the api at http://docs.gurock.com/testrail-api2/reference-results
    // e.g. {comment: '<A comment to be logged in the result record>', version: '<free form version info>'}
    
    testrail.passCase = function(runId, caseId, additionalFields) {
        testrail.addStatusAndResultForCase(runId, caseId, additionalFields, 1);
    };
    
    testrail.failCase = function(runId, caseId, additionalFields) {
        testrail.addStatusAndResultForCase(runId, caseId, additionalFields, 5);
    };
    
    testrail.blockedCase = function(runId, caseId, additionalFields) {
        testrail.addStatusAndResultForCase(runId, caseId, additionalFields, 2);
    };
    
    testrail.retestCase = function(runId, caseId, additionalFields) {
        testrail.addStatusAndResultForCase(runId, caseId, additionalFields, 4);
    };
    
    testrail.runIdAndCaseIdFromTestId = function(testId) {
        test = testrail.getTest(testId);
        caseId = test.Item('case_id').Value_2.m_value;
        runId = test.Item('run_id').Value_2.m_value;
        return {runId: runId, caseId: caseId};
    };
    
    
    // Support functions for the above functions. These do not need to be called directly outside of this file.
    
    testrail.addStatusAndResultForCase = function(runId, caseId, additionalFields, statusId) {
        additionalFields = additionalFields || {};
        additionalFields.status_id = statusId;
        testrail.addResultForCase(runId, caseId, additionalFields);
    };
    
    testrail.addResultForCase = function(runId, caseId, additionalFields) {
        dataObj = testrail.dataDictonary(additionalFields);
        testrail.sendPost("add_result_for_case/" + runId + "/" + caseId, dataObj);
    };
    
    testrail.getTest = function(testId) {
        result = testrail.sendGet('get_test/' + testId);
        return result;
    };
    
    testrail.sendPost = function(apiArgsAsString, dataDictionaryObj) {
        testrail.apiClient().SendPost(apiArgsAsString, dataDictionaryObj);
    };
    
    testrail.sendGet = function(apiArgumentString) {
        results = testrail.apiClient().SendGet(apiArgumentString);
        return results;
    };
    
    testrail.dataDictonary = function(jsonObj) {
        var dataD = dotNET.System_Collections.Hashtable.zctor();
        for (var key in jsonObj) {
            if (jsonObj.hasOwnProperty(key)) {
                dataD.Add(key, jsonObj[key]);
            }
        }
        return dataD;
    };
    
    testrail.apiClient = function() {
        var client = dotNET.Gurock_TestRail.APIClient.zctor("https://testrail.blahblah1234.com/testrail/"); 
    client.User = "bojack.horseman@blahblah1234.com";
    client.Password = "api_key_from_your_testrail_instance_instead_of_users_pwd";
    return client;
    };

    //TODO: add error handling
    //TODO: implement the add_results api call so we can do a bulk update instead of calling add_result_for_case for each case

    Usage:

     

    //USEUNIT TestRail
    
    function testUpdateTestRail() {
    testrail.retestCase(4683, 866867);
    testrail.passCase(4683, 866868, {version: 'Build 10.0.0.1234'});
    testrail.blockedCase(4683, 866869, {comment: 'Blocked due to JIRA-4321'}); testrail.failCase(4683, 866870, {comment: 'Failed. JIRA-5678 logged.', version: 'Build 10.0.0.1234'});
    }
    • cbeal's avatar
      cbeal
      New Member

      Can you tell me it your integration was successful?  I am looking at trying the same integration.

       

      Were you able to get results from Test Complete to automatically update TestRail?

       

      What was involved, what issues had to be overcome.

       

      Thanks!

    • leandropoblet's avatar
      leandropoblet
      Frequent Contributor
      Can I please get more information on how to get the library going?
      Specially the notes in the script can you clarify the steps to do it?

      // Note: this functionality depends on 3rd party .NET libraries that needed to be compiled by you. We downloaded the testrail .NET api bindings
      // from the testrail website, along with the Json.NET library. Using visual Studio 2010, we built the Gurock.TestRail library, referencing the Newtonsoft.Json
      // library. We built x86 and x64 versions using .NET 3.5. In this project, the libraries are stored in a folder next to the project, and have
      // already been linked to the project via the CLR bridge.

      Thank you
    • BenAtStrata's avatar
      BenAtStrata
      New Contributor

      Hello I am using this code to try out TestRail integration myself, however I'm having difficulties handling the object returned from TestRail. 

       

      Currently the only way I am able to retrieve data is using the methods you described:

       

      var caseId = jobject.Item('case_id').Value_2.m_value;
      var runId = jobject.Item('run_id').Value_2.m_value;

       

      Any way I try to read the data or keys outside of these two lines, I get an empty string.

       

      so a few questions:

      1) What type of object is this? (I originally thought JSON but I am unable to use JSON properties to convert to javascript object)

      2) Where does "Value_2.m_value" come from?

      3) How can I get the keys for 'Item(<key>)' for all items of this object?

       

      Thank you!

       

  • TanyaYatskovska's avatar
    TanyaYatskovska
    SmartBear Alumni (Retired)

    Hi Chandresh,


     


    Support for JIRA is implemented via TestComplete's Script Extension. It gets access to JIRA objects via its API. If TestRail provides REST API as well, I suppose you can extend the support and add the needed code to work with TestRail.


     

  • schef's avatar
    schef
    New Contributor

    Hello,

     

    Sorry I'm a bit late to the party here. I no longer use testcomplete and testrail, but I'll try to help where I can. 

     

    leandropoblet, you posted an image that had an exception message that pointed to the testrail script file, line 86, column 5. Can you please post the statement from that line? I'm guessing it's the 

    testrail.apiClient().SendPost(apiArgsAsString, dataDictionaryObj);

    line.

     

    Next, I would put a debug breakpoint on that statement, and then run the function that you've been testing with. Once TC stops at that line, use the Locals panel and/or the Evaluate dialog to get the apiArgsAsString value and dataDictionaryObj (may have to change the latter into a string or json object). Paste those values and we can go from there. My guess is that apiArgsAsString is not a valid string.

     

    Another place to check would be the client root endpoint is correct

    var client = dotNET.Gurock_TestRail.APIClient.zctor("https://testrail.blahblah1234.com/testrail/");
    • leandropoblet's avatar
      leandropoblet
      Frequent Contributor

      Hi schef, joseph_michaud and Colin_McCrae,

      Found the source of the problem thanks to schef's last reply and it has nothing to do with schef's scripts.

      TestRail address was incorrect although that wasn't the only problem. Also TestRail has an awkward way to reference test cases in a test run. Using the method add_result_for_case passing runId and caseId it's a bit tricky as the caseId in this case is the test case number (C) not the Test (T) from the test run.

      Yes as complicated as it sounds that's the source of the problem. So basically TestRail references a test case in a run using RunId + CaseId instead of RunId + TestId (which is generated for each test run).

      Thank you all for the good effort and support as it would have been impossible to get it working without you. Much appreciated.

      Cheers,
      Leo

      • leandropoblet's avatar
        leandropoblet
        Frequent Contributor
        Just FYI I'm folowing up on another threat regarding the get_case method as it returns Json but can't be accessed as such
  • chandreshp's avatar
    chandreshp
    Occasional Contributor
    Thanks for reply Tanya!



    I will have to look into TestComplete's Script Extension first and then I will try to access TestRail objects.



    Thanks,

    Chandresh Parmar
  • schef's avatar
    schef
    New Contributor

    Nice brainwave Colin_McCrae that is indeed how testrail works. If you know the unique case id, and run id, you can get the test id, which is the specific instance of the test case in the test run. It's a bit confusing, but allows you to put unique case ids in your test data or scripts in testcomplete. You can even create new test runs via the testrail api.

     

    leandropoblet let us know about that return json if you are having new issues.

     

    Glad this worked out, thanks everyone. Happy testing.

  • The functions are working but I would like to add more functions like adding runs or users.

     

    I tried to get results for getTest for a test run but when I try to output the result it is always blank.

     

    I believe the results are in JSON, but how does one handle the JSON result and output the result in Test Complete.