HP ALM REST API

Many companies use HP ALM (formerly known as Quality Center) for storing test cases and test results.  ALM’s companion test automation tool is another HP product called UFT (formerly know as QTP).  If you use another automation tool (for example… Selenium), it is not easy to save test results in ALM.  While it is not easy, it is possible to save external test results to ALM using an HP API.  HP has provided two API’s that can be used to do this:

A) OTA API

B) REST API

There are plenty of examples on the web if you want to use the OTA.  I would suggest against doing this since the REST API is newer and will be supported going forward.

In this article I am going to show you how to log external test results using a series of web service requests:

  1. Authentication
  2. Create a new session
  3. Using a testset ID to return a list of test ID’s
  4. Create a new testrun in testlab
  5. Update the new testrun in testlab
  6. Logout

You will need to build requests, submit them to the ALM server, and then extract crucial data from the response XML.  The examples in this article are code agnostic so it will be up to you to write and execute the requests.  When I did this in C# I wrote the HTTP requests by hand, but you might find it easier to use a REST client like RestSharp.  If you are scripting in another language, there are a plethora of REST clients available for Java, Javascript, Python, etc.

1) Authentication

To authenticate, update this XML with your credentials and submit as a POST request.

Request Type:  POST

Header:
ContentType = “application/xml”
Accept = “application/xml”

Cookie Container:  N/A

URI:

http://targetserver:targetport/qcbin/authentication-point/alm-authenticate

XML:

<alm-authentication>
 <user>ALMusername</user> 
 <password>ALMpassword</password> 
</alm-authentication>

You should get a successful response from the server.  If not, you need to double check your credentials and fix this request before attempting to proceed any further.

Make sure to extract the LWSSO_COOKIE_KEY value from the response XML and store that value inside a variable which will be used in subsequent requests.

2) Create a new session

Now that you are authenticated, you must create a new session before you can do anything else.  When you build this request, you must also create a cookie container and add the LWSSO_COOKIE_KEY value to the container.

Request Type:  POST

Cookie Container:

  • LWSSO_COOKIE_KEY

Header:
ContentType = “application/xml”
Accept = “application/xml”

URI:

http://targetserver:targetport/qcbin/rest/site-session

XML:  N/A

You must extract three values (QCSession, ALM_USER, XSRF-TOKEN) from the response XML and store these values inside variables which will be used in subsequent requests.

3) Using a testset ID to return a list of test ID’s

You need to get the config ID, test ID, and testset ID of the testset that you want to update in ALM testlab. The testset ID will be used to run a query to get a list of test instance ID’s.

In this example my testset is a manual test.  To get the testset ID, right-click on the testset and select “Test Set Details”

testset

Request Type:  GET

Header:
ContentType = “application/xml”
Accept = “application/xml”

Cookie Container:

  • LWSSO_COOKIE_KEY
  • QCSession
  • ALM_USER
  • XSRF-TOKEN

URI:

http://targetserver:targetport/qcbin/rest/domains/ALMDomain/projects/ALMProject/test-instances?query={cycle-id[#####]}

(##### is the testset ID)

XML:  N/A

This is the portion of the response XML that we are interested in:

<Field Name="id">
 <Value>#####</Value>
</Field>

This is the test instance ID.  You will want to create a list or array to hold all of these ID’s.

For the purpose of this article we will only be using the first test instance ID found inside the XML response.

4) Create a new testrun in testlab

What we want to do next is create a new test run with the minimum amount of required fields.  You may have different required fields in your ALM project, so you might need to tweak the XML a bit.

Request Type:  POST

Header:
ContentType = “application/xml”
Accept = “application/xml”

Cookie Container:

  • LWSSO_COOKIE_KEY
  • QCSession
  • ALM_USER
  • XSRF-TOKEN

URI:

http://targetserver:targetport/qcbin/rest/domains/ALMDomain/projects/ALMProject/runs

XML:

