[[PageOutline(2-5,Contents,pullout)]] = Requirements Management Trac can be configured to support [wikipedia:Requirements_management requirements management]. There are [th:ProjectManagementIdeas#TracPlugins some plugins available] as well as a [th:#1226 plugin request] for building a requirements management solution in Trac. On this page one possible approach is presented for doing so. == Before you start Make sure you know your process and environment: * Which types of requirements do you have? System requirements, functional requirements, test cases, performance requirements? * Who owns the requirements? There may be more than one stakeholder in the project and each stakeholder has the responsibility to understand and prioritise their own requirements. * Who writes the requirements? The tech people or maybe management people? It may be impossible to drag your management people away from MS-Word c.s., so you may need a Word document importer. * Is there a predefined workflow for requirements, eg {{{ draft -> in review -> approved -> closed }}}? * Is the workflow dependent on the type of requirement? * How do you manage changes to requirements? * Are roles and permissions defined in the process and are they understood by all stakeholders? * Is an approval process defined on the requirements? * It may be necessary to import data from other tools or departments. For example the test department may be using their own tooling and even their own bug tracker. This process review should help to understand whether Trac with the appropriate plugins is a viable solution. Don't do that by counting bullet points, but by actually using it for a (sub)project. Instead, with the right collection of plugins or writing new plugins, the specific needs can be fulfilled and your solution will **exactly** match your process. == Requirements management using Trac The following sections describe a bare bones implementation for requirements management using some available Trac plugins. === Environment type Each project lives in a separate environment with its own database. This way you may not accidentally alter data not belonging to your current project because of a misconfiguration (e.g. broken permissions) or bug in one of your plugins. It makes access control easier which may be important. After the project is done one may revoke all write permissions and archive the complete environment so the current state of requirements is frozen. === Requirement types To distinguish requirements and test cases at least two new ticket types must be created: * {{{requirement}}} * {{{testcase}}} If you want to use your Trac also for issue tracking, then keep the standard ticket types. There is no need to create special types for each level of a [wikipedia:V-Model_(software_development) '''V model'''], but this is certainly possible. For administrating ticket types go to the '''Admin''' area of your Trac installation or use the command line: {{{#!sh $ trac-admin /path/to/projenv ticket_type add requirement $ trac-admin /path/to/projenv ticket_type add testcase }}} TracAdmin describes the command line interface in more detail. === Defining roles It may be necessary to define additional permissions to have more control of the requirements workflow. For example there may be a distinct group for requirements review and approval while the [wikipedia:Software_testing QA department] is responsible for closing requirements. To define the additional permissions {{{REQUIREMENT_APPROVE}}} and {{{REQUIREMENT_CLOSE}}} add the following to your `trac.ini` file: {{{#!ini [components] tracopt.perm.config_perm_provider.ExtraPermissionsProvider = enabled [extra-permissions] REQUIREMENT_ADMIN = REQUIREMENT_APPROVE, REQUIREMENT_CLOSE }}} Note that this also defines the permission {{{REQUIREMENT_ADMIN}}}, which grants {{{REQUIREMENT_APPROVE}}} and {{{REQUIREMENT_CLOSE}}}. For more information see ExtraPermissionsProvider. === Creating specialized workflows A workflow for a requirement is very different from a standard issue workflow. With th:MultipleWorkflowPlugin you can create specific workflows for each new type. Add this to your `trac.ini` file: {{{#!ini [components] # Enable MultipleWorkflowPlugin multipleworkflow.* = enabled [ticket-workflow-requirement] # Create special workflow for tickets with type 'requirement' # Note that special permissions are used here leave = * -> * leave.default = 1 leave.operations = leave_status approve = new, reopened -> approved approve.operations = del_resolution approve.permissions = REQUIREMENT_APPROVE reopen_verified = closed -> reopened reopen_verified.name = Reopen reopen_verified.operations = set_resolution reopen_verified.set_resolution = from verified reopen_verified.permissions = TICKET_MODIFY reopen_approved = approved -> reopened reopen_approved.name = Reopen reopen_approved.operations = set_resolution reopen_approved.set_resolution = from approved reopen_approved.permissions = TICKET_CREATE remove = new, reopened, approved, closed -> removed remove.name = Remove this Requirement permanently remove.operations = set_resolution remove.set_resolution = removed remove.permissions = TICKET_MODIFY verify = approved -> closed verify.name = Verify the Requirement and mark verify.operations = set_resolution verify.set_resolution = verified verify.permissions = REQUIREMENT_CLOSE [ticket-workflow-testcase] leave = * -> * leave.default = 1 leave.operations = leave_status ... }}} This results in the following control flow: {{{ #!Workflow width=800 height=400 leave = * -> * leave.default = 1 leave.operations = leave_status approve = new, reopened -> approved approve.operations = del_resolution approve.permissions = REQUIREMENT_APPROVE reopen_verified = closed -> reopened reopen_verified.name = Reopen reopen_verified.operations = set_resolution reopen_verified.set_resolution = from verified reopen_verified.permissions = TICKET_MODIFY reopen_approved = approved -> reopened reopen_approved.name = Reopen reopen_approved.operations = set_resolution reopen_approved.set_resolution = from approved reopen_approved.permissions = TICKET_CREATE remove = new, reopened, approved, closed -> removed remove.name = Remove this Requirement permanently remove.operations = set_resolution remove.set_resolution = removed remove.permissions = TICKET_MODIFY verify = approved -> closed verify.name = Verify the Requirement and mark verify.operations = set_resolution verify.set_resolution = verified verify.permissions = REQUIREMENT_CLOSE }}} In this workflow special permissions as defined in section [#Definingroles Defining roles] are used to control access. You may use the full power of [TracWorkflow TracWorkflow]s here, for example assigning new owners on state change. Using one of the following validation plugins, correct values in required ticket fields can be enforced: * th:TicketValidatorPlugin * th:TracTicketValidatorPlugin * th:TracTicketConditionalValidatePlugin You have to adapt the given workflow to your own process. === Parent - child relationships There **must** be some kind of parent - child relationship between tickets, so one may follow the chain of requirements in forward and backwards direction. The following plugins can be used for this: * th:SubticketsPlugin * th:MasterTicketsPlugin * th:ChildTicketsPlugin (described here) For requirements tickets the th:ChildTicketsPlugin adds buttons to the ticket page to create a child ticket of type {{{requirement}}} or {{{testcase}}}. Any child tickets are directly shown on the ticket page. See th:ChildTicketsPlugin/Examples for some screenshots of the plugin in action. Add the following to your `trac.ini` file: {{{#!ini [childtickets] # Allow child tickets for tickets of type 'requirement' parent.requirement.allow_child_tickets = true # Restrict child ticket types parent.requirement.restrict_child_type = requirement, testcase # Define the table headers to be shown for child tickets parent.requirement.table_headers = summary, type, status, component, description # No child tickets for ticket type 'testcase' parent.testcase.allow_child_tickets = false [components] # Enable ChildTicketsPlugin childtickets.* = enabled childtickets.childtickets.tracchildticketsmodule = enabled [ticket-custom] # Define ticket custom field for use with ChildTicketsPlugin parent = text parent.format = wiki parent.label = Parent ID }}} With the given settings only tickets with type {{{requirement}}} or {{{testcase}}} are allowed as children of requirements tickets. Testcase tickets can't have any children. If you use your environment also for issue tracking, then it may be necessary to change the configuration to allow other ticket types like {{{defect}}} or {{{task}}} tickets. See the th:ChildTicketsPlugin page for more configuration options. You can use th:ChildTicketTreeMacro to show a ticket hierarchy everywhere where wiki content is allowed, which may be useful for reporting purposes. === Requirements grouping Grouping of requirements may be achieved by specifying different requirement types. Each level of the '''V model''' is mapped to a different ticket type. This is probably not practical enough when you have several thousand requirements for a single level. Additional grouping may be done using the {{{component}}} field of a ticket or a custom ticket field. This can be done using the custom field {{{docid}}}, because a requirement typically starts life in an external document with a unique document id which is imported into Trac after approval. To prepare for import and subsequent grouping add the following to your `trac.ini` file: {{{#!ini [ticket-custom] # Define field for grouping of requirements docid = text docid.format = text docid.label = Document ID }}} By grouping it's possible to find requirements belonging to some part of your product/project. For example in hardware development you may group all requirements pertaining to the power supply by one id, thus making it easy for the power supply people to check for fulfillment. === Cleaning up the ticket page To some users the fields on the ticket page may be overwhelming. With the th:CondFieldsGenshiPlugin or th:DynamicFieldsPlugin it is possible to hide unneeded ticket fields or prevent undue changes. It's unlikely that a requirement morphs into a test case, so preventing any accidental damage is a good idea. With the th:CondFieldsGenshiPlugin add the following to your `trac.ini` file: {{{#!ini [components] condfieldsgenshi.* = enabled [condfieldsgenshi] # We only tweak the 'type' filed atm tweaks = type default = enable # Disable ticket type field type.type_cond = requirement, testcase }}} === Possible improvements What has been described so far is a basic solution that may already work for you. You possibly want in addition: * Some reporting: use TicketQuery for that or create TracReports. * Sign off for requirements: CookBook/Configuration/SignedTickets may be a starting point. == Summary Install the following plugins: * th:MultipleWorkflowPlugin * th:ChildTicketsPlugin * th:CondFieldsGenshiPlugin Add the following settings to your `trac.ini` file: {{{#!ini [childtickets] # Allow child tickets for tickets of type 'requirement' parent.requirement.allow_child_tickets = true # Restrict child ticket types parent.requirement.restrict_child_type = requirement, testcase # Define the table headers to be shown for child tickets parent.requirement.table_headers = summary, type, status, component, description # No child tickets for ticket type 'testcase' parent.testcase.allow_child_tickets = false [components] # Enable ChildTicketsPlugin childtickets.* = enabled childtickets.childtickets.tracchildticketsmodule = enabled # Enable CondFieldsGenshiPlugin condfieldsgenshi.* = enabled # Enable MultipleWorkflowPlugin multipleworkflow.* = enabled # Remove this if you need no special permissions tracopt.perm.config_perm_provider.ExtraPermissionsProvider = enabled [condfieldsgenshi] # We only tweak the 'type' filed atm tweaks = type default = enable # Disable ticket type field type.type_cond = requirement, testcase # Remove this section if you need no special permissions [extra-permissions] REQUIREMENT_ADMIN = REQUIREMENT_APPROVE, REQUIREMENT_CLOSE [ticket] # Use MultipleWorkflowPlugin for ticket workflows workflow = MultipleWorkflowPlugin [ticket-custom] # Define ticket custom field for use with ChildTicketsPlugin parent = text parent.format = wiki parent.label = Parent ID # Define field for grouping of requirements docid = text docid.format = text docid.label = Document ID [ticket-workflow-requirement] # Create special workflow for tickets with type 'requirement' # Note that special permissions are used here leave = * -> * leave.default = 1 leave.operations = leave_status approve = new, reopened -> approved approve.operations = del_resolution approve.permissions = REQUIREMENT_APPROVE reopen_verified = closed -> reopened reopen_verified.name = Reopen reopen_verified.operations = set_resolution reopen_verified.set_resolution = from verified reopen_verified.permissions = TICKET_MODIFY reopen_approved = approved -> reopened reopen_approved.name = Reopen reopen_approved.operations = set_resolution reopen_approved.set_resolution = from approved reopen_approved.permissions = TICKET_CREATE remove = new, reopened, approved, closed -> removed remove.name = Remove this Requirement permanently remove.operations = set_resolution remove.set_resolution = removed remove.permissions = TICKET_MODIFY verify = approved -> closed verify.name = Verify the Requirement and mark verify.operations = set_resolution verify.set_resolution = verified verify.permissions = REQUIREMENT_CLOSE # Create your testcase workflow here [ticket-workflow-testcase] leave = * -> * leave.default = 1 leave.operations = leave_status ... }}} On the command line enter the following commands to add ticket types: {{{#!sh $ trac-admin /path/to/projenv ticket_type add requirement $ trac-admin /path/to/projenv ticket_type add testcase }}}