Updating test results in QC using the QC OTA API explained

Yesterday I cleaned up and posted my example QCIntegration utility on GitHub.

While it works as a standalone tool, some people might not want to wade through the code to understand or modify it. So today, I’m going to try to explain how the OTA API works by recreating the steps as a blog post with explanation in a simple script.

I’ll start with an example using C# and then give an equivalent Python example. I’ll use the same scenario, updating test case results in QC, but if requested, I can also show how to get test steps from a test plan, or read & update defects in QC using the OTA library.

First, create a new project in Visual Studio (or SharpDevelop). You’ll need to add the OTAClient.dll as a reference. It is a COM library and contains the single interface TDConnection.

When searching for the library name it is called the “OTA COM Type Library”. The package is “TDApiOle80.” Since it is a COM library, it needs to use an interop for C#, but this is handled automatically by the IDE.

using TDAPIOLELib;
TDConnection conn = new TDConnection();

Now, let’s create a connection to your Quality Center server. You’ll need to know the URL of your QC Server and have valid login credentials with access to an existing Domain and Project.

Assuming you have quality center installed on your local machine (not a typical setup) you might have the following setup:

string qcUrl = "http://localhost:8080/qcbin";
string qcDomain = "oneshore";
string qcProject = "qa-site";
string qcLoginName = "aaron";
string qcPassword = "secret";

Note: I do not use this same password for my bank account

There are several ways to log in, but I’ll use the simplest here:

tdConn.ConnectProjectEx(qcDomain, qcProject, qcLoginName, qcPassword);

Now you need to find your test sets that need updated. I typically use folder structure that goes something like:

Project – Iteration – Component – Feature

It’s a bit convoluted but here’s the code to get a testSet:

string testFolder = "Root\QASite\Sprint5\Dashboard\Recent Updates";
string testSet = "Recent Updates - New Defects Logged";

TestSetFactory tsFactory = (TestSetFactory)tdConn.TestSetFactory;
TestSetTreeManager tsTreeMgr = (TestSetTreeManager)tdConn.TestSetTreeManager;
TestSetFolder tsFolder = (TestSetFolder)tsTreeMgr.get_NodeByPath(testFolder);
List tsList = tsFolder.FindTestSets(testSetName, false, null);

The parameters for FindTestSets are a pattern to match, whether to match case, and a filter. Since I’m looking for a specific test set, I don’t bother with the other two parameters.
You could easily get a list of all test sets that haven’t been executed involving the recent updates feature by substituting this line:

List tsList = tsFolder.FindTestSets("recent updates", true, "status=No Run");

Now we want to loop through the test set and build a collection of tests to update. Note that we might have more than one test set in the folder and one or more subfolders as well:

foreach (TestSet testSet in tsList)
	TestSetFolder tsFolder = (TestSetFolder)testSet.TestSetFolder;
	TSTestFactory tsTestFactory = (TSTestFactory)testSet.TSTestFactory;
	List tsTestList = tsTestFactory.NewList("");

And finally, update each test case status:

    foreach (TSTest tsTest in tsTestList)
        Run lastRun = (Run)tsTest.LastRun;

        // don't update test if it may have been modified by someone else
        if (lastRun == null)
            RunFactory runFactory = (RunFactory)test.RunFactory;
            String date = DateTime.Now.ToString("yyyyMMddhhmmss");
            Run run = (Run)runFactory.AddItem("Run" + date);
            run.Status = "Pass";
    } // end loop of test cases

} // end outer loop of test sets

Of course you might want to add your actual test results. If you have a dictionary of test names and statuses, you can simply do this:

Dictionary testResults = new Dictionary();
testResults.Add("New defects in Recent Updates are red", "Pass");
testResults.Add("Resolved defects in Recent Updates are green", "Pass");
testResults.Add("Reopened defects in Recent Updates are bold", "Fail");

