Agile/XP software teams are expected to follow a number of specific practices during each Agile iteration, such as estimating the effort (“points”) required to complete user stories, using branches and pull requests properly to coordinate when merging code, having frequent “standups” to keep the team in sync, and conducting retrospectives to identify areas of improvement for future iterations. With our tool, Eagle, we combine two observations in developing a methodology and tools to help teams monitor their performance and encourage individual members to improve on these practices over time. The first is that many Agile practices are increasingly supported by web-based tools whose “data exhaust” can provide insight into how closely the teams are following the practices. The second is that some of the practices can be expressed in terms similar to those developed for expressing service level objectives in software as a service. A typical SLO for an interactive Web site might be “ over any 5-minute window, 99% of requests to the main page must be delivered within 200ms.” Analogously, a typical Team Practice Objective (TPO) for an Agile/XP team might be “over any 3-days period, 75% of assigned 1-point stories should be finished.” With our work, we create a natural lenguage to express this and also measure the adherence of the team to this TPO. We adapt a system originally developed for monitoring and visualizing SLO compliance to monitor selected TPOs for Agile/XP software teams. The system consumes and analyzes the data exhaust from widely-used tools such as GitHub and Pivotal Tracker and provides team(s) and coach(es) a “dashboard” summarizing the teams’ adherence to various practices.
A demo video is available at https://youtu.be/A4xwJMEQh9c
In order to have live demo of the tool over a list of public projects please follow this link. (user/pwd: demo/demo)
The case study addressed a TPA containg 7 TP as described in Table 1.
An actual formal TPA used in the case study modeling the differen practices is as following:
---
id: tpa-12032
version: 1.0.0
type: agreement
context:
validity:
initial: '2017-10-15'
timeZone: America/Los_Angeles
infrastructure:
registry: http://registry.eagle.governify.io/api/v6
reporter: http://reporter.eagle.governify.io/api/v4
render: https://ui.eagle.governify.io/render?model=https://registry.eagle.governify.io/api/v6/agreements/tpa-12032&view=/renders/tpa/default.html&ctrl=/renders/tpa/default.js
dashboard: http://dashboard.eagle.governify.io
definitions:
schemas: {}
scopes:
development:
member:
name: Member
description: Member of a project
type: string
project:
name: Project
description: Project
type: string
default: 12032
class:
name: Class
description: Group some projects
type: string
default: CS169
computers:
pivotaltracker:
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
terms:
metrics:
PERCENTAGE_SUCCESSFULLY_FINISHED_1P_STORIES:
computer:
name: PERCENTAGE_SUCCESSFULLY_FINISHED_1P_STORIES
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element:
percentage:
transition:
fromState: started
toState: finished
duration: "< 1440"
filters:
type: feature
state: finished,delivered,accepted,rejected
estimate: 1
PERCENTAGE_SUCCESSFULLY_DELIVERED_1P_STORIES:
computer:
name: PERCENTAGE_SUCCESSFULLY_DELIVERED_1P_STORIES
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element:
percentage:
transition:
fromState: started
toState: delivered
duration: "< 4320"
filters:
type: feature
state: delivered,accepted,rejected
estimate: 1
PERCENTAGE_OF_1P_STORIES:
computer:
name: PERCENTAGE_OF_1P_STORIES
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element:
percentage:
estimate: 1
filters:
type: feature
state: started,finished,delivered,accepted,rejected
NUMBER_OF_STARTED_STORIES:
computer:
name: NUMBER_OF_STARTED_STORIES
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element: number
filters:
type: feature,bug,chore
state: started
REMAINING_POINTS:
computer:
name: REMAINING_POINTS
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element: points
filters:
type: feature
state: unstarted
CURRENT_FINISHED_STORIES:
computer:
name: CURRENT_FINISHED_STORIES
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element: number
filters:
type: feature,bug,chore
state: finished,delivered,accepted,rejected
FINISHED_STORIES_THREE_DAYS_AGO:
computer:
name: FINISHED_STORIES_THREE_DAYS_AGO
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element: number
filters:
type: feature,bug,chore
state: finished,delivered,accepted,rejected
offset: -3
CURRENT_DELIVERED_POINTS:
computer:
name: CURRENT_DELIVERED_POINTS
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element: points
filters:
type: feature,bug,chore
state: delivered,accepted,rejected
DELIVERED_POINTS_THREE_DAYS_AGO:
computer:
name: DELIVERED_POINTS_THREE_DAYS_AGO
url: http://pt.computer.eagle.governify.io
apiVersion: '1'
measure:
computing: actual
element: points
filters:
type: feature,bug,chore
state: delivered,accepted,rejected
offset: -3
guarantees:
- id: 1P_STORIES_SUCCESSFULLY_FINISHED_ON_TIME
description: A one-point story should take less than a day to finish
of:
- objective: PERCENTAGE_SUCCESSFULLY_FINISHED_1P_STORIES >= 75
with:
PERCENTAGE_SUCCESSFULLY_FINISHED_1P_STORIES: {}
window:
type: static
period: daily
initial: '2018-01-01'
- id: 1P_STORIES_SUCCESSFULLY_DELIVERED_ON_TIME
description: A one-point story should take less than three days to deliver
of:
- objective: PERCENTAGE_SUCCESSFULLY_DELIVERED_1P_STORIES >= 75
with:
PERCENTAGE_SUCCESSFULLY_DELIVERED_1P_STORIES: {}
window:
type: static
period: daily
initial: '2018-01-01'
- id: MAJORITY_OF_1P_STORIES
description: More than half of started features should be 1-point
of:
- objective: PERCENTAGE_OF_1P_STORIES >= 50
with:
PERCENTAGE_OF_1P_STORIES: {}
window:
type: static
period: daily
initial: '2018-01-01'
- id: ONE_STORY_AT_A_TIME
description: Only one story per person can be started at a time
of:
- scope:
member: "*"
objective: NUMBER_OF_STARTED_STORIES <= 1
with:
NUMBER_OF_STARTED_STORIES: {}
window:
type: static
period: daily
initial: '2018-01-01'
- id: NO_REMAINING_POINTS
description: A team should finish the backlog by the end of an iteration
of:
- objective: REMAINING_POINTS == 0
with:
REMAINING_POINTS: {}
window:
type: static
period: biweekly
initial: '2018-01-01'
- id: INCREMENT_OF_FINISHED_STORIES
description: Students should finish at least one story every three days
of:
- scope:
member: "*"
objective: CURRENT_FINISHED_STORIES - FINISHED_STORIES_THREE_DAYS_AGO > 0
with:
FINISHED_STORIES_THREE_DAYS_AGO: {}
CURRENT_FINISHED_STORIES: {}
window:
type: static
period: daily
initial: '2018-01-01'
- id: INCREMENT_OF_DELIVERED_POINTS
description: A team should deliver at least one point every three days
of:
- objective: CURRENT_DELIVERED_POINTS - DELIVERED_POINTS_THREE_DAYS_AGO > 0
with:
DELIVERED_POINTS_THREE_DAYS_AGO: {}
CURRENT_DELIVERED_POINTS: {}
window:
type: static
period: daily
initial: '2018-01-01'