From d413812c06c4b733343a2824e97c2403b6341e2b Mon Sep 17 00:00:00 2001 From: Damien Coraboeuf Date: Mon, 9 Oct 2023 14:46:58 +0000 Subject: [PATCH 1/3] Validation using JUnit tests --- client/runInfo.go | 10 ++++++ client/validations.go | 79 +++++++++++++++++++++++++++++++++++++++++++ cmd/runInfo.go | 15 +++----- cmd/validateTests.go | 72 +++++++-------------------------------- 4 files changed, 106 insertions(+), 70 deletions(-) create mode 100644 client/runInfo.go create mode 100644 client/validations.go diff --git a/client/runInfo.go b/client/runInfo.go new file mode 100644 index 0000000..169c46e --- /dev/null +++ b/client/runInfo.go @@ -0,0 +1,10 @@ +package client + +// RunInfo defines the input for the run info for a build or validation run +type RunInfo struct { + SourceType string `json:"sourceType"` + SourceURI string `json:"sourceUri"` + TriggerType string `json:"triggerType"` + TriggerData string `json:"triggerData"` + RunTime int `json:"runTime"` +} diff --git a/client/validations.go b/client/validations.go new file mode 100644 index 0000000..d3ac55b --- /dev/null +++ b/client/validations.go @@ -0,0 +1,79 @@ +package client + +import ( + "ontrack-cli/config" +) + +func ValidateWithTests( + cfg *config.Config, + project string, + branch string, + build string, + validation string, + description string, + runInfo *RunInfo, + passed int, + skipped int, + failed int, +) error { + + // Mutation payload + var payload struct { + ValidateBuildWithTests struct { + Errors []struct { + Message string + } + } + } + + // Runs the mutation + if err := GraphQLCall(cfg, ` + mutation ValidateBuildWithTests( + $project: String!, + $branch: String!, + $build: String!, + $validationStamp: String!, + $description: String!, + $runInfo: RunInfoInput, + $passed: Int!, + $skipped: Int!, + $failed: Int! + ) { + validateBuildWithTests(input: { + project: $project, + branch: $branch, + build: $build, + validation: $validationStamp, + description: $description, + runInfo: $runInfo, + passed: $passed, + skipped: $skipped, + failed: $failed + }) { + errors { + message + } + } + } + `, map[string]interface{}{ + "project": project, + "branch": branch, + "build": build, + "validationStamp": validation, + "description": description, + "runInfo": runInfo, + "passed": passed, + "skipped": skipped, + "failed": failed, + }, &payload); err != nil { + return err + } + + // Checks for errors + if err := CheckDataErrors(payload.ValidateBuildWithTests.Errors); err != nil { + return err + } + + // OK + return nil +} diff --git a/cmd/runInfo.go b/cmd/runInfo.go index 63b3ca1..1226d10 100644 --- a/cmd/runInfo.go +++ b/cmd/runInfo.go @@ -1,6 +1,8 @@ package cmd import ( + client "ontrack-cli/client" + "github.com/spf13/cobra" ) @@ -12,7 +14,7 @@ func InitRunInfoCommandFlags(cmd *cobra.Command) { cmd.PersistentFlags().Int("run-time", 0, "Run info run time (in seconds)") } -func GetRunInfo(cmd *cobra.Command) (*RunInfo, error) { +func GetRunInfo(cmd *cobra.Command) (*client.RunInfo, error) { sourceType, err := cmd.Flags().GetString("source-type") if err != nil { return nil, err @@ -35,7 +37,7 @@ func GetRunInfo(cmd *cobra.Command) (*RunInfo, error) { } if sourceType != "" || sourceURI != "" || triggerType != "" || triggerData != "" || runTime != 0 { - var info = RunInfo{ + var info = client.RunInfo{ SourceType: sourceType, SourceURI: sourceURI, TriggerType: triggerType, @@ -47,12 +49,3 @@ func GetRunInfo(cmd *cobra.Command) (*RunInfo, error) { return nil, nil } } - -// RunInfo defines the input for the run info for a build or validation run -type RunInfo struct { - SourceType string `json:"sourceType"` - SourceURI string `json:"sourceUri"` - TriggerType string `json:"triggerType"` - TriggerData string `json:"triggerData"` - RunTime int `json:"runTime"` -} diff --git a/cmd/validateTests.go b/cmd/validateTests.go index 6cf02f6..196d776 100644 --- a/cmd/validateTests.go +++ b/cmd/validateTests.go @@ -91,65 +91,19 @@ For example: return err } - // Mutation payload - var payload struct { - ValidateBuildWithTests struct { - Errors []struct { - Message string - } - } - } - - // Runs the mutation - if err := client.GraphQLCall(cfg, ` - mutation ValidateBuildWithTests( - $project: String!, - $branch: String!, - $build: String!, - $validationStamp: String!, - $description: String!, - $runInfo: RunInfoInput, - $passed: Int!, - $skipped: Int!, - $failed: Int! - ) { - validateBuildWithTests(input: { - project: $project, - branch: $branch, - build: $build, - validation: $validationStamp, - description: $description, - runInfo: $runInfo, - passed: $passed, - skipped: $skipped, - failed: $failed - }) { - errors { - message - } - } - } - `, map[string]interface{}{ - "project": project, - "branch": branch, - "build": build, - "validationStamp": validation, - "description": description, - "runInfo": runInfo, - "passed": passed, - "skipped": skipped, - "failed": failed, - }, &payload); err != nil { - return err - } - - // Checks for errors - if err := client.CheckDataErrors(payload.ValidateBuildWithTests.Errors); err != nil { - return err - } - - // OK - return nil + // Call + return client.ValidateWithTests( + cfg, + project, + branch, + build, + validation, + description, + runInfo, + passed, + skipped, + failed, + ) }, } From e16b56e165a6dbfd7faa8d26d7527bb797c48a75 Mon Sep 17 00:00:00 2001 From: Damien Coraboeuf Date: Mon, 6 Nov 2023 15:03:08 +0000 Subject: [PATCH 2/3] feat: validation from JUnit XML files --- cmd/junit/junit.go | 63 +++++++++++ .../junit_reports/junit_report_composite.xml | 104 ++++++++++++++++++ .../junit_reports/junit_report_simple.xml | 36 ++++++ cmd/junit/junit_test.go | 28 +++++ cmd/validateJUnitTests.go | 90 +++++++++++++++ 5 files changed, 321 insertions(+) create mode 100644 cmd/junit/junit.go create mode 100644 cmd/junit/junit_reports/junit_report_composite.xml create mode 100644 cmd/junit/junit_reports/junit_report_simple.xml create mode 100644 cmd/junit/junit_test.go create mode 100644 cmd/validateJUnitTests.go diff --git a/cmd/junit/junit.go b/cmd/junit/junit.go new file mode 100644 index 0000000..7b28cde --- /dev/null +++ b/cmd/junit/junit.go @@ -0,0 +1,63 @@ +package junit + +import ( + "encoding/xml" + "io" + "os" + "path/filepath" +) + +func GetSummaryJUnitTestReports(pattern string) (int, int, int, error) { + // Gets all the matching fields + matches, err := filepath.Glob(pattern) + if err != nil { + return 0, 0, 0, err + } + + // Counts + totalPassed := 0 + totalSkipped := 0 + totalFailed := 0 + + // Getting over all matches + for _, match := range matches { + passed, skipped, failed, err := getSummaryJUnitTestReport(match) + if err != nil { + return 0, 0, 0, err + } + totalPassed += passed + totalSkipped += skipped + totalFailed += failed + } + + // OK + return totalPassed, totalSkipped, totalFailed, nil +} + +type TestSuite struct { + Tests int `xml:"tests,attr"` + Skipped int `xml:"skipped,attr"` + Failures int `xml:"failures,attr"` + Errors int `xml:"errors,attr"` +} + +func getSummaryJUnitTestReport(path string) (int, int, int, error) { + reader, err := os.Open(path) + if err != nil { + return 0, 0, 0, err + } + buf, err := io.ReadAll(reader) + if err != nil { + return 0, 0, 0, err + } + + var root TestSuite + err = xml.Unmarshal(buf, &root) + if err != nil { + return 0, 0, 0, err + } + + passed := root.Tests - root.Skipped - root.Failures - root.Errors + + return passed, root.Skipped, root.Failures + root.Errors, nil +} diff --git a/cmd/junit/junit_reports/junit_report_composite.xml b/cmd/junit/junit_reports/junit_report_composite.xml new file mode 100644 index 0000000..5505fba --- /dev/null +++ b/cmd/junit/junit_reports/junit_report_composite.xml @@ -0,0 +1,104 @@ + + + + + org.opentest4j.AssertionFailedError: Test + at app//org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:43) + at app//org.junit.jupiter.api.Assertions.fail(Assertions.java:146) + at app//org.junit.jupiter.api.AssertionsKt.fail(Assertions.kt:27) + at app//org.junit.jupiter.api.AssertionsKt.fail$default(Assertions.kt:26) + at app//net.nemerosa.ontrack.gitlab.pipeline.SkippedTest.failed(SkippedTest.kt:21) + at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568) + at app//org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725) + at app//org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) + at app//org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) + at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) + at app//org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) + at app//org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) + at app//org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) + at app//org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) + at app//org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) + at app//org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) + at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210) + at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) + at app//org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) + at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) + at java.base@17.0.7/java.util.ArrayList.forEach(ArrayList.java:1511) + at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) + at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) + at java.base@17.0.7/java.util.ArrayList.forEach(ArrayList.java:1511) + at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) + at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) + at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) + at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) + at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) + at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) + at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) + at app//org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) + at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) + at app//org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) + at app//org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94) + at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89) + at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) + at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) + at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.base@17.0.7/java.lang.reflect.Method.invoke(Method.java:568) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) + at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) + at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) + at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) + at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source) + at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) + at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) + at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) + at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) + at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) + at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) + at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) + + + + + + + + + + diff --git a/cmd/junit/junit_reports/junit_report_simple.xml b/cmd/junit/junit_reports/junit_report_simple.xml new file mode 100644 index 0000000..1ef3b13 --- /dev/null +++ b/cmd/junit/junit_reports/junit_report_simple.xml @@ -0,0 +1,36 @@ + + + + + true]], class annotated with @DirtiesContext [false] with mode [null]. + + . ____ _ __ _ _ + /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ +( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ + \\/ ___)| |_)| | | | | || (_| | ) ) ) ) + ' |____| .__|_| |_|_| |_\__, | / / / / + =========|_|==============|___/=/_/_/_/ + :: Spring Boot :: (v2.7.17) + +2023-11-06 15:59:07.791 INFO 51222 --- [ Test worker] n.n.o.g.p.GitlabPipelineApplicationTests : Starting GitlabPipelineApplicationTests using Java 17.0.7 on Damiens-MacBook-Pro.local with PID 51222 (started by damien in /Users/damien/Documents/workspaces/nemerosa/gitlab/ontrack-gitlab-pipeline-test) +2023-11-06 15:59:07.791 INFO 51222 --- [ Test worker] n.n.o.g.p.GitlabPipelineApplicationTests : No active profile set, falling back to 1 default profile: "default" +2023-11-06 15:59:08.235 INFO 51222 --- [ Test worker] n.n.o.g.p.GitlabPipelineApplicationTests : Started GitlabPipelineApplicationTests in 5.576 seconds (JVM running for 5.981) +]]> + + diff --git a/cmd/junit/junit_test.go b/cmd/junit/junit_test.go new file mode 100644 index 0000000..19115d6 --- /dev/null +++ b/cmd/junit/junit_test.go @@ -0,0 +1,28 @@ +package junit + +import ( + "testing" +) + +func TestJUnitParsing(t *testing.T) { + + pattern := "./cmd/junit/junit_reports/*.xml" + + passed, skipped, failed, err := GetSummaryJUnitTestReports(pattern) + if err != nil { + t.Errorf("Error reading the JUnit XML reports: %v", err) + } + + if passed != 3 { + t.Errorf("Passed - Expected: 3, Actual: %v", passed) + } + + if skipped != 1 { + t.Errorf("Skipped - Expected: 1, Actual: %v", skipped) + } + + if failed != 1 { + t.Errorf("Failed - Expected: 1, Actual: %v", failed) + } + +} diff --git a/cmd/validateJUnitTests.go b/cmd/validateJUnitTests.go new file mode 100644 index 0000000..7d23715 --- /dev/null +++ b/cmd/validateJUnitTests.go @@ -0,0 +1,90 @@ +package cmd + +import ( + "github.com/spf13/cobra" + + client "ontrack-cli/client" + "ontrack-cli/cmd/junit" + config "ontrack-cli/config" +) + +var validateJUnitTestsCmd = &cobra.Command{ + Use: "junit", + Short: "Validation with JUnit test data", + Long: `Validation with JUnit XML test data. + +For example: + + ontrack-cli validate -p PROJECT -b BRANCH -n BUILD -v VALIDATION junit --pattern "**/results/*.xml" +`, + RunE: func(cmd *cobra.Command, args []string) error { + project, err := cmd.Flags().GetString("project") + if err != nil { + return err + } + + branch, err := cmd.Flags().GetString("branch") + if err != nil { + return err + } + branch = NormalizeBranchName(branch) + + build, err := cmd.Flags().GetString("build") + if err != nil { + return err + } + + validation, err := cmd.Flags().GetString("validation") + if err != nil { + return err + } + + description, err := cmd.Flags().GetString("description") + if err != nil { + return err + } + + runInfo, err := GetRunInfo(cmd) + if err != nil { + return err + } + + pattern, err := cmd.Flags().GetString("pattern") + if err != nil { + return err + } + + // Get the configuration + cfg, err := config.GetSelectedConfiguration() + if err != nil { + return err + } + + // Parsing of JUnit test reports + passed, skipped, failed, err := junit.GetSummaryJUnitTestReports(pattern) + if err != nil { + return err + } + + // Call + return client.ValidateWithTests( + cfg, + project, + branch, + build, + validation, + description, + runInfo, + passed, + skipped, + failed, + ) + }, +} + +func init() { + validateCmd.AddCommand(validateJUnitTestsCmd) + validateJUnitTestsCmd.Flags().String("pattern", "", "Pattern (glob) to the JUnit XML tests") + // Run info arguments + InitRunInfoCommandFlags(validateJUnitTestsCmd) +} From 37576ab83582d08a9a2206774ed6bb417c6fb9d3 Mon Sep 17 00:00:00 2001 From: Damien Coraboeuf Date: Mon, 6 Nov 2023 15:41:09 +0000 Subject: [PATCH 3/3] chore: fixing the tests --- cmd/junit/junit_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/junit/junit_test.go b/cmd/junit/junit_test.go index 19115d6..2c5f037 100644 --- a/cmd/junit/junit_test.go +++ b/cmd/junit/junit_test.go @@ -6,7 +6,7 @@ import ( func TestJUnitParsing(t *testing.T) { - pattern := "./cmd/junit/junit_reports/*.xml" + pattern := "junit_reports/*.xml" passed, skipped, failed, err := GetSummaryJUnitTestReports(pattern) if err != nil {