Skip to content

Commit d14c012

Browse files
authored
spock2: add test plan filter support (via #943)
1 parent 155df5d commit d14c012

File tree

3 files changed

+213
-4
lines changed

3 files changed

+213
-4
lines changed

allure-spock2/src/main/java/io/qameta/allure/spock2/AllureSpock2.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package io.qameta.allure.spock2;
1717

1818
import io.qameta.allure.Allure;
19+
import io.qameta.allure.AllureId;
1920
import io.qameta.allure.AllureLifecycle;
2021
import io.qameta.allure.model.FixtureResult;
2122
import io.qameta.allure.model.Label;
@@ -26,6 +27,10 @@
2627
import io.qameta.allure.model.StepResult;
2728
import io.qameta.allure.model.TestResult;
2829
import io.qameta.allure.model.TestResultContainer;
30+
import io.qameta.allure.testfilter.FileTestPlanSupplier;
31+
import io.qameta.allure.testfilter.TestPlan;
32+
import io.qameta.allure.testfilter.TestPlanUnknown;
33+
import io.qameta.allure.testfilter.TestPlanV1_0;
2934
import io.qameta.allure.util.AnnotationUtils;
3035
import io.qameta.allure.util.ExceptionUtils;
3136
import io.qameta.allure.util.ResultsUtils;
@@ -94,6 +99,8 @@ protected String initialValue() {
9499

95100
private final AllureLifecycle lifecycle;
96101

102+
private final TestPlan testPlan;
103+
97104
@SuppressWarnings("unused")
98105
public AllureSpock2() {
99106
this(Allure.getLifecycle());
@@ -102,6 +109,13 @@ public AllureSpock2() {
102109
public AllureSpock2(final AllureLifecycle lifecycle) {
103110
this.lifecycle = lifecycle;
104111
this.streamsCapturer.addStandardStreamsListener(this);
112+
this.testPlan = new FileTestPlanSupplier().supply().orElse(new TestPlanUnknown());
113+
}
114+
115+
public AllureSpock2(final AllureLifecycle lifecycle, final TestPlan plan) {
116+
this.lifecycle = lifecycle;
117+
this.streamsCapturer.addStandardStreamsListener(this);
118+
this.testPlan = plan;
105119
}
106120

107121
@Override
@@ -111,6 +125,8 @@ public void start() {
111125

112126
@Override
113127
public void visitSpec(final SpecInfo spec) {
128+
spec.getAllFeatures().forEach(methodInfo -> methodInfo.setSkipped(this.isSkipped(methodInfo)));
129+
114130
spec.addListener(this);
115131

116132
final String specContainerUuid = UUID.randomUUID().toString();
@@ -258,7 +274,15 @@ public void beforeIteration(final IterationInfo iteration) {
258274
}
259275

260276
private String getQualifiedName(final IterationInfo iteration) {
261-
return iteration.getFeature().getSpec().getReflection().getName() + "." + iteration.getName();
277+
return this.getQualifiedName(iteration.getFeature().getSpec().getReflection().getName(), iteration.getName());
278+
}
279+
280+
private String getQualifiedName(final FeatureInfo featureInfo) {
281+
return this.getQualifiedName(featureInfo.getSpec().getReflection().getName(), featureInfo.getName());
282+
}
283+
284+
private String getQualifiedName(final String specName, final String testName) {
285+
return specName + "." + testName;
262286
}
263287

264288
private String getHistoryId(final String name, final List<Parameter> parameters) {
@@ -274,6 +298,29 @@ private String getHistoryId(final String name, final List<Parameter> parameters)
274298
return bytesToHex(bytes);
275299
}
276300

301+
private boolean isSkipped(final FeatureInfo featureInfo) {
302+
if (this.testPlan instanceof TestPlanV1_0) {
303+
final TestPlanV1_0 tp = (TestPlanV1_0) testPlan;
304+
return !Objects.isNull(tp.getTests()) && tp.getTests()
305+
.stream()
306+
.filter(Objects::nonNull)
307+
.noneMatch(tc -> this.match(tc, this.getAllureId(featureInfo), this.getQualifiedName(featureInfo)));
308+
}
309+
return false;
310+
}
311+
312+
private String getAllureId(final FeatureInfo featureInfo) {
313+
final AllureId annotation = featureInfo.getFeatureMethod().getAnnotation(AllureId.class);
314+
if (Objects.nonNull(annotation)) {
315+
return annotation.value();
316+
}
317+
return null;
318+
}
319+
320+
private boolean match(final TestPlanV1_0.TestCase tc, final String allureId, final String qualifiedName) {
321+
return Objects.equals(allureId, tc.getId()) || Objects.equals(qualifiedName, tc.getSelector());
322+
}
323+
277324
@Override
278325
public void error(final ErrorInfo error) {
279326
final String uuid = testResults.get();

allure-spock2/src/test/groovy/io/qameta/allure/spock2/AllureSpock2Test.java

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import io.qameta.allure.Step;
2121
import io.qameta.allure.aspects.AttachmentsAspects;
2222
import io.qameta.allure.aspects.StepsAspects;
23-
import io.qameta.allure.junitplatform.AllurePostDiscoveryFilter;
2423
import io.qameta.allure.model.ExecutableItem;
2524
import io.qameta.allure.model.FixtureResult;
2625
import io.qameta.allure.model.Label;
@@ -46,9 +45,12 @@
4645
import io.qameta.allure.spock2.samples.TestWithAnnotationsOnClass;
4746
import io.qameta.allure.spock2.samples.TestWithCustomAnnotations;
4847
import io.qameta.allure.spock2.samples.TestWithSteps;
48+
import io.qameta.allure.spock2.samples.TestsWithIdForFilter;
49+
import io.qameta.allure.test.AllureFeatures;
4950
import io.qameta.allure.test.AllureResults;
5051
import io.qameta.allure.test.AllureResultsWriterStub;
5152
import io.qameta.allure.testfilter.TestPlan;
53+
import io.qameta.allure.testfilter.TestPlanV1_0;
5254
import org.apache.commons.lang3.tuple.Pair;
5355
import org.apache.commons.lang3.tuple.Triple;
5456
import org.junit.jupiter.api.Test;
@@ -494,6 +496,107 @@ void shouldNotMixUpFixturesBetweenTests() {
494496
);
495497
}
496498

499+
private final TestPlanV1_0.TestCase onlyId2 = new TestPlanV1_0.TestCase().setId("2");
500+
private final TestPlanV1_0.TestCase onlyId4 = new TestPlanV1_0.TestCase().setId("4");
501+
502+
private final TestPlanV1_0.TestCase test1 = new TestPlanV1_0.TestCase().setId("1")
503+
.setSelector("io.qameta.allure.spock2.samples.TestsWithIdForFilter.test 1");
504+
private final TestPlanV1_0.TestCase test2 = new TestPlanV1_0.TestCase()
505+
.setId("2")
506+
.setSelector("io.qameta.allure.spock2.samples.TestsWithIdForFilter.test 2");
507+
private final TestPlanV1_0.TestCase test3 = new TestPlanV1_0.TestCase()
508+
.setId("3")
509+
.setSelector("io.qameta.allure.spock2.samples.TestsWithIdForFilter.test 3");
510+
511+
private final TestPlanV1_0.TestCase correctIdIncorrectSelector = new TestPlanV1_0.TestCase()
512+
.setId("4")
513+
.setSelector("io.qameta.allure.spock2.samples.TestsWithIdForFilter_bla.test 3");
514+
private final TestPlanV1_0.TestCase correctIdIncorrectSelectorFailed = new TestPlanV1_0.TestCase()
515+
.setId("6")
516+
.setSelector("io.qameta.allure.spock2.samples.TestsWithIdForFilter_bla.test 3");
517+
private final TestPlanV1_0.TestCase otherId = new TestPlanV1_0.TestCase().setId("4")
518+
.setSelector("io.qameta.allure.spock2.samples.TestsWithIdForFilter.test 1");
519+
private final TestPlanV1_0.TestCase ignored = new TestPlanV1_0.TestCase().setId("5")
520+
.setSelector("io.qameta.allure.testng.samples.TestsWithIdForFilter.test 5");
521+
522+
@Test
523+
@AllureFeatures.Filtration
524+
public void simpleFiltration() {
525+
TestPlanV1_0 plan = new TestPlanV1_0().setTests(Arrays.asList(test1, test2, test3));
526+
List<TestResult> testResults = runClasses(plan, TestsWithIdForFilter.class).getTestResults();
527+
528+
assertThat(testResults)
529+
.hasSize(3)
530+
.extracting(TestResult::getName, TestResult::getStatus)
531+
.contains(
532+
tuple("test 1", Status.PASSED),
533+
tuple("test 2", Status.PASSED),
534+
tuple("test 3", Status.PASSED)
535+
);
536+
}
537+
538+
@Test
539+
@AllureFeatures.Filtration
540+
public void onlyId() {
541+
TestPlanV1_0 plan = new TestPlanV1_0().setTests(Arrays.asList(onlyId2, onlyId4));
542+
List<TestResult> testResults = runClasses(plan, TestsWithIdForFilter.class).getTestResults();
543+
544+
assertThat(testResults)
545+
.hasSize(2)
546+
.extracting(TestResult::getName, TestResult::getStatus)
547+
.contains(
548+
tuple("test 4", Status.PASSED),
549+
tuple("test 2", Status.PASSED)
550+
);
551+
}
552+
553+
@Test
554+
@AllureFeatures.Filtration
555+
public void idAssignToOtherTest() {
556+
TestPlanV1_0 plan = new TestPlanV1_0().setTests(Collections.singletonList(otherId));
557+
List<TestResult> testResults = runClasses(plan, TestsWithIdForFilter.class).getTestResults();
558+
559+
assertThat(testResults)
560+
.hasSize(2)
561+
.extracting(TestResult::getName, TestResult::getStatus)
562+
.contains(
563+
tuple("test 1", Status.PASSED),
564+
tuple("test 4", Status.PASSED)
565+
);
566+
}
567+
568+
@Test
569+
@AllureFeatures.Filtration
570+
public void skippedTest() {
571+
TestPlanV1_0 plan = new TestPlanV1_0().setTests(Arrays.asList(test1, ignored));
572+
List<TestResult> testResults = runClasses(plan, TestsWithIdForFilter.class).getTestResults();
573+
574+
assertThat(testResults)
575+
.hasSize(1)
576+
.extracting(TestResult::getName, TestResult::getStatus)
577+
.contains(
578+
tuple("test 1", Status.PASSED)
579+
);
580+
}
581+
582+
@Test
583+
@AllureFeatures.Filtration
584+
public void correctIdIncorrectSelector() {
585+
TestPlanV1_0 plan = new TestPlanV1_0().setTests(
586+
Arrays.asList(test1, test2, correctIdIncorrectSelector, correctIdIncorrectSelectorFailed)
587+
);
588+
List<TestResult> testResults = runClasses(plan, TestsWithIdForFilter.class).getTestResults();
589+
assertThat(testResults)
590+
.hasSize(4)
591+
.extracting(TestResult::getName, TestResult::getStatus)
592+
.contains(
593+
tuple("test 1", Status.PASSED),
594+
tuple("test 2", Status.PASSED),
595+
tuple("test 4", Status.PASSED),
596+
tuple("test 6", Status.FAILED)
597+
);
598+
}
599+
497600
@Step("Run classes {classes}")
498601
public static AllureResults runClasses(final Class<?>... classes) {
499602
return runClasses(null, classes);
@@ -509,7 +612,6 @@ public static AllureResults runClasses(final TestPlan testPlan, final Class<?>..
509612
.toArray(ClassSelector[]::new);
510613

511614
final LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
512-
.filters(new AllurePostDiscoveryFilter(testPlan))
513615
.selectors(classSelectors)
514616
.build();
515617

@@ -519,7 +621,7 @@ public static AllureResults runClasses(final TestPlan testPlan, final Class<?>..
519621
.andThenTry(GlobalExtensionRegistry.class::cast)
520622
.toOptional()
521623
.orElseThrow(() -> new AssertionError("could not access globalExtensionRegistry field of RunContext"));
522-
extensionRegistry.getGlobalExtensions().add(new AllureSpock2(lifecycle));
624+
extensionRegistry.getGlobalExtensions().add(new AllureSpock2(lifecycle, testPlan));
523625

524626
final LauncherConfig config = LauncherConfig.builder()
525627
.enableTestEngineAutoRegistration(false)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2023 Qameta Software OÜ
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.qameta.allure.spock2.samples
17+
18+
import spock.lang.Ignore;
19+
20+
import io.qameta.allure.AllureId;
21+
import spock.lang.Specification;
22+
23+
class TestsWithIdForFilter extends Specification {
24+
25+
@AllureId("1")
26+
def "test 1"() {
27+
expect:
28+
true
29+
}
30+
31+
@AllureId("2")
32+
def "test 2"() {
33+
expect:
34+
true
35+
}
36+
37+
def "test 3"() {
38+
expect:
39+
true
40+
}
41+
42+
@AllureId("4")
43+
def "test 4"() {
44+
expect:
45+
true
46+
}
47+
48+
@Ignore
49+
@AllureId("5")
50+
def "test 5"() {
51+
expect:
52+
true
53+
}
54+
55+
@AllureId("6")
56+
def "test 6"() {
57+
expect:
58+
false
59+
}
60+
}

0 commit comments

Comments
 (0)