if (testResults.ContainsKey(tsTest.TestName))
    string status = testResults[tsTest.TestName];
    recordTestResult(tsTest, status);

That’s all for now. I’ll translate the example into Python tomorrow, but you’ll see it’s really quite straightforward.


93 thoughts on “Updating test results in QC using the QC OTA API explained

  1. Pingback: Running NUnit tests programmatically « Fiji Ecuador Seattle Greece Montana

  2. Pingback: Selenium QC integration summary « Fiji Ecuador Seattle Greece Montana

  3. Pingback: Selenium QC integration update « Fiji Ecuador Seattle Greece Montana

  4. Hi Aaron,
    Thanks a lot for your post.It was really helpful for me as I am just entering in the QC world.I have 4 custom fields in QC test instance properties ie OS,Locale,prod version and IE version. I am trying to do something as below but getting an error saying “Field not present”.

    RunFactory runFactory = (RunFactory)test.RunFactory;
    String date = DateTime.Now.ToString(“yyyyMMddhhmmss”);
    Run run = (Run)runFactory.AddItem(“Run” + date);
    run[“IE Version”]=”IE 9.0″;
    run[“OS”]=”Win 7 SP1 32 bit”;
    run[“Prod Version”]=”33″;
    run.Status = “Pass”;

  5. Hi,
    I have lots of manul test cases under a test set.After executing them I have to update the results in QC. For that I am using your blog to write an exe for the same.But, in my case when I update the test status in QC manully I am asked to enter OS,IE version,Locale,Prod version. How can I add these information to the current run.I am trying to do something like this but getting error saying invalid field.
    Could you help?

    foreach (TSTest tsTest in tsTestList)
    Run lastRun = (Run)tsTest.LastRun;

    string g = lastRun[“Browser Version”].ToString(); //error
    RunFactory runFactory = (RunFactory)tsTest.RunFactory;
    String date = DateTime.Now.ToString(“yyyyMMddhhmmss”);
    Run run = (Run)runFactory.AddItem(“Run_” + date);

    run.Status = status;
    run[“Browser Version”] = “IE 9.x”; //error

    Console.WriteLine(status + ” ” + tsTest.Name);

    • Hi,
      The above issue has been resolved. Now, the isue is using above approach only the main test case is marked as “passed”, but if we open the test run instance and click on the run created by the code ,it is missing all the test steps.On the other hand if we do the same thing manually all the test steps along with the test case are marked as “passed”.

      • Hi An,
        You can do something like this to solve the issue:
        1. Retreive all the fields
        RunFactory rf = (RunFactory)tsTest.RunFactory;
        List allfields = rf.Fields;
        2. Compare allfields list elements to what you want and store them in a variable
        TDField item1 = null;
        foreach (TDField item in allfields)
        if ((((FieldProperty)item.Property).UserLabel).Equals(“Browser Version”))
        item1 = item;

        3. At last update it with your value
        run[item1.Name] = “IE 9.0”;

        Hope this will help.

    • Sorry, I don’t know VBScript. The COM objects and function calls should translate directly to VBScript. I’d welcome someone who knows VBscript to add a version though.

  6. How can I acheive the below:
    the isue in using above approach is that only the main test case is marked as “passed”, but if we open the test run instance in QC and click on the run created by the code ,it is missing all the test steps.On the other hand if we do the same thing manually all the test steps along with the test case are marked as “passed”.

    Thanks in advance for your help.

    • I think this should help.

      RunFactory runFactory = (RunFactory)tstest.RunFactory;
      string date = DateTime.Now.ToString(“yyyyMMddhhmmss”);
      Run run = (Run)runFactory.AddItem(“Run” + date);


      run.Status = “Passed”;

      StepFactory rsFactory = (StepFactory)run.StepFactory;

      dynamic rdata_stepList = rsFactory.NewList(“”);
      var rstepList = (TDAPIOLELib.List)rdata_stepList;

      foreach (dynamic rstep in rstepList)
      rstep.Status = “Passed”;

  7. Its a great post, preciseley what I was looking for.
    Everything is working fine for me. I can later open the run result from QC. But when I close the test run QC logs out. Any idea?

      • No, we can have “multiple login per user” at a time. I am still stuck with this problem. It seems run created is in locked state. If we refresh the run from QC before opening the result, things work fine. If we dont refresh, QC trashes. I eagerly wait for your expert feedback. Thanks

  8. Hi fijiaaron
    Thanks it is really helpful.
    Could you please explain how to do same thing by selenium like
    first which dll files need to convert to JAR’s ?
    Then how to write such code.

  9. Hi Aaron,

    I have a similar requirement :

    I am writting a function which accepts test case id and result and I need to update the result in HPQC. Can you please provide me the modified version of above program to match my requirement ?


  10. Hi fijiaaron,
    I am trying to Intrgrate selenium results (Junit) to Qc using Python. i am very new to this. Can you help me in this.

  11. Hi fijiaaron,
    I am trying to Intrgrate selenium results (Junit) to Qc using Python. i am very new to this. Can you please help me in this.

  12. i am trying to update the testcases in testset using avobe code but not able to get the result.Could you please help me on?

  13. Hey Aaron, why come back? I’m looking for the/an API which will tell me how many user’s are currently logged onto a specific DOMAIN/Project but am having no luck? Do you know, is there such a monster? Thanks…

    • Unfortunately, I do not know of a way to list the users logged in to Quality Center through the OTA API. Sounds like that would require admin access, and I’m not sure the OTA API covers that very well. You could probably do a custom query against the database, but that’s all I can think of.

  14. Hi Arron,

    Great article, I have a query regarding the way of retrieving a value from specific columns from a particular test

    I would like to do something like this:

    DataTable dtTests = new DataTable(“Test Cases”);
    dtTests.Columns.Add(“Name”, Type.GetType(“System.String”));
    dtTests.Columns.Add(“Planned Date”, Type.GetType(“System.DateTime”));
    dtTests.Columns.Add(“Execution Date”, Type.GetType(“System.DateTime”));
    dtTests.Columns.Add(“Status”, Type.GetType(“System.String”));


    foreach (TestSet tst in listTestSet)
    TestSetFolder tsfldr = (TestSetFolder)tst.TestSetFolder;
    TSTestFactory tstf = (TSTestFactory)tst.TSTestFactory;
    testList = (List)tstf.NewList(“”);

    testFieldList = (List)tstf.Fields;

    foreach (TSTest tdf in testFieldList)
    //Retrieve specific field values of the current test e.g. Execution Time, Planned Date and store as a single dataset row
    dtTests.Rows.add(tdf.Name, tdf.Field[“TC_PLAN_SCHEDULING_DATE”], tdf.Field[“TC_EXEC_DATE”], tdf.Status);

    However the TSTest.Field property doesn’t seem to exist (at least for c#) – any advice would be greatly appreicated.


  15. Hi Araon,
    I was wondering if you can send me the Python code for the example above, I really appreciate it!


  16. Hi,
    I don’t write very well english because of i’m from a frensh country. I was interreded n’y this post about ota api usage. Have you an experience about java or python usine this api? How can i find java api for ota 11, and how can i create a bug using api.
    Thanks in advance.

  17. Hi Aaron,

    Trying to Run ALM Performance Test through OTA API scheduler.
    I was able to Connect to HP ALM PC using C#. But Would appreciate if there any Example C# Code to Run a Performance Test .


    • Just Trying to paste similar thing that I tried in VBscript

      Set TestSetFactory = TDConnection.TestSetFactory
      Set TestSetTreeManager = TDConnection.TestSetTreeManager
      Set TSetFolder = TestSetTreeManager.NodeByPath(StrTestSetLoc)
      Set TestSetList = TSetFolder.FindTestSets(strTestName)
      Set TestSet = TestSetList.Item(1)
      Set Scheduler = TestSet.StartExecution(“”)
      Scheduler.RunAllLocally = True

      Need advice on Equivalent C# code


      • Converting to C# is pretty straightforward if you know the language. It’s mostly just a matter of translating the API.

        The first part of your code is actually explained in the post above. Here’s how it looks in C#

        TestSetFactory testSetFactory = connection.TestSetFactory;
        TestSetTreeManager testSetTreeManager = connection.TestSetTreeManager;

        TestSetFolder testSetFolder = (TestSetFolder) testSetTreeManager.NodeByPath[testSetPath];
        List testSetList = testSetFolder.FindTestSets(testSetName);
        TestSet testSet = testSetList[0];

        TSScheduler scheduler = testSet.StartExecution("");
        scheduler.RunAllLocally = true;

        You can see a working example that runs the Quality Center Scheduler here: https://gist.github.com/4121324

    • Sunny-

      Sorry, I haven’t used HP Performance Center. Looks like a “cloud” version of LoadRunner — is that right? It would be interesting to learn more about.


      • Hi Aaron,
        Firstly thank you for the reply.

        HP Performance center is an advanced web based performance test management tool. At a higher level the traditional Loadrunner Components are wrapped in Web Front End. It can be treated as SAAS , However I have not come across a scenario where HP-PC is hosted on a Cloud.

        Usually the Software is internally hosted and has licensing structure more simplified compared to standalone Loadrunner.

        Generally suitable for big Organizations, Advantages:
        A. (similar to Quality Center) It can be centrally Administered,
        B. Anyone in Organization can Gain access,
        C. Need not install multiple copies of standalone Loadrunner on Performance Testers Machines,
        D. Hardware Resources ( Load Generators, Controllers) can be shared across different Testing Teams.

        HP Performance Center can be merged with HP ALM11.0 which basically integrates Functional Testing, Performance Testing, Developer Management and Defect Management.


  18. Pingback: Executing Tests in Quality Center using the OTA API « Fijiaaron in Ecuador

  19. Arron, nice work here.
    I am trying to update the most recent status of a test run. I have both the test ID and the Cycle ID, how do I set this up to insert a new run record?
    I want to ‘change’ the status of the test to “rerun” under certain conditions.
    Thank you

  20. Hi Aaron,
    Thanks a lot for your post. It was really helpful for me as I am just entering in the QC world. I’m a JAVA guy and looking into interact with QC11 through java. Question here is do I need any JARs to access QC?

      • I haven’t used QC 11 or worked with the web service API, though I’d love to look at it. I do not currently have access to a QC 11 install, but I’m available for consulting work if you’re interested in hiring me to help with your system.

  21. Hi Aaron,

    I have a regression test set which contains 3000 tests. If I have to update 2600th test case only, I can put a if condition in inner FOR loop and update it. but as per the code, inner for loop will be run 3000 times which leads to large execution time.
    any alternative to fix this?

    • That logic would be best handled outside the update loop. You could diff the current test results against the previous. Or you could modify it to check a flag for whether the test case was updated.

  22. hi, I use python to operate QC as bellow, but it failed, could you help me, I’m a freshman

    qcConn = get_QCConnection(qcServer,qcUser,qcPassword,qcDomain,qcProject)

    path = “Root\\Unattached\\”
    TestSetFactory = qcConn.TestSetFactory
    TestSetTreeManager = qcConn.TestSetTreeManager
    TSetFolder = TestSetTreeManager.NodeByPath(path)

    print TSetFolder
    TestSetList = TSetFolder.FindTestSets(“CBR for inc23”)

    TestSet = TestSetList.Item(1)

    print TestSet

    the execution result :

    Traceback (most recent call last):
    File “C:\Users\chenrxia\Desktop\Workspaces\PYTHON\Scripts\test.py”, line 45, in
    TestSetList = TSetFolder.FindTestSets(“CBR for inc23”)
    AttributeError: ‘NoneType’ object has no attribute ‘FindTestSets’

    I don’t know why the TSetFolder = None, and ‘NoneType’ object has no attribute ‘FindTestSets’

    in my QC test Lab, the test set Tree like:

    -CBR for inc23
    +Test Sets

    thank you in advance

  23. Hi,
    i have created a service to fetch the qc data.
    when I ran the service, am getting the below error

    system.Runtime.InteropServices.COMException (0x8000FFFF): Server is not available at TDAPIOLELib.ITDConnection4.ConnectProjectEx(String DomainName, String ProjectName, String UserName, String Password)
    But, same code is working in C# windows applicaiton.

    Please advice.
    thank you in advance

  24. Can i get all the OTA API field names ? If yes how if i dont have admin access? I have made all types of tools but always get stuck in finding the field names. Some of the Commonly used field names Such as TS_USER_01, TS_USER_02 etc i know but is there any other way? Please let me know quickly as i am in need of it. Thanks in advance :)

    • There is a helpfile (chm) that can download the OTA API documentation from a Quality Center installation. It is thorough but not necessarily comprehensive.

      If you are looking for how to identify a list of custom fields in tests, I’m not sure if OTA can do this.

  25. Hello Fijiaaron,

    I am able to do following:
    (1) I can upload the multiple test cases using Excel Addin in HPQC ALM
    (2) I need to write VB test Script for all the test cases manually

    My requirement here is as follows.
    (1) I want to upload the VB script also for all the test cases from outside may be using VB Script or Python or any other language
    (2) If Step one is not possible then is it possible to pass argument/parameter to test script from outside
    for example i have following test script statements
    run ABX.ese XYZ1.txt
    i want to change the or replace XYZ1.txt with XYZ2.txt
    same i want to access all the test cases and wants to replace that particular parameter only.


  26. Hello Fijiaaron,

    I am able to do following:
    (1) I can upload the multiple test cases using Excel Addin in HPQC ALM
    (2) I need to write VB test Script for all the test cases manually

    My requirement here is as follows.
    (1) I want to upload the VB script also for all the test cases from outside may be using VB Script or Python or any other language
    (2) If Step one is not possible then is it possible to pass argument/parameter to test script from outside
    for example i have following test script statements
    run ABX.ese XYZ1.txt
    i want to change the or replace XYZ1.txt with XYZ2.txt
    same i want to access all the test cases and wants to replace that particular parameter only.


  27. Hi All,

    I am trying to retrieve and execute test steps of each test case using com4j interface through java,but i am not getting.

    Cany anyone please help me to solve this issue please.

    Thanks in advance.

  28. Hi,

    Wondering if this page is still active, anyhow when I’m connecting to a certain project using .ConnectProjectEx Visual Studio crashes. Do you have any clue how to fix this?

    This is mine code :

    public static void Connect()
    // Pass server URL
    try { tdConnection.InitConnectionEx(ConnectionURL); }
    catch (Exception ex) { Debug.WriteLine(“Error at connecting to server”); }

    // Login
    //try { tdConnection.Login(UserName, Password); }
    //catch (Exception ex) { Debug.WriteLine(“Error at login”); }

    // Connect to project
    try { tdConnection.ConnectProjectEx(DomainName,ProjectName, UserName, Password); }
    catch (Exception ex)
    { Debug.WriteLine(“Error at connecting to project \n ”
    + ex.Message); }

  29. Hello,
    I’m not able to change step details (actual, expected, description) from C#. From VB this seems simple but I see nothing in ObjectBrowser that can help me with this issue…

    Any help will be useful,


      • Hello,
        After another day of research with Object Browser in Visual Studio and trial & error, I was able to change the value of a test step field from C#.
        The code is something like this:
        Step groupStep = stepFactory.AddItem(t.getName());
        status = getGroupStatus(t.getName(), tr);
        groupStep.Status = status;//update in QC

        if (!status.Equals(“Passed”))
        groupStep[“ST_DESCRIPTION”] = htmlLink;// (link to the Jenkins job)


        Please note that in the OTA documentation is a public property “Fields” and we have tons of examples on internet based on that property in VB scripts, but this is NOT available from C#.

        Now I need to have that htmlLink clickable in test step description but this is another story.

  30. I am looking for a code to delete all the attachments in a TestSet in the Test Lab..

    Set ObjTestSetFound = ObjTests.Item(1)
    Set ObjAttachment = ObjTestSetFound.Attachments.NewList(“”)
    For intAttachLoop = 1 To ObjAttachment.Count
    IntAttachId = ObjAttachment.RemoveAll

    This is what I have used and is not working. ANy help appreaciated.

  31. Hi,

    I am using HP ALM 11.0 and I need to upload the test results for each test run manually. Can someone please help me with a VB code that I can use to upload the test results from my local machine to some path in QC.

    Thanks in advance!

  32. Pingback: Fix Qc Failed To Get Test Value Windows XP, Vista, 7, 8 [Solved]

  33. Hi Aaron sir,

    awesome blog. Thanks for posting nice blog and i’m java guy..please help me to do the same in java. Its helps me very much.

    Thanks in advance sir..have a great day…

    • Sunny-

      Glad you find it useful. You can use a Java-COM bridge like JACOB but I’ve found it less than reliable.

      You will need to be on Windows to access OTAClient.dll and I have successfully used python COM bindings as well as the C# interop assembly, but not Java.

      Quality Center / ALM 11 does have a web service interface, but I don’t have personal experience with it. I’d be happy to work with someone who has QC 11 on a solution but in the mean time, you can run your tests in Java and output results into a simple csv format (TEST_CASE_ID, TEST_RESULT) and then use my QC Integration tool (an exe written in C#) to upload results to Quality Center.

  34. Thanks for reply sir.

    As you mentioned, using JACOB is not reliable it seems and the link you shared above uisng JACOB dll and set up supports 32-bit ..but our workstations have all 64-bit. So I have created C# code looking at your blog and trying hardddddddddddddddddd to use that dll in my java code..please help me to use in java code.. I am getting ” java.lang.UnsatisfiedLinkError: Error looking up function ‘QCConnectionUpdateTestResult’: ” error

  35. I don’t know a way to use a dll from Java code without a Java COM bridge. There are commercial solutions that *may* be more reliable than JACOB, but I still recommend isolating your java code from the C# calls to OTA API

  36. Hello Fijiaaron,

    is there a way by which i can update the RN_EXECUTION_DATE and RN_EXECUTION_TIME for the run.
    run.Field[“RN_EXECUTION_DATE”] = date // date is datetime

    Thanks for your help in advance…

  37. Hello Fijiaaron,

    I am new to QC. It would be very helpfull if i get to know the code how to make each test case of a test set in a folder where there are multiple test sets to be passed if its passed, not completed it should be not completed and if its failed it should be Failed.
    Also need to attach the screen shot to the particular test case.

    Thanks in advance

  38. Hello Fijiaaron,

    I am new to QC . I am i need of a VB script for passing all the test cases of a particular test set from a folder having more than one test set. Also i need to attach the screen shot for the passed test cases.

    Thanks in advance

  39. Hi, everyone, I have connected ALM with java via Com4j. Am having(Test set path, test name) or (test set name, test name) as input…can I able to access specific test via java code..?? Thanks in advance

  40. Hello Fijiaaron,
    I am using the project uploaded in the link above. However when i run this with my config file related to qc url and login credentials, i am getting com unhandled exception for Tdconnection.

    An unhandled exception of type ‘System.Runtime.InteropServices.COMException’ occurred in mscorlib.dll
    Additional information: Retrieving the COM class factory for component with CLSID {C5CBD7B2-490C-45F5-8C40-B8C3D108E6D7} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

    please help me on how to resolve the issue.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s