1"use strict";(globalThis.webpackChunkserenity_users_guide=globalThis.webpackChunkserenity_users_guide||[]).push([[4821],{2510(e,s,t){t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>n,toc:()=>l});const n=JSON.parse('{"id":"reporting/the_serenity_reports","title":"The Serenity Reports","description":"The Serenity reports are a particularly powerful feature of Serenity BDD. They aim not only to report test results, but also to document how features are tested, and what the application does.","source":"@site/docs/reporting/the_serentity_reports.md","sourceDirName":"reporting","slug":"/reporting/the_serenity_reports","permalink":"/docs/reporting/the_serenity_reports","draft":false,"unlisted":false,"editUrl":"https://github.com/serenity-bdd/serenity-bdd.github.io/blob/master/docs/reporting/the_serentity_reports.md","tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"id":"the_serenity_reports","title":"The Serenity Reports","sidebar_position":1},"sidebar":"tutorialSidebar","previous":{"title":"Integration Testing in Spring","permalink":"/docs/spring/integration_testing_spring"},"next":{"title":"Living Documentation","permalink":"/docs/reporting/living_documentation"}}');var r=t(4848),i=t(8453);const o={id:"the_serenity_reports",title:"The Serenity Reports",sidebar_position:1},a=void 0,c={},l=[{value:"An overview of the test results",id:"an-overview-of-the-test-results",level:2},{value:"Functional Test Coverage",id:"functional-test-coverage",level:2},{value:"Functional Coverage Details",id:"functional-coverage-details",level:2},{value:"Test Results",id:"test-results",level:2},{value:"Errors and Tags",id:"errors-and-tags",level:2}];function d(e){const s={code:"code",em:"em",h2:"h2",img:"img",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(s.p,{children:["The Serenity reports are a particularly powerful feature of Serenity BDD. They aim not only to ",(0,r.jsx)(s.em,{children:"report"})," test results, but also to ",(0,r.jsx)(s.em,{children:"document"})," how features are tested, and what the application does."]}),"\n",(0,r.jsx)(s.h2,{id:"an-overview-of-the-test-results",children:"An overview of the test results"}),"\n",(0,r.jsx)(s.p,{children:"A typical Serenity test report is shown below:"}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Functional Coverage Overview",src:t(2950).A+"",width:"3140",height:"1802"})}),"\n",(0,r.jsx)(s.p,{children:"This shows a simple pie chart displaying the test result distribution, and bar charts indicating the test outcomes sorted by result and by test duration."}),"\n",(0,r.jsxs)(s.p,{children:["The squiggly lines in the orange bars (indicating broken tests) are for accessiblity. To activate these, you will need the following setting in your ",(0,r.jsx)(s.code,{children:"serenity.conf"})," file:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-hocon",children:"serenity {\n report {\n accessibility = true\n }\n}\n"})}),"\n",(0,r.jsx)(s.h2,{id:"functional-test-coverage",children:"Functional Test Coverage"}),"\n",(0,r.jsxs)(s.p,{children:["Further down the screen you will find the Functional Test Coverage section:\n",(0,r.jsx)(s.img,{alt:"A typical Serenity Report home page",src:t(4971).A+"",width:"3064",height:"1228"})]}),"\n",(0,r.jsxs)(s.p,{children:["This section gives a breakdown by capability (or by however you have decided to group your features). You can define the requirements types used in your project using the ",(0,r.jsx)(s.code,{children:"serenity.requirement.types"})," property, e.g."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-hocon",children:'serenity {\n requirement {\n types = "epic, feature"\n }\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["Note that for Cucumber, the lowest level will always be defined as ",(0,r.jsx)(s.em,{children:"Feature"}),"."]}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.em,{children:"Key Statistics"})," section shows execution times and the overall number of test scenarios and test cases. You can define the ranges of duration values that appear in the report using the ",(0,r.jsx)(s.code,{children:"serenity.report.durations"})," property:"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-hocon",children:'serenity{\n report {\n durations = "1,2,4,8,15,30,60"\n }\n}\n'})}),"\n",(0,r.jsxs)(s.p,{children:["Serenity distinguishes between more general ",(0,r.jsx)(s.em,{children:"Test Scenarios"}),", and more specific ",(0,r.jsx)(s.em,{children:"Test Cases"}),"."]}),"\n",(0,r.jsx)(s.p,{children:"A simple scenario or JUnit test counts as a scenario with a single test case. For example, consider the following scenario:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-gherkin",children:"Scenario: Colin logs in with Colin's valid credentials\n Given Colin is on the login page\n When Colin logs in with valid credentials\n Then he should be presented the product catalog\n"})}),"\n",(0,r.jsx)(s.p,{children:"This counts as 1 scenario with 1 test case."}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Scenarios"}),(0,r.jsx)(s.th,{children:"Test Cases"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"1"})]})})]}),"\n",(0,r.jsx)(s.p,{children:"A scenario outline, on the other hand, is a single scenario with many test cases. So if you had the following scenario outline:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-gherkin",children:" Scenario Outline: Login's with invali
1d credentials for <username>\n Given Colin is on the login page\n When Colin attempts to login with the following credentials:\n | username | password |\n | <username> | <password> |\n Then he should be presented with the error message <message>\n Examples:\n | username | password | message |\n | standard_user | wrong_password | Username and password do not match any user in this service |\n | unknown_user | secret_sauce | Username and password do not match any user in this service |\n | unknown_user | wrong_password | Username and password do not match any user in this service |\n | locked_out_user | secret_sauce | Sorry, this user has been locked out |\n"})}),"\n",(0,r.jsx)(s.p,{children:"Then the test report would include 1 scenario but 4 test cases:"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Scenarios"}),(0,r.jsx)(s.th,{children:"Test Cases"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"1"}),(0,r.jsx)(s.td,{children:"4"})]})})]}),"\n",(0,r.jsx)(s.p,{children:"So a test suite that contains both of these scenarios would include 2 scenarios made up of 5 test cases:"}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Scenarios"}),(0,r.jsx)(s.th,{children:"Test Cases"})]})}),(0,r.jsx)(s.tbody,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"2"}),(0,r.jsx)(s.td,{children:"5"})]})})]}),"\n",(0,r.jsx)(s.h2,{id:"functional-coverage-details",children:"Functional Coverage Details"}),"\n",(0,r.jsx)(s.p,{children:"Further down the functional coverage results are displayed in more detail:"}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Functional Coverage Details",src:t(4774).A+"",width:"2856",height:"1538"})}),"\n",(0,r.jsxs)(s.p,{children:["This lists the requirements by category. By default, Cucumber results organised in folders under ",(0,r.jsx)(s.code,{children:"src/test/resources/features"})," will be organised by Capabilities and Features. As mentioned above, you can customise these categories using the ",(0,r.jsx)(s.code,{children:"serenity.requirement.types"})," property."]}),"\n",(0,r.jsx)(s.h2,{id:"test-results",children:"Test Results"}),"\n",(0,r.jsx)(s.p,{children:"The Test Results tab lists the actual test results:"}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Test Results",src:t(3524).A+"",width:"3124",height:"1740"})}),"\n",(0,r.jsx)(s.p,{children:"For data-driven tests and scenario outlines, each row of data is reported as a separate test result, and marked by a table icon to indicate that it is a data-driven test result."}),"\n",(0,r.jsx)(s.h2,{id:"errors-and-tags",children:"Errors and Tags"}),"\n",(0,r.jsx)(s.p,{children:"The last section of the report lists the most frequent causes of test failures:"}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Errors and tags",src:t(9370).A+"",width:"2886",height:"824"})}),"\n",(0,r.jsxs)(s.p,{children:["This section also mentions which the features containing the most failing tests. You can see which tests fail for a given reason by clicking on the corresponding ",(0,r.jsx)(s.em,{children:"error"})," tag just below this section."]}),"\n",(0,r.jsxs)(s.p,{children:["It also lists the tags appearing in the features. You can exclude tags you don't want to appear in this section (for example, technical tags) using the ",(0,r.jsx)(s.code,{children:"serenity.report.exclude.tags"})," property, e.g."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:'serenity {\n report {\n exclude.tags = "resetappstate,singlebrowser,manual"\n }\n}\n'})})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},2950(e,s,t){t.d(s,{A:()=>n});const n=t.p+"assets/images/reports-overview-71f7fb1aae958453fc042f9b385fff85.png"},3524(e,s,t){t.d(s,{A:()=>n});const n=t.p+"assets/images/test-results-2b204165143994d93b7a1480dd1b5915.png"},4774(e,s,t){t.d(s,{A:()=>n});const n=t.p+"assets/images/functional-coverage-details-3f85043f2ec4989bcbd2edce2b36f417.png"},4971(e,s,t){t.d(s,{A:()=>n});const n=t.p+"assets/images/functional-coverage-overview-9439c771ccb6aac9925f30ff3f84b5b0.png"},8453(e,s,t){t.d(s,{R:()=>o,x:()=>a});var n=t(6540);const r={},i=n.createContext(r);function o(e){const s=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(s):{...s,...e}},[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:s},e.children)}},9370(e,s,t){t.d(s,{A:()=>n});const n=t.p+"assets/images/tags-8c41950829719f2fb397f4d20dc8c43f.png"}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.