devopshq / tfs

Microsoft TFS API Python client
https://devopshq.github.io/tfs/
MIT License
110 stars 28 forks source link

Help needed in understanding how to use TFSHTTPClient #84

Open LakshmiAntin opened 4 years ago

LakshmiAntin commented 4 years ago

Hi,

Can someone explain the following line below mentioned in Advanced usage example? I am getting WorkItem undefined error.

new_task = WorkItem(client, new_task_raw)

SAnCherepan commented 4 years ago

@LakshmiAntin, this line is used to create a WorkItem instance from a raw JSON that you would get from via client.rest_client.send_post.

Make sure you have imported the library first: from tfs import TFSAPI.

If that does not help, please provide a complete code example we can use to reproduce your error.

LakshmiAntin commented 4 years ago

I want to upload test case steps using send_patch method. I am able to do it through postman, but I am not sure if I should use this line( new_task = WorkItem(client, new_task_raw) ) to upload test case steps.

Please find my code below:

import requests from tfs import TFSAPI from requests_ntlm import HttpNtlmAuth

username = 'username' password = 'password' client = TFSAPI("https://TFSLINK:8080/tfs", project="Collection name", user=username, password=password,auth_type=HttpNtlmAuth)

data = [] obj = {} obj["op"] = "add" obj["path"] = "/fields/Microsoft.VSTS.TCM.Steps" obj["value"] = "<steps id=\"0\"> <step id=\"2\" type=\"ValidateStep\"><parameterizedString isformatted=\"true\">Input step 1<parameterizedString isformatted=\"true\">Expectation step 1 <step id=\"3\" type=\"ValidateStep\"><parameterizedString isformatted=\"true\">Input step 2<parameterizedString isformatted=\"true\">Expectation step 2" data.append(obj) headers = {} headers['Content-Type'] = 'application/json-patch+json' headers['Cache-Control'] = 'no-cache' payload = {} payload['validateOnly'] = True payload['api-version'] = '1.0' project = True

test_patch = client.rest_client.send_patch("https://TFSLINK:8080/tfs/Collection name/_apis/wit/workitems/XXXXX",data,headers = headers,payload = payload,project = project) new_task = WorkItem(client, test_patch)

XXXXX is workitem id for which I would like to add test case steps.

SAnCherepan commented 4 years ago

@LakshmiAntin,

PATCH-requests are used to modify existing work items. POST-requests are used to create new work items.

If your task at hand is to modify already existing test cases, you do not need to initialize them via raw data. Steps should be added here: test_patch = client.rest_client.send_patch("https://TFSLINK:8080/tfs/Collection name/_apis/wit/workitems/XXXXX",data,headers = headers,payload = payload,project = project)

If you want to further modify your test case, init it via test_case = client.get_workitem(XXXXX) and you should have access to all of its fields. If no further modification is required, then send_patch should be your last command.

Let me know if that helps.

LakshmiAntin commented 4 years ago

{ "id": XXXXX, "rev": 1, "fields": { "System.AreaPath": "TFS", "System.TeamProject": "TFS", "System.IterationPath": "TFS", "System.WorkItemType": "Test Case", "System.State": "Design", "System.Reason": "New", "System.AssignedTo": "ABC <TFS\ABC>", "System.CreatedDate": "2019-01-09T08:00:50.51Z", "System.CreatedBy": "ABC <TFS\ABC>", "System.ChangedDate": "2019-01-09T08:00:50.51Z", "System.ChangedBy": "ABC <TFS\ABC>", "System.Title": "Sample task 2", "Microsoft.VSTS.Common.StateChangeDate": "2019-01-09T08:00:50.51Z", "Microsoft.VSTS.Common.ActivatedDate": "2019-01-09T08:00:50.51Z", "Microsoft.VSTS.Common.ActivatedBy": "ABC <TFS\ABC>", "Microsoft.VSTS.Common.Priority": 2, "Microsoft.VSTS.TCM.AutomationStatus": "Not Automated" 'XYZCorp.RegressionTest': 'No', 'Microsoft.VSTS.TCM.Steps': ' Input step 1Expectation step 1 Input step 2Expectation step 2' }, "_links": { "self": { "href": "https://TFSLINK/DefaultCollection/_apis/wit/workItems/XXXXX" }, "workItemUpdates": { "href": "https://TFSLINK/DefaultCollection/_apis/wit/workItems/XXXXX/updates" }, "workItemRevisions": { "href": "https://TFSLINK/DefaultCollection/_apis/wit/workItems/XXXXX/revisions" }, "workItemHistory": { "href": "https://TFSLINK/DefaultCollection/_apis/wit/workItems/XXXXX/history" }, "html": { "href": "https://TFSLINK/web/wi.aspx?pcguid=07b658c4-97e5-416f-b32d-3dd48d7f56cc&id=XXXXX" }, "workItemType": { "href": "https://TFSLINK/DefaultCollection/18ca0a74-cf78-45bf-b163-d8dd4345b418/_apis/wit/workItemTypes/Test%20Case" }, "fields": { "href": "https://TFSLINK/DefaultCollection/_apis/wit/fields" } }, "url": "https://TFSLINK/DefaultCollection/_apis/wit/workItems/XXXXX" }

I get the above response when I use send_patch request. I can see test case steps are returned back in the response, however it is not shown on the Web interface of TFS.

LakshmiAntin commented 4 years ago

'Microsoft.VSTS.TCM.Steps': '<steps id="0"> <step id="2" type="ValidateStep"><parameterizedString isformatted="true">Input step 1</parameterizedString><parameterizedString isformatted="true">Expectation step 1</parameterizedString><description/></step> <step id="3" type="ValidateStep"><parameterizedString isformatted="true">Input step 2</parameterizedString><parameterizedString isformatted="true">Expectation step 2</parameterizedString><description/></step></steps>'

Above steps xml representation was changed by browser I guess. Adding it again for clarity.

SAnCherepan commented 4 years ago

I will ask just in case: have you tried updating the web page after recieving positive response from patch?

Also try to get test case via client.get_workitem(XXXXX) after patching and see the content of its fields. Microsoft.VSTS.TCM.Steps in particular.

LakshmiAntin commented 4 years ago

Yes. I have tried updating the web page after receiving positive response from patch. But steps were not shown even after a successful patch response.

I tried workitem = client.get_workitem(XXXXX) print(workitem['fields']) and the output is None. Is the way I am accessing 'fields' wrong? How do I see all contents of a workitem object?

Thanks

SAnCherepan commented 4 years ago

Try print(workitem['Microsoft.VSTS.TCM.Steps']) or try looking for values in debugger if you have the opportunity.

LakshmiAntin commented 4 years ago

No. The data returned by workitem = client.get_workitem(XXXXX) does not have Microsoft.VSTS.TCM.Steps field. But the response the patch request sends back does have it. Could you please help me figure out the problem?

Thanks.

SAnCherepan commented 4 years ago

Another just-in-case-check: make sure the field you see in web actually corresponds to Microsoft.VSTS.TCM.Steps and no other HTML field.

Try this algorithm:

  1. Add steps to your test case manually via web and save it.
  2. Get test case via client.get_workitem() and print workitem['Microsoft.VSTS.TCM.Steps']. Remember/copy the value.
  3. Remove steps via web and save the test case.
  4. Add the same steps via workitem['Microsoft.VSTS.TCM.Steps'] = <copy_value_from_step_2>
  5. See if the steps appear in web.
LakshmiAntin commented 4 years ago

I tried the above algorithm and steps still do not appear on web.

SAnCherepan commented 4 years ago

I really should have mentioned it sooner. If your TFS is 2017 or newer, try authenticating via personal access token: client = TFSAPI("https://TFSLINK:8080/tfs", project="Collection name", pat=personal_access_token) as password authentification was disabled for API-requests in 2017.

LakshmiAntin commented 4 years ago

I used personal_access_token and still test steps did not show up on web.

SAnCherepan commented 4 years ago

The very last advice i can give you will be a generic one: Same actions provide same results. If result is different, something is done differently. Whether you use slightly different value, put it into a different field, or use a different account that has permission issues.

LakshmiAntin commented 4 years ago

Is project ID required for a PATCH request like it is required for creating work items mentioned in #77 ?

SAnCherepan commented 4 years ago

Yes it is required. Because TFS needs to know which WITD to use when creating a work item.

LakshmiAntin commented 4 years ago

No it still did not help. The following is returned as a response from PATCH request 'Microsoft.VSTS.TCM.Steps':'<steps id="0"> <step id="1" type="ValidateStep"><parameterizedString isformatted="true">Input step 1</parameterizedString><parameterizedString isformatted="true">Passed</parameterizedString><description/></step> <step id="2" type="ValidateStep"><parameterizedString isformatted="true">Input step 2</parameterizedString><parameterizedString isformatted="true">Failed</parameterizedString><description/></step></steps>'

However, after calling client.get_workitem(XXXXX) the following is returned for 'Microsoft.VSTS.TCM.Steps': '<steps id="0" last="0"/>'

for the same workitem XXXXX

SAnCherepan commented 4 years ago

Could you share the test case WITD? Do not forget to remove any sensitive data from it.

LakshmiAntin commented 4 years ago

client.rest_client.send_patch(URL,data,headers = headers,payload = payload,project = project)

Does the above URL needs to have a path project/projectId/_apis/wit/workitems/XXXXX ?``

SAnCherepan commented 4 years ago

Based on REST API doc, update URL can have both collection and project specified but only collection is required.