How to use RunWithData method of test_helpers Package

Best Ginkgo code snippet using test_helpers.RunWithData

Run Ginkgo automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

run_tracker.go

Source: run_tracker.go Github

copy
1package test_helpers
2
3import (
4	"fmt"
5	"strings"
6	"sync"
7
8	"github.com/onsi/ginkgo/v2/formatter"
9	. "github.com/onsi/gomega"
10	"github.com/onsi/gomega/types"
11)
12
13/*
14
15RunTracker tracks invocations of functions - useful to assert orders in which nodes run
16
17*/
18
19type RunTracker struct {
20	lock        *sync.Mutex
21	trackedRuns []string
22	trackedData map[string]map[string]interface{}
23}
24
25func NewRunTracker() *RunTracker {
26	return &RunTracker{
27		lock:        &sync.Mutex{},
28		trackedData: map[string]map[string]interface{}{},
29	}
30}
31
32func (rt *RunTracker) Reset() {
33	rt.lock.Lock()
34	defer rt.lock.Unlock()
35	rt.trackedRuns = []string{}
36}
37
38func (rt *RunTracker) Run(text string) {
39	rt.lock.Lock()
40	defer rt.lock.Unlock()
41	rt.trackedRuns = append(rt.trackedRuns, text)
42}
43
44func (rt *RunTracker) RunWithData(text string, kv ...interface{}) {
45	rt.lock.Lock()
46	defer rt.lock.Unlock()
47	rt.trackedRuns = append(rt.trackedRuns, text)
48	data := map[string]interface{}{}
49	for i := 0; i < len(kv); i += 2 {
50		key := kv[i].(string)
51		value := kv[i+1]
52		data[key] = value
53	}
54	rt.trackedData[text] = data
55}
56
57func (rt *RunTracker) TrackedRuns() []string {
58	rt.lock.Lock()
59	defer rt.lock.Unlock()
60	trackedRuns := make([]string, len(rt.trackedRuns))
61	copy(trackedRuns, rt.trackedRuns)
62	return trackedRuns
63}
64
65func (rt *RunTracker) DataFor(text string) map[string]interface{} {
66	rt.lock.Lock()
67	defer rt.lock.Unlock()
68	return rt.trackedData[text]
69}
70
71func (rt *RunTracker) T(text string, callback ...func()) func() {
72	return func() {
73		rt.Run(text)
74		if len(callback) > 0 {
75			callback[0]()
76		}
77	}
78}
79
80func (rt *RunTracker) C(text string, callback ...func()) func(args []string, additionalArgs []string) {
81	return func(args []string, additionalArgs []string) {
82		rt.RunWithData(text, "Args", args, "AdditionalArgs", additionalArgs)
83		if len(callback) > 0 {
84			callback[0]()
85		}
86	}
87}
88
89func HaveRun(run string) OmegaMatcher {
90	return WithTransform(func(rt *RunTracker) []string {
91		return rt.TrackedRuns()
92	}, ContainElement(run))
93}
94
95func HaveRunWithData(run string, kv ...interface{}) OmegaMatcher {
96	matchers := []types.GomegaMatcher{}
97	for i := 0; i < len(kv); i += 2 {
98		matchers = append(matchers, HaveKeyWithValue(kv[i], kv[i+1]))
99	}
100	return And(
101		HaveRun(run),
102		WithTransform(func(rt *RunTracker) map[string]interface{} {
103			return rt.DataFor(run)
104		}, And(matchers...)),
105	)
106}
107
108func HaveTrackedNothing() OmegaMatcher {
109	return WithTransform(func(rt *RunTracker) []string {
110		return rt.TrackedRuns()
111	}, BeEmpty())
112}
113
114type HaveTrackedMatcher struct {
115	expectedRuns []string
116	message      string
117}
118
119func (m *HaveTrackedMatcher) Match(actual interface{}) (bool, error) {
120	rt, ok := actual.(*RunTracker)
121	if !ok {
122		return false, fmt.Errorf("HaveTracked() must be passed a RunTracker - got %T instead", actual)
123	}
124	actualRuns := rt.TrackedRuns()
125	n := len(actualRuns)
126	if n < len(m.expectedRuns) {
127		n = len(m.expectedRuns)
128	}
129	failureMessage, success := &strings.Builder{}, true
130	fmt.Fprintf(failureMessage, "{{/}}%10s == %-10s{{/}}\n", "Actual", "Expected")
131	fmt.Fprintf(failureMessage, "{{/}}========================\n{{/}}")
132	for i := 0; i < n; i++ {
133		var expected, actual string
134		if i < len(actualRuns) {
135			actual = actualRuns[i]
136		}
137		if i < len(m.expectedRuns) {
138			expected = m.expectedRuns[i]
139		}
140		if actual != expected {
141			success = false
142			fmt.Fprintf(failureMessage, "{{red}}%10s != %-10s{{/}}\n", actual, expected)
143		} else {
144			fmt.Fprintf(failureMessage, "{{green}}%10s == %-10s{{/}}\n", actual, expected)
145		}
146
147	}
148	m.message = failureMessage.String()
149	return success, nil
150
151}
152func (m *HaveTrackedMatcher) FailureMessage(actual interface{}) string {
153	return "Expected runs did not match tracked runs:\n" + formatter.F(m.message)
154
155}
156func (m *HaveTrackedMatcher) NegatedFailureMessage(actual interface{}) string {
157	return "Expected runs matched tracked runs:\n" + formatter.F(m.message)
158}
159
160func HaveTracked(runs ...string) OmegaMatcher {
161	return &HaveTrackedMatcher{expectedRuns: runs}
162}
163
Full Screen

