Page History
...
Xray's built-in Document Generator feature, and also the Xporter Jira app, allows you to export information from Jira issues and supported Jira plugins, including Xray, to Word, Excel, PDF, or other type of documents.
...
A given issue may have fields that are "simple" single-value attributes or that are "lists". These lists may be array of objects (e.g., labels, components) stored on the issue or may be virtual lists of related issues/entities (e.g., Preconditions on a Test, all the Test Runs in a Test Execution). It's possible to iterate on these lists and the inner context becomes the element being iterated.
Parent expression | Incoming context | Inner context | Syntax for accessing fields on the inner context element | Example of accessing a field on the inner context element |
---|---|---|---|---|
none (i.e., whenever exporting a single issue, that issue becomes the parent context) | the Jira issue (i.e., the one it was exported from) | the incoming context (i.e., the issue) | ${...} | ${Priority} |
&{for issues} (i.e., whenever exporting multiple issues, inside the "&{for issues}" loop the issue becomes the current context) | the chosen Jira issues (e.g., the ones selected for bulk export) | a issue from the list of the issues from the incoming context | ${...} | ${Priority} |
#{for j=LinksCount} (i.e., some fields have a corresponding "...Count" element that can serve to implement an iterator) | the Jira issue (i.e., the one it was exported from) | each of the issue links, one by one, on the issue where it was export from | ${Links[j]} | |
#{for components} | the Jira issue (i.e., the one it was exported from) | each of the components, one by one, from the issue where it was export from | ${Components[n]} | ${Components[n].Name) |
#{for testruns} | the Jira issue (i.e., the one it was exported from) | each of the Test Runs, one by one, from the Test or Test Execution issue where it was export from | ${TestRuns[n]} | ${TestRuns[n].Key) |
#{for idx=JQLIssuesCount|clause=key in testRequirements('${Tests[n].Key}')} | N/A | each issue, one by one, returned by the JQL Expression | ${JQLIssues[idx]} | ${JQLIssues[idx].Summary} |
#{for s=TestRuns[n].TestStepsCount} | ${TestRuns[n].TestSteps[s]} | each Test Step, one by one, of a given Test Run, from the Test or Test Execution issue where it was export from | ${TestRuns[n].TestSteps[s]} | ${TestRuns[n].TestSteps[s].Action} |
Variables
Fields, for example for the current issue in context, are case sensitive.
...
Code Block |
---|
%{'${defects}'.replace(/,\s*$/, '')} |
Test
The following examples assume the current context is a Test issue.
Requirements linked to/covered by a given Test
Assuming the context is a Test issue.
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
${set(Req,'')} #{for a=JQLIssuesCount|clause=key in testRequirements('${Key}')} #{if (%{'${Req}'.indexOf('${Key},')==-1})} ${set(Req,%{'${Req}'.concat('${JQLIssues[a].Key},')})} #{end} #{end} %{'${Req}'.replace(/,\s*$/, '')} |
...
Status | ||||
---|---|---|---|---|
|
Thie example assumes that the coverage of a "requirement"/story by the related Test issues is made using the issue link "tests".
Code Block |
---|
${set(Req,'')} #{for k=TestRuns[n].LinksCount|filter=%{'${TestRuns[n].Links[k].LinkType}'.equals('tests')}} #{if (%{'${Req}'.indexOf('${TestRuns[n].Links[k].Key}')==-1})} ${set(Req,%{'${Req}'.concat('${TestRuns[n].Links[k].Key},')})} #{end} #{end} %{'${Req}'.replace(/,\s*$/, '')}" |
...
Code Block |
---|
Test Runs of a Test
...
Preconditions associated with a Test
...
Status | ||||
---|---|---|---|---|
|
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
#{for l=TestRunstestruns} ${TestRuns[n].PreConditionsCountExecution Status} #{end} |
Preconditions associated with a Test
Status | ||||
---|---|---|---|---|
|
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
#{for preconditions} ${PreConditionsif (%{'${TestRuns[n].Key} ${PreConditions[ln].PreCondition.Definition}'.equals('')})Summary} This Pre-Condition ${TestRunsPreConditions[n].Description} #{end} |
Preconditions "associated" with a TestRun
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
#{for l=TestRuns[n].PreConditionsCountPreConditions[l].Key} doesn’t have a definition. #{end} #{if (%{!'${TestRuns[n].PreConditions[l].PreCondition.Definition}'.equals('')})} Definition of Pre-ConditionThis Precondition ${TestRuns[n].PreConditions[l].Key}: ${wiki:} doesn’t have a definition. #{end} #{if (%{!'${TestRuns[n].PreConditions[l].PreCondition.Definition} #{end} |
Preconditions associated with a TestRun
'.equals('')})}
Definition of Precondition ${TestRuns[n].PreConditions[l].Key}: ${TestRuns[n].PreConditions[l].PreCondition.Definition}
#{end} |
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
#{for a=TestRuns[n].PreConditionsCount}
@{title=${TestRuns[n].PreConditions[a].Key}|href=${BaseURL}/browse/${TestRuns[n].PreConditions[a].Key}}
${wiki:TestRuns[n].PreConditions[a].Conditions}
#{end}
|
Test Sets associated with a Test
Status | |||
---|---|---|---|
|
...
Test Executions associated with a Test
...
Test Plans associated with a Test
Code Block |
---|
TestExecutionsCount |
Test Plan
The following examples assume the current context is a Test Plan.
Requirements indirectly linked to/covered by a given Test Plan (without doubles)
...
|
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
#{for testSets}
${TestSets[n].Key}
${TestSets[n].Summary}
${TestSets[n].Description}
#{end} |
Test Executions associated with a Test
Status | ||||
---|---|---|---|---|
|
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
#{for testExecutions}
${TestExecutions |
...
Code Block |
---|
/* Define a variable that will hold the keys of the requirements already listed */ ${set(Req, “A”)} /* iterate over all the Tests */ #{for tests} /* Fetch all Requirements for a given Test */ #{for a=JQLIssuesCount|clause=key in testRequirements('${Tests[n].Key}')} /* Check if Requirement key is in the variable */ #{if (%{'${Req}'.indexOf('${JQLIssues[a].Key}')==-1})} /* Add Requirement key to the variable */ ${set(Req,%{'${Req}'.concat('${JQLIssues[a].Key},')})} /* List URL, Summary, Status and Requirement Status */ @{title=${JQLIssues[a].Key}|href=${BaseURL}/browse/${JQLIssues[a].Key}} ${JQLIssues[a].Summary} ${JQLIssues[a].Status} ${JQLIssues[a].Requirement Status} /* Close if */ #{end} #{end} # /* Close for testRequirements */ #{end} |
Status | ||||
---|---|---|---|---|
|
${TestExecutions[n].Summary}
${TestExecutions[n].Description}
#{end} |
Test Plans associated with a Test
Status | ||||
---|---|---|---|---|
|
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
#{for testPlans}
${TestPlans[n].Key}
${TestPlans[n].Summary}
${TestPlans[n].Description}
#{end} |
Test Plan
The following examples assume the current context is a Test Plan.
Requirements indirectly linked to/covered by a given Test Plan (without doubles)
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
/* Define a variable that will hold the keys of the requirements already listed */
|
Code Block |
${set(Req, ‘A’“A”)} /* iterate over all the Tests */ #{for tests} /* Fetch all Requirements for a given Test */ #{for k=Tests[n].LinksCount|filter=%{a=JQLIssuesCount|clause=key in testRequirements('${Tests[n].Links[k].LinkTypeKey}'.equals('tests')}})} /* Check if Requirement key is in the variable */ #{if (%{'${Req}'.indexOf('${TestsJQLIssues[na].Links[k].Key}')==-1})} /* Add Requirement key to the variable */ ${set(Req,%{'${Req}'.concat('${Tests[n].Links[kJQLIssues[a].Key},')})} @{ /* List URL, Summary, Status and Requirement Status */ @{title=${TestsJQLIssues[na].Links[k].Key}|href=${BaseURL}/browse/${Tests[n].Links[kJQLIssues[a].Key}} ${TestsJQLIssues[na].Links[k].Summary} ${Tests[n].Links[kJQLIssues[a].Status} ${Tests[n].Links[kJQLIssues[a].Requirement Status} /* Close if */ #{end} #{end} #{end} |
Total Defects linked to Test Runs of related Test Executions
/* Close for testRequirements */
#{end}
|
Status | ||||
---|---|---|---|---|
Status | ||||
title | SERVERDC | |||
Status | ||||
|
Code Block |
---|
${set(DefReq, ‘A’)} #{for testExecutionstests} #{for ak=TestExecutionsTests[n].TestRunsCount} #{for d=TestExecutionsLinksCount|filter=%{'${Tests[n].TestRunsLinks[ak].ExecutionDefectsCountLinkType}'.equals('tests')}} #{if (%{'${DefReq}'.indexOf('${TestExecutionsTests[n].TestRunsLinks[ak].ExecutionDefects[d].Key}')==-1})} ${set(DefReq,%{'${DefReq}'.concat('${TestExecutionsTests[n].TestRuns[a].ExecutionDefects[dLinks[k].Key}')})} @{title=${TestExecutionsTests[n].TestRunsLinks[ak].ExecutionDefects[d].Key}|href=${BaseURL}/browse/${TestExecutionsTests[n].TestRunsLinks[ak].ExecutionDefects[d].Key}} ${TestExecutionsTests[n].TestRunsLinks[ak].ExecutionDefects[d].Summary} #{end} #{end} #{for m=TestExecutions${Tests[n].TestRunsLinks[ak].TestStepsCountStatus} #{for dc=TestExecutions${Tests[n].TestRunsLinks[a].TestSteps[m].DefectsCountk].Requirement Status} #{end} #{end} #{end} |
Total Defects linked to Test Runs of related Test Executions
Status | ||||
---|---|---|---|---|
|
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
${set(Def, ‘A’)} #{for testExecutions} #{for a=TestExecutions[n].TestRunsCount} #{for d=TestExecutions[n].TestRuns[a].ExecutionDefectsCount} #{if (%{'${Def}'.indexOf('${TestExecutions[n].TestRuns[a].ExecutionDefects[dif (%{'${Def}'.indexOf('${TestExecutions[n].TestRuns[a].TestSteps[m].Defects[dc].Key}')==-1})} ${set(Def,%{'${Def}'.concat('${TestExecutions[n].TestRuns[a].TestSteps[m].Defects[dcExecutionDefects[d].Key}')})} @{title=${TestExecutions[n].TestRuns[a].TestSteps[m].Defects[dcExecutionDefects[d].Key} }|href=${BaseURL}/browse/${TestExecutions[n].TestRuns[a].TestStepsExecutionDefects[md].Defects[dcKey}} ${TestExecutions[n].TestRuns[a].ExecutionDefects[d].Summary} #{end} #{end} #{end} #{for it=TestExecutions[n].TestRuns[a].IterationsCount} #{for rfor m=TestExecutions[n].TestRuns[a].Iterations[it].TestStepsCount} #{for dc=TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[rm].DefectsCount} #{if (%{'${Def}'.indexOf('${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[rm].Defects[dc].Key}')==-1})} ${set(Def,%{'${Def}'.concat('${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[rm].Defects[dc].Key}')})} @{title=${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[rm].Defects[dc].Key}|href= ${BaseURL}/browse/${TestExecutionsTestExecutions[n].TestRuns[a].Iterations[it].TestSteps[rm].Defects[dc].Key}} ${Summary} #{end} #{end} #{end} #{for it=TestExecutions[n].TestRuns[a].Iterations[itIterationsCount} #{for r=TestExecutions[n].TestStepsTestRuns[ra].DefectsIterations[dcit].SummaryTestStepsCount} #{end} #{end} #{end} #{end} #{end} #{end} |
Notes:
- includes global defects
- includes step level defects
- includes step level defects from data-driven tests
- considers only unique defects
Total Defects Count linked to Test Runs of related Test Executions
...
Notes:
- includes global defects
- includes step level defects
- includes step level defects from data-driven tests
- counts only unique defects
Test Executions associated with a Test Plan
Code Block |
---|
#{for j=TestExecutionsCount}
${TestExecutions[j].Key}
#{end}
#{for testExecutions}
${TestExecutions[n].Key}
#{end}
#{for j=JQLIssuesCount|clause= key in testPlanTestExecutions('${Key}')}
${JQLIssues[j].Key}
#{end} |
Test Execution
Test Run
Requirements indirectly linked to/covered by a given Test Run
...
Code Block |
---|
${set(Req, "")} #{for a=JQLIssuesCount|clause=key in testRequirements('${TestRuns[n]}')} #{if (%{"${Req}".indexOf("${TestRuns[n].Key},"for dc=TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].DefectsCount} #{if (%{'${Def}'.indexOf('${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Key}')==-1})} ${set(ReqDef,%{"'${ReqDef}"'.concat(”${JQLIssues[a].Key},")})} #{end} #{end} %{'${Req}'.replace(/,\s*$/, '')}" |
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
${set(Req,'')}
#{for k=TestRuns[n].LinksCount|filter=%{'${TestRuns[n].Links[k].LinkType}'.equals('tests')}}
#{if (%{'${Req}'.indexOf('${TestRuns[n].Links[k].Key}')==-1})}
${set(Req,%{'${Req}'.concat('${TestRuns[n].Links[k].Key},')})}
#{end}
#{end}
%{'${Req}'.replace(/,\s*$/, '')}" |
Total Defects linked to a given Test Run
...
'${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Key}')})}
@{title=${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Key}|href=${BaseURL}/browse/${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Key}} ${TestExecutions[n].TestRuns[a].Iterations[it].TestSteps[r].Defects[dc].Summary}
#{end}
#{end}
#{end}
#{end}
#{end}
#{end}
|
Notes:
- includes global defects
- includes step level defects
- includes step level defects from data-driven tests
- considers counts only unique defects
Total Defects Count linked to a given Test Run
Test Executions associated with a Test Plan
Code Block |
---|
#{for j=TestExecutionsCount}
${TestExecutions[j].Key}
#{end}
#{for testExecutions}
${TestExecutions[n].Key} |
Code Block |
/* context: in a data-driven test, while looping iterations */ ${set(defects, "")} ${set(totalDefects,%{${TestRuns[n].ExecutionDefectsCount}})} #{for e=TestRuns[n].ExecutionDefectsCount} ${set(defects, %{'${defects}'.concat('${TestRuns[n].ExecutionDefects[e].Key},')})} #{end} #{for s=TestRuns[n].Iterations[m].TestStepsCount} #{for d=TestRuns[n].Iterations[m].TestSteps[s].DefectsCount} #{if (%{'${defects}'.indexOf('${TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},') == -1})} ${set(defects, %{'${defects}'.concat('${TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},')})} ${set(totalDefects,%{${totalDefects}+1j=JQLIssuesCount|clause= key in testPlanTestExecutions('${Key}')} ${JQLIssues[j].Key} #{end} |
Test Run
Requirements indirectly linked to/covered by a given Test Run
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
${set(Req, "")} #{for a=JQLIssuesCount|clause=key in testRequirements('${TestRuns[n]}')} #{if (%{"${Req}".indexOf("${TestRuns[n].Key},")==-1})} ${set(Req,%{"${Req}".concat(”${JQLIssues[a].Key},")})} #{end} #{end} #%{end} '${Req}'.replace(/,\s*$/, '')}" |
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
totalDefects} /* context: in a TestRun, while looping testruns object */ ${set(defects, ""Req,'')} #{if (%{!${for k=TestRuns[n].IsDataDriven}})} ${set(totalDefects,LinksCount|filter=%{'${TestRuns[n].ExecutionDefectsCount} + ${TestRuns[nLinks[k].TestStepsDefectsCount} })LinkType}'.equals('tests')}} #{for e=TestRuns[n].ExecutionDefectsCount} ${set(defects, if (%{'${defectsReq}'.concatindexOf('${TestRuns[n].ExecutionDefectsLinks[ek].Key},')==-1})} #{end} #{for s=TestRuns[n].TestStepsCount} #{for d=TestRuns[n].TestSteps[s].DefectsCount} #{if (${set(Req,%{'${defectsReq}'.indexOfconcat('${TestRuns[n].TestSteps[s].Defects[dLinks[k].Key},') == -1})} #{end} ${set(defects, #{end} %{'${defectsReq}'.replace(/,\s*$/, '')}" |
Total Defects linked to a given Test Run
See the example below for "Total Defects Count linked to a given Test Run" and use the defects variable at the end instead.
Notes:
- includes global defects
- includes step level defects
- includes step level defects from data-driven tests
- considers only unique defects
Total Defects Count linked to a given Test Run
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
${set(defects, "")} #{if (%{!concat('${TestRuns[n].TestSteps[s].Defects[d].Key},')})} ${set(totalDefects,%{${totalDefects}+1})} #{end} #{end} #{end} #{end} #{if (%{${TestRuns[n].IsDataDriven}})} ${set(totalDefects,%{${TestRuns[n].ExecutionDefectsCount}})} #{for m= + ${TestRuns[n].IterationsCountTestStepsDefectsCount} })} #{for e=TestRuns[n].ExecutionDefectsCount} ${set(defects, %{'${defects}'.concat('${TestRuns[n].ExecutionDefects[e].Key},')})} #{end} #{for s=TestRuns[n].Iterations[m].TestStepsCount} #{for d=TestRuns[n].Iterations[m].TestSteps[s].DefectsCount} #{if (%{'${defects}'.indexOf('${TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},') == -1})} ${set(defects, %{'${defects}'.concat('${TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},')})} ${set(totalDefects,%{${totalDefects}+1}+1})} #{end} #{end} #{end} #{end} #{if (%{${TestRuns[n].IsDataDriven}})} ${set(totalDefects,%{${TestRuns[n].ExecutionDefectsCount}})} #{endfor m=TestRuns[n].IterationsCount} #{endfor e=TestRuns[n].ExecutionDefectsCount} #{end} #{end} #{end} ${totalDefects} /***/ ${set(defects, '')} #{for e=if (%{'${defects}'.indexOf('${TestRuns[n].ExecutionDefectsCountExecutionDefects[e].Key},') == -1})} ${set(defects, %{'${defects}'.concat('${TestRuns[n].ExecutionDefects[e].Key},')})} #{end} #{end} #{for s=TestRuns[n].Iterations[m].TestStepsCount} #{for d=TestRuns[n].Iterations[m].TestSteps[s].DefectsCount} #{if (%{'${defects}'.indexOf('${TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},') == -1})} ${set(defects, %{'${defects}'.concat('${TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},')})} ${set(totalDefects,%{${totalDefects}+1})} #{end} #{end} #{end} $#{defectsend} #{end} ${set(defects, %{'${defects}'.replace(/,\s*$/, '')})} ${totalDefects} |
Status | ||||
---|---|---|---|---|
|
Code Block |
---|
${ /* for a given TestRun, whenever iterating testruns, calculate total unique defects; count is "totalDefects"; list is "defects" */ ${set(defects, "")} #{if (%{!${Tests[j].TestRuns[n].IsDataDriven}})} ${set(totalDefects,%{${Tests[j].TestRuns[n].ExecutionDefectsCount} + ${Tests[j].TestRuns[n].TestStepsDefectsCount} })} #{for e=Tests[j].TestRuns[n].ExecutionDefectsCount} ${set(defects, %{'${defects}'.concat('${Tests[j].TestRuns[n].ExecutionDefects[e].Key},')})} #{end} #{for s=Tests[j].TestRuns[n].TestStepsCount} #{for d=Tests[j].TestRuns[n].TestSteps[s].DefectsCount} #{if (%{'${defects}'.indexOf('${Tests[j].TestRuns[n].TestSteps[s].Defects[d].Key},') == -1})} ${set(defects, %{'${defects}'.concat('${Tests[j].TestRuns[n].TestSteps[s].Defects[d].Key},')})} ${set(totalDefects,%{${totalDefects}+1})} #{end} #{end} #{end} #{end} #{if (%{${Tests[j].TestRuns[n].IsDataDriven}})} ${set(totalDefects,%{${Tests[j].TestRuns[n].ExecutionDefectsCount}})} #{for m=Tests[j].TestRuns[n].IterationsCount} #{for e=Tests[j].TestRuns[n].ExecutionDefectsCount} #{if (%{'${defects}'.indexOf('${Tests[j].TestRuns[n].ExecutionDefects[e].Key},') == -1})} ${set(defects, %{'${defects}'.concat('${Tests[j].TestRuns[n].ExecutionDefects[e].Key},')})} #{end} #{end} #{for s=Tests[j].TestRuns[n].Iterations[m].TestStepsCount} #{for d=Tests[j].TestRuns[n].Iterations[m].TestSteps[s].DefectsCount} #{if (%{'${defects}'.indexOf('${Tests[j].TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},') == -1})} ${set(defects, %{'${defects}'.concat('${Tests[j].TestRuns[n].Iterations[m].TestSteps[s].Defects[d].Key},')})} ${set(totalDefects,%{${totalDefects}+1})} #{end} #{end} #{end} #{end} #{end} ${set(defects, %{'${defects}'.replace(/,\s*$/, '')})} ${totalDefects} |
Notes:
- includes global defects
- includes step level defects
- includes step level defects from data-driven tests
- counts only unique defects
...