Skip to content

Commit

Permalink
Add ability to import automated tests to Zephyr
Browse files Browse the repository at this point in the history
Add ability to import automated tests to Zephyr:
add level properties for story and scenario
add ability to create jira issue
add ability to link requirement to test
  • Loading branch information
TatianaTochko committed Dec 22, 2021
1 parent 3124f8e commit 1e9199b
Show file tree
Hide file tree
Showing 28 changed files with 1,185 additions and 87 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions docs/modules/integrations/pages/zephyr-exporter.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ include::partial$jira-configuration.adoc[]
|Required
|Description

|`zephyr.exporter.level`
|true
|Property to export stories on STORY or SCENARIO level

|`zephyr.exporter.jira-instance-key`
|false
|The key of the configured JIRA instance, in case of missing value it will be evaluated automatically based on issue keys being exported
Expand Down Expand Up @@ -52,6 +56,30 @@ include::partial$jira-configuration.adoc[]

|===

== Jira Fields Mapping

The Zephyr is a Jira plugin that uses custom Jira fields for it's data, one of the ways to find out custom field names for particular field used by Zephyr on Jira UI (if access to Jira configuration is prohibited) is to request description of some issue.

=== Test Case Properties

image::zephyr.png[Zephyr test case view]

[cols="1,2", options="header"]
|===

|Property
|Description

|`jira.fields-mapping.story-type`
|Key of a field containing story type

|`jira.fields-mapping.test-step`
|Key of a field containing step of cucumber story/scenario

|===

include::partial$authentication.adoc[]

== Zephyr Execution Status Mapping

The Zephyr plugin for Jira has own configurable execution statuses. testExecutionStatus endpoint is used to get the detailed information about the statuses, like: https://jira.example.com/rest/zapi/latest/util/testExecutionStatus. The following properties are used to setup a mapping between Vividus and Zephyr execution statuses.
Expand Down
75 changes: 75 additions & 0 deletions vividus-engine/src/main/java/org/vividus/model/jbehave/Story.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,27 @@

package org.vividus.model.jbehave;

import static org.vividus.model.MetaWrapper.META_VALUES_SEPARATOR;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import org.apache.commons.lang3.StringUtils;

public class Story
{
private String path;
private Lifecycle lifecycle;
private List<Scenario> scenarios;
private List<Meta> meta;

public String getPath()
{
Expand Down Expand Up @@ -60,6 +68,16 @@ public void setScenarios(List<Scenario> scenarios)
this.scenarios = scenarios;
}

public List<Meta> getMeta()
{
return meta;
}

public void setMeta(List<Meta> meta)
{
this.meta = meta;
}

/**
* Get unique scenarios.
*
Expand Down Expand Up @@ -116,4 +134,61 @@ private static void adjustScenarioWithLifecycle(Parameters scenarioParameters, P

scenarioParameters.setValues(adjustedValues);
}

/**
* Get unique <b>meta</b> value
*
* <p>If the <b>meta</b> does not exist or has no value, an empty {@link Optional} will be returned
*
* <p><i>Notes</i>
* <ul>
* <li><b>meta</b> value is trimmed upon returning</li>
* <li><i>;</i> char is used as a separator for <b>meta</b> with multiple values</li>
* </ul>
*
* @param metaName the meta name
* @return the meta value
* @throws NotUniqueMetaValueException if the <b>meta</b> has more than one value
*/
public Optional<String> getUniqueMetaValue(String metaName) throws NotUniqueMetaValueException
{
Set<String> values = getMetaValues(metaName);
if (values.size() > 1)
{
throw new NotUniqueMetaValueException(metaName, values);
}
return values.isEmpty() ? Optional.empty() : Optional.of(values.iterator().next());
}

/**
* Get all <b>meta</b> values
*
* <p><i>Notes</i>
* <ul>
* <li><b>meta</b>s without value are ignored</li>
* <li><b>meta</b> values are trimmed upon returning</li>
* <li><i>;</i> char is used as a separator for <b>meta</b> with multiple values</li>
* </ul>
*
* @param metaName the meta name
* @return the meta values
*/
public Set<String> getMetaValues(String metaName)
{
return getMetaStream().filter(m -> metaName.equals(m.getName()))
.map(Meta::getValue)
.filter(StringUtils::isNotEmpty)
.map(String::trim)
.map(value -> StringUtils.splitPreserveAllTokens(value, META_VALUES_SEPARATOR))
.flatMap(Stream::of)
.map(String::trim)
.collect(Collectors.toCollection(LinkedHashSet::new));
}

private Stream<Meta> getMetaStream()
{
return Optional.ofNullable(getMeta())
.map(List::stream)
.orElseGet(Stream::empty);
}
}
1 change: 1 addition & 0 deletions vividus-to-zephyr-exporter/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ project.description = 'Vividus to Zephyr exporter'

dependencies {
implementation project(':vividus-util')
implementation project(':vividus-engine')
implementation project(':vividus-facade-jira')

// https://github.com/spring-gradle-plugins/dependency-management-plugin/issues/257
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,23 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.vividus.jira.JiraConfigurationException;
import org.vividus.util.property.PropertyParser;
import org.vividus.zephyr.configuration.JiraFieldsMapping;
import org.vividus.zephyr.configuration.ZephyrExporterConfiguration;
import org.vividus.zephyr.configuration.ZephyrExporterProperties;
import org.vividus.zephyr.exporter.ZephyrExporter;

@SpringBootApplication
@ImportResource(locations = { "org/vividus/zephyr/spring.xml", "org/vividus/http/client/spring.xml",
"org/vividus/jira/spring.xml" })
@EnableConfigurationProperties({ ZephyrExporterConfiguration.class, ZephyrExporterProperties.class })
@PropertySource({
"org/vividus/http/client/defaults.properties",
"org/vividus/util/defaults.properties"
})
@EnableConfigurationProperties({ ZephyrExporterConfiguration.class, ZephyrExporterProperties.class,
JiraFieldsMapping.class })
public class VividusToZephyrExporterApplication
{
public static void main(String[] args) throws IOException, JiraConfigurationException
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.zephyr.configuration;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("jira.fields-mapping")
public class JiraFieldsMapping
{
private String storyType;

private String testSteps;

public String getStoryType()
{
return storyType;
}

public void setStoryType(String storyType)
{
this.storyType = storyType;
}

public String getTestSteps()
{
return testSteps;
}

public void setTestSteps(String testSteps)
{
this.testSteps = testSteps;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.vividus.zephyr.model.TestCaseStatus;
import org.vividus.zephyr.model.TestLevel;

@ConfigurationProperties("zephyr.exporter")
public class ZephyrExporterProperties
Expand All @@ -36,6 +37,8 @@ public class ZephyrExporterProperties

private List<TestCaseStatus> statusesOfTestCasesToAddToExecution;

private TestLevel level;

public String getJiraInstanceKey()
{
return jiraInstanceKey;
Expand Down Expand Up @@ -75,4 +78,14 @@ public void setStatusesOfTestCasesToAddToExecution(List<TestCaseStatus> statuses
{
this.statusesOfTestCasesToAddToExecution = statusesOfTestCasesToAddToExecution;
}

public TestLevel getLevel()
{
return level;
}

public void setLevel(TestLevel level)
{
this.level = level;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.vividus.zephyr.convertor;

import java.util.ArrayList;
import java.util.List;

import org.vividus.model.jbehave.Step;
import org.vividus.model.jbehave.Story;
import org.vividus.zephyr.model.CucumberTestStep;

public final class CucumberStoryScenarioConverter
{
private CucumberStoryScenarioConverter()
{
}

public static List<CucumberTestStep> convert(String scenarioTitle, List<Step> steps)
{
List<CucumberTestStep> testSteps = new ArrayList<>();
return testSteps;
}

public static List<CucumberTestStep> convert(Story steps)
{
List<CucumberTestStep> testSteps = new ArrayList<>();
return testSteps;
}
}
Loading

0 comments on commit 1e9199b

Please sign in to comment.