<Entity Type='run'>
 <Fields>
 <Field Name='name'><Value>testnamegoeshere</Value></Field>
 <Field Name='test-instance'><Value>1</Value></Field>
 <Field Name='testcycl-id'><Value>testcycleidgoeshere</Value></Field> 
 <Field Name='cycle-id'><Value>cycleidgoeshere</Value></Field>
 <Field Name='test-id'><Value>testidgoeshere</Value></Field>
 <Field Name='subtype-id'><Value>hp.qc.run.MANUAL</Value></Field>
 <Field Name='status'><Value>Not Completed</Value></Field>
 <Field Name='owner'><Value>testownergoeshere</Value></Field> 
 </Fields>
</Entity>

Please note that you should set the test status as “Not Completed“.

This is the portion of the response XML that we are interested in:

 <Field Name="id"><Value>#####</Value></Field>
 <Field Name="test-config-id"><Value>#####</Value></Field>
 <Field Name="testcycl-id"><Value>#####</Value></Field>
 <Field Name="cycle-id"><Value>#####</Value></Field>
 <Field Name="test-id"><Value>#####</Value></Field>

In this response, the “id” field value refers to the “id” of the new test run.  Make sure to double check all of these values before sending the next request.

Some of these naming conventions can be confusing. This is how I identify them:

test-config-id = config ID from testlab [column name = Configuration: ID]
testcycle-id = this is the test instance ID [from Step 3]
cycle-id = this is the test set ID [right-click on testset to get this]
test-id = test ID from testlab [column name = Configuration: Test ID]

5) Update the new testrun in testlab

The most important thing to remember here is that you should set the pass/fail test status during this PUT request, not the previous POST request.  When you update the status of the test run as part of this PUT request, the status of the test instance gets updated automatically.

If you attempt to POST a new test run and pass/fail it at the same time, the test instance will not get updated with the status of the latest run.  It is possible to update the test instance directly.  I would not recommend doing this because this will create a duplicate fast run.  If you are running lots of tests, you don’t want the results to get cluttered with fast runs.

Request Type:  PUT

Header:
ContentType = “application/xml”
Accept = “application/xml”

Cookie Container:

  • LWSSO_COOKIE_KEY
  • QCSession
  • ALM_USER
  • XSRF-TOKEN

URI:

http://targetserver:targetport/qcbin/rest/domains/ALMDomain/projects/ALMProject/runs/#####

XML:

<Entity Type='run'>
 <Fields>
 <Field Name='test-instance'><Value>1</Value></Field>
 <Field Name='execution-date'><Value>yyyy-mm-dd</Value></Field>
 <Field Name='ver-stamp'><Value>1</Value></Field>
 <Field Name='test-config-id'><Value>configidgoeshere</Value></Field>
 <Field Name='name'><Value>testnamegoeshere</Value></Field>
 <Field Name='has-linkage'><Value>N</Value></Field>
 <Field Name='testcycl-id'><Value>testcycleidgoeshere</Value></Field>
 <Field Name='cycle-id'><Value>cycleidgoeshere</Value></Field>
 <Field Name='host'><Value>machinenamegoeshere</Value></Field>
 <Field Name='status'><Value>Passed</Value></Field>
 <Field Name='test-id'><Value>testidgoeshere</Value></Field>
 <Field Name='subtype-id'><Value>hp.qc.run.MANUAL</Value></Field>
 <Field Name='draft'><Value>N</Value></Field>
 <Field Name='duration'><Value>0</Value></Field>
 <Field Name='owner'><Value>testownergoeshere</Value></Field>
 </Fields>
</Entity>

6) Logout

Logout and kill the active ALM session when done.

Request Type:  GET

Header:  N/A

Cookie Container:  N/A

URI:

http://targetserver:targetport/qcbin/authentication-point/logout

XML:  N/A

Once your code is refined, you can build a DLL, JAR, etc and and have your test framework pass in arguments like test project, test ID, test status, test owner, etc