report_after_suite_test.go

Source: report_after_suite_test.go Github

copy
1package internal_integration_test
2
3import (
4	"time"
5
6	. "github.com/onsi/ginkgo/v2"
7	"github.com/onsi/ginkgo/v2/internal/interrupt_handler"
8	. "github.com/onsi/ginkgo/v2/internal/test_helpers"
9	"github.com/onsi/ginkgo/v2/types"
10	. "github.com/onsi/gomega"
11)
12
13var _ = Describe("Sending reports to ReportAfterSuite procs", func() {
14	var failInReportAfterSuiteA, interruptSuiteB bool
15	var fixture func()
16
17	BeforeEach(func() {
18		failInReportAfterSuiteA = false
19		interruptSuiteB = false
20		conf.RandomSeed = 17
21		fixture = func() {
22			BeforeSuite(rt.T("before-suite", func() {
23				outputInterceptor.AppendInterceptedOutput("out-before-suite")
24			}))
25			Context("container", func() {
26				It("A", rt.T("A"))
27				It("B", rt.T("B", func() {
28					F("fail in B")
29				}))
30				It("C", rt.T("C"))
31				PIt("D", rt.T("D"))
32			})
33			ReportAfterSuite("Report A", func(report Report) {
34				rt.RunWithData("report-A", "report", report)
35				writer.Print("gw-report-A")
36				outputInterceptor.AppendInterceptedOutput("out-report-A")
37				if failInReportAfterSuiteA {
38					F("fail in report-A")
39				}
40			})
41			ReportAfterSuite("Report B", func(report Report) {
42				if interruptSuiteB {
43					interruptHandler.Interrupt(interrupt_handler.InterruptCauseTimeout)
44					time.Sleep(100 * time.Millisecond)
45				}
46				rt.RunWithData("report-B", "report", report, "emitted-interrupt", interruptHandler.EmittedInterruptPlaceholderMessage())
47				writer.Print("gw-report-B")
48				outputInterceptor.AppendInterceptedOutput("out-report-B")
49			})
50			AfterSuite(rt.T("after-suite", func() {
51				writer.Print("gw-after-suite")
52				F("fail in after-suite")
53			}))
54
55		}
56	})
57
58	Context("when running in series", func() {
59		BeforeEach(func() {
60			conf.ParallelTotal = 1
61			conf.ParallelProcess = 1
62		})
63
64		Context("the happy path", func() {
65			BeforeEach(func() {
66				success, _ := RunFixture("happy-path", fixture)
67				Ω(success).Should(BeFalse())
68			})
69
70			It("runs all the functions", func() {
71				Ω(rt).Should(HaveTracked(
72					"before-suite",
73					"A", "B", "C",
74					"after-suite",
75					"report-A", "report-B",
76				))
77			})
78
79			It("reports on the report procs", func() {
80				Ω(reporter.Did.Find("Report A")).Should(HavePassed(
81					types.NodeTypeReportAfterSuite,
82					CapturedGinkgoWriterOutput("gw-report-A"),
83					CapturedStdOutput("out-report-A"),
84				))
85
86				Ω(reporter.Did.Find("Report B")).Should(HavePassed(
87					types.NodeTypeReportAfterSuite,
88					CapturedGinkgoWriterOutput("gw-report-B"),
89					CapturedStdOutput("out-report-B"),
90				))
91			})
92
93			It("passes the report in to each reporter", func() {
94				reportA := rt.DataFor("report-A")["report"].(types.Report)
95				reportB := rt.DataFor("report-B")["report"].(types.Report)
96
97				for _, report := range []types.Report{reportA, reportB} {
98					Ω(report.SuiteDescription).Should(Equal("happy-path"))
99					Ω(report.SuiteSucceeded).Should(BeFalse())
100					Ω(report.SuiteConfig.RandomSeed).Should(Equal(int64(17)))
101					reports := Reports(report.SpecReports)
102					Ω(reports.FindByLeafNodeType(types.NodeTypeBeforeSuite)).Should(HavePassed(CapturedStdOutput("out-before-suite")))
103					Ω(reports.Find("A")).Should(HavePassed())
104					Ω(reports.Find("B")).Should(HaveFailed("fail in B"))
105					Ω(reports.Find("C")).Should(HavePassed())
106					Ω(reports.Find("D")).Should(BePending())
107					Ω(reports.FindByLeafNodeType(types.NodeTypeAfterSuite)).Should(HaveFailed("fail in after-suite", CapturedGinkgoWriterOutput("gw-after-suite")))
108				}
109
110				Ω(len(reportB.SpecReports)-len(reportA.SpecReports)).Should(Equal(1), "Report B includes the invocation of ReporteAfterSuite A")
111				Ω(Reports(reportB.SpecReports).Find("Report A")).Should(Equal(reporter.Did.Find("Report A")))
112			})
113		})
114
115		Context("when a ReportAfterSuite proc fails", func() {
116			BeforeEach(func() {
117				failInReportAfterSuiteA = true
118				success, _ := RunFixture("report-A-fails", fixture)
119				Ω(success).Should(BeFalse())
120			})
121
122			It("keeps running subseuqent reporting functions", func() {
123				Ω(rt).Should(HaveTracked(
124					"before-suite",
125					"A", "B", "C",
126					"after-suite",
127					"report-A", "report-B",
128				))
129			})
130
131			It("reports on the faitlure, to Ginkgo's reporter and any subsequent reporters", func() {
132				Ω(reporter.Did.Find("Report A")).Should(HaveFailed(
133					types.NodeTypeReportAfterSuite,
134					"fail in report-A",
135					CapturedGinkgoWriterOutput("gw-report-A"),
136					CapturedStdOutput("out-report-A"),
137				))
138
139				reportB := rt.DataFor("report-B")["report"].(types.Report)
140				Ω(Reports(reportB.SpecReports).Find("Report A")).Should(Equal(reporter.Did.Find("Report A")))
141			})
142		})
143
144		Context("when an interrupt is attempted in a ReportAfterSuiteNode", func() {
145			BeforeEach(func() {
146				interruptSuiteB = true
147				success, _ := RunFixture("report-B-interrupted", fixture)
148				Ω(success).Should(BeFalse())
149			})
150
151			It("ignores the interrupt and soliders on", func() {
152				Ω(rt).Should(HaveTracked(
153					"before-suite",
154					"A", "B", "C",
155					"after-suite",
156					"report-A", "report-B",
157				))
158
159				Ω(rt.DataFor("report-B")["report"]).ShouldNot(BeZero())
160				Ω(rt.DataFor("report-B")["emitted-interrupt"]).Should(ContainSubstring("The running ReportAfterSuite node is at:\n%s", reporter.Did.Find("Report B").LeafNodeLocation.FileName))
161			})
162		})
163	})
164
165	Context("when running in parallel", func() {
166		var otherNodeReport types.Report
167
168		BeforeEach(func() {
169			SetUpForParallel(2)
170
171			otherNodeReport = types.Report{
172				SpecReports: types.SpecReports{
173					types.SpecReport{LeafNodeText: "E", LeafNodeLocation: cl, State: types.SpecStatePassed, LeafNodeType: types.NodeTypeIt},
174					types.SpecReport{LeafNodeText: "F", LeafNodeLocation: cl, State: types.SpecStateSkipped, LeafNodeType: types.NodeTypeIt},
175				},
176			}
177		})
178
179		Context("on proc 1", func() {
180			BeforeEach(func() {
181				conf.ParallelProcess = 1
182			})
183
184			Context("the happy path", func() {
185				BeforeEach(func() {
186					// proc 2 has reported back and exited
187					client.PostSuiteDidEnd(otherNodeReport)
188					close(exitChannels[2])
189					success, _ := RunFixture("happy-path", fixture)
190					Ω(success).Should(BeFalse())
191				})
192
193				It("runs all the functions", func() {
194					Ω(rt).Should(HaveTracked(
195						"before-suite",
196						"A", "B", "C",
197						"after-suite",
198						"report-A", "report-B",
199					))
200				})
201
202				It("passes the report in to each reporter, including information from other procs", func() {
203					reportA := rt.DataFor("report-A")["report"].(types.Report)
204					reportB := rt.DataFor("report-B")["report"].(types.Report)
205
206					for _, report := range []types.Report{reportA, reportB} {
207						Ω(report.SuiteDescription).Should(Equal("happy-path"))
208						Ω(report.SuiteSucceeded).Should(BeFalse())
209						reports := Reports(report.SpecReports)
210						Ω(reports.FindByLeafNodeType(types.NodeTypeBeforeSuite)).Should(HavePassed(CapturedStdOutput("out-before-suite")))
211						Ω(reports.Find("A")).Should(HavePassed())
212						Ω(reports.Find("B")).Should(HaveFailed("fail in B"))
213						Ω(reports.Find("C")).Should(HavePassed())
214						Ω(reports.Find("D")).Should(BePending())
215						Ω(reports.Find("E")).Should(HavePassed())
216						Ω(reports.Find("F")).Should(HaveBeenSkipped())
217						Ω(reports.FindByLeafNodeType(types.NodeTypeAfterSuite)).Should(HaveFailed("fail in after-suite", CapturedGinkgoWriterOutput("gw-after-suite")))
218					}
219
220					Ω(len(reportB.SpecReports)-len(reportA.SpecReports)).Should(Equal(1), "Report B includes the invocation of ReporteAfterSuite A")
221					Ω(Reports(reportB.SpecReports).Find("Report A")).Should(Equal(reporter.Did.Find("Report A")))
222				})
223			})
224
225			Describe("waiting for reports from other procs", func() {
226				It("blocks until the other procs have finished", func() {
227					done := make(chan interface{})
228					go func() {
229						defer GinkgoRecover()
230						success, _ := RunFixture("happy-path", fixture)
231						Ω(success).Should(BeFalse())
232						close(done)
233					}()
234					Consistently(done).ShouldNot(BeClosed())
235					client.PostSuiteDidEnd(otherNodeReport)
236					Consistently(done).ShouldNot(BeClosed())
237					close(exitChannels[2])
238					Eventually(done).Should(BeClosed())
239				})
240			})
241
242			Context("when a non-primary proc disappears before it reports", func() {
243				BeforeEach(func() {
244					close(exitChannels[2]) //proc 2 disappears before reporting
245					success, _ := RunFixture("disappearing-proc-2", fixture)
246					Ω(success).Should(BeFalse())
247				})
248
249				It("does not run the ReportAfterSuite procs", func() {
250					Ω(rt).Should(HaveTracked(
251						"before-suite",
252						"A", "B", "C",
253						"after-suite",
254					))
255				})
256
257				It("reports all the ReportAfterSuite procs as failed", func() {
258					Ω(reporter.Did.Find("Report A")).Should(HaveFailed(types.GinkgoErrors.AggregatedReportUnavailableDueToNodeDisappearing().Error()))
259					Ω(reporter.Did.Find("Report B")).Should(HaveFailed(types.GinkgoErrors.AggregatedReportUnavailableDueToNodeDisappearing().Error()))
260				})
261			})
262		})
263
264		Context("on a non-primary proc", func() {
265			BeforeEach(func() {
266				conf.ParallelProcess = 2
267				success, _ := RunFixture("happy-path", fixture)
268				Ω(success).Should(BeFalse())
269			})
270
271			It("does not run the ReportAfterSuite procs", func() {
272				Ω(rt).Should(HaveTracked(
273					"before-suite",
274					"A", "B", "C",
275					"after-suite",
276				))
277			})
278		})
279	})
280})
281
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)