Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
AnnotationExtractor.php
Go to the documentation of this file.
1 <?php
8 
12 
17 {
23  private $storyToTitleMappings = [];
24 
28  private $testCaseToTitleMappings = [];
29 
30  const ANNOTATION_VALUE = 'value';
32  "BLOCKER" => "BLOCKER",
33  "CRITICAL" => "CRITICAL",
34  "MAJOR" => "NORMAL",
35  "AVERAGE" => "MINOR",
36  "MINOR" => "TRIVIAL"
37  ];
39  "stories",
40  "title",
41  "description",
42  "severity"
43  ];
44 
48  public function __construct()
49  {
50  // empty constructor
51  }
52 
62  public function extractAnnotations($testAnnotations, $filename)
63  {
64  $annotationObjects = [];
65  $annotations = $this->stripDescriptorTags($testAnnotations, self::NODE_NAME);
66 
67  // parse the Test annotations
68 
69  foreach ($annotations as $annotationKey => $annotationData) {
70  $annotationValues = [];
71  // Only transform severity annotation
72  if ($annotationKey == "severity") {
73  $annotationObjects[$annotationKey] = $this->transformAllureSeverityToMagento(
74  $annotationData[0]['value']
75  );
76  continue;
77  }
78 
79  if ($annotationKey == "skip") {
80  $annotationData = $annotationData['issueId'];
81  $this->validateSkippedIssues($annotationData, $filename);
82  }
83 
84  foreach ($annotationData as $annotationValue) {
85  $annotationValues[] = $annotationValue[self::ANNOTATION_VALUE];
86  }
87  // TODO deprecation|deprecate MFTF 3.0.0
88  if ($annotationKey == "group" && in_array("skip", $annotationValues)) {
89  LoggingUtil::getInstance()->getLogger(AnnotationExtractor::class)->warning(
90  "Use of group skip will be deprecated in MFTF 3.0.0. Please update tests to use skip tags.",
91  ["test" => $filename]
92  );
93  }
94 
95  $annotationObjects[$annotationKey] = $annotationValues;
96  }
97 
98  $this->addTestCaseIdToTitle($annotationObjects, $filename);
99  $this->validateMissingAnnotations($annotationObjects, $filename);
100  $this->addStoryTitleToMap($annotationObjects, $filename);
101 
102  return $annotationObjects;
103  }
104 
111  public function addStoryTitleToMap($annotations, $filename)
112  {
113  if (isset($annotations['stories']) && isset($annotations['title'])) {
114  $story = $annotations['stories'][0];
115  $title = $annotations['title'][0];
116  $this->storyToTitleMappings[$story . "/" . $title][] = $filename;
117  }
118  }
119 
126  private function addTestCaseIdToTitle(&$annotations, $filename)
127  {
128  if (!isset($annotations['title'])) {
129  return;
130  }
131 
132  $testCaseId = "[NO TESTCASEID]";
133 
134  if (isset($annotations['testCaseId'])) {
135  $testCaseId = $annotations['testCaseId'][0];
136  }
137 
138  $newTitle = "{$testCaseId}: " . $annotations['title'][0];
139 
140  $annotations['title'][0] = $newTitle;
141  $this->testCaseToTitleMappings[$newTitle][] = $filename;
142  }
143 
149  private function validateMissingAnnotations($annotationObjects, $filename)
150  {
151  $missingAnnotations = [];
152 
153  foreach (self::REQUIRED_ANNOTATIONS as $REQUIRED_ANNOTATION) {
154  if (!array_key_exists($REQUIRED_ANNOTATION, $annotationObjects)) {
155  $missingAnnotations[] = $REQUIRED_ANNOTATION;
156  }
157  }
158 
159  if (!empty($missingAnnotations)) {
160  $message = "Test {$filename} is missing required annotations.";
161  LoggingUtil::getInstance()->getLogger(ActionObject::class)->deprecation(
162  $message,
163  ["testName" => $filename, "missingAnnotations" => implode(", ", $missingAnnotations)]
164  );
165  }
166  }
167 
174  {
175  $dupes = [];
176 
177  foreach ($this->storyToTitleMappings as $storyTitle => $files) {
178  if (count($files) > 1) {
179  $dupes[$storyTitle] = "'" . implode("', '", $files) . "'";
180  }
181  }
182  if (!empty($dupes)) {
183  $message = "Story and Title annotation pairs must be unique:\n\n";
184  foreach ($dupes as $storyTitle => $tests) {
185  $storyTitleArray = explode("/", $storyTitle);
186  $story = $storyTitleArray[0];
187  $title = $storyTitleArray[1];
188  $message .= "Story: '{$story}' Title: '{$title}' in Tests {$tests}\n\n";
189  }
190  throw new XmlException($message);
191  }
192  }
193 
201  {
202  $dupes = [];
203  foreach ($this->testCaseToTitleMappings as $newTitle => $files) {
204  if (count($files) > 1) {
205  $dupes[$newTitle] = "'" . implode("', '", $files) . "'";
206  }
207  }
208  if (!empty($dupes)) {
209  $message = "TestCaseId and Title pairs must be unique:\n\n";
210  foreach ($dupes as $newTitle => $tests) {
211  $testCaseTitleArray = explode(": ", $newTitle);
212  $testCaseId = $testCaseTitleArray[0];
213  $title = $testCaseTitleArray[1];
214  $message .= "TestCaseId: '{$testCaseId}' Title: '{$title}' in Tests {$tests}\n\n";
215  }
216  throw new XmlException($message);
217  }
218  }
219 
227  public function validateSkippedIssues($issues, $filename)
228  {
229  foreach ($issues as $issueId) {
230  if (empty($issueId['value'])) {
231  $message = "issueId for skipped tests cannot be empty. Test: $filename";
232  throw new XmlException($message);
233  }
234  }
235  }
236 
244  public function transformAllureSeverityToMagento($annotationData)
245  {
246  $annotationValue = strtoupper($annotationData);
247  //Mapping Magento severity to Allure Severity
248  //Attempts to resolve annotationValue reference against MAGENTO_TO_ALLURE_SEVERITY_MAP -
249  // if not found returns without modification
250  $allureAnnotation[] = self::MAGENTO_TO_ALLURE_SEVERITY_MAP[$annotationValue] ?? $annotationValue;
251 
252  return $allureAnnotation;
253  }
254 }
$title
Definition: default.phtml:14
$message
foreach($appDirs as $dir) $files