Is there a way to measure time spent on a use case or a task in Visual Studio Online? I would like to keep everything in one place (Visual Studio Online would be the case) and from there to be able to generate reports, for instance monthly time tracking reports per user and daily reports that would reflect the actual time that has been worked on a specific use case / task versus the estimated time.
Time tracking in Visual Studio Online
11.1k views Asked by Diana TM AtThere are 3 answers
No, there is no way to do this out of the box in VSO or on TFS. This approach is not conducive to effective and value delivery. Indeed studies show that it can be detrimental to delivering value to customers.
While there are third party tools that plug into VSO and provide this capability I would recommend a different approach.
Have a separate time tracking against course grained tasks. Focus on billing and not time tracking. I want to know which customer or project to bill as well as capex vs opex... Beyond that there is little value in the data. I use Freshbooks and have used Harvest in the past successfully.
Update: If you are a consultancy you obviously need to track your time for billing. This should be done in a separate system from TFS.
I used Jira in the past and liked the way one could log hours worked.
We created a workaround in VSTS using the list of comments. It's not elegant, but it works. One adds a numeric value in a comment and that is counted as a number of hours worked. You can make this more elaborate using a regular expression, but I'm enclosing code that assumes there is a float or integer in there.
URL_PREFACE = "https://yourproject.visualstudio.com/defaultcollection/"
def getTicketComments(ticketID):
""" Gets a list of the comments (in order from oldest to newest) for a given ticket """
url = URL_PREFACE + "_apis/wit/workitems/" + str(ticketID) + "/comments?api-version=3.0-preview&order=asc"
jsonDict = readURL(url)
return jsonDict["comments"]
Then we sum the values we find:
def getHoursSum(ticketID):
""" For the given ticket, gets their comments, and calculates the hours
"""
commentList = getTicketComments(ticketID)
hourSum = 0
for comment in commentList:
try:
hourSum += float(comment["text"]) # Will break if it's not a number
except:
pass
return hourSum
And finally, we store the number of hours worked in the CompletedWork
field:
def updateHours(ticketID, completedHours):
headers = {"Content-Type": "application/json-patch+json"}
url = URL_PREFACE + "_apis/wit/workitems/" + str(ticketID) + "?api-version=1.0"
body = """[
{
"op": "replace",
"path": "/fields/Microsoft.VSTS.Scheduling.CompletedWork",
"value": """ + str(completedHours) + """
}
]"""
username = 'username' # Doesn't matter
password = TOKEN
# TO GET TOKEN:
# Log into https://yourproject.visualstudio.com/
# Click on your name -> My Profile
# In the left-hand sidebar, click on "Security"
# Under "Personal Accesss Tokens," click "Add"
# Under "Description" give your token a name (doesn't matter)
# Choose an expiration for your token (recommend: 1 yr)
# "Authorized Scopes" = "All Scopes"
# Click "Save"
# Copy the token it gives you into token field below (paste between quotes)
session = requests.Session()
request = requests.Request(method="PATCH", headers=headers, auth=(username, password),
url=url, data=body)
prepped = request.prepare()
response = session.send(prepped)
return response
(I just copied and pasted some simplified code--you will need to integrate it.)
Code was written by my most excellent colleague @Elliptica.
When you are creating a Task linked to a Backlog item or a Bug, the field Remaining work is actually in hours. So you can set this to have kind of a time tracking.
Unfortunately, there is no way to set the actual time the task took after it is finished, as far as I know.