diff --git a/README.md b/README.md
index b077383..ce0d706 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,7 @@ The project started as a fork of testify, but over time it got its own runner an
+ [XSkip](#xskip)
+ [:rocket: Parametrized tests](#parametrized-test)
+ [Setup test](#setup-test)
+ + [Add ALLURE_ID to the tests before executing BeforeAll function](#Add-ALLURE_ID-to-the-tests-before-executing-BeforeAll-function)
## :zap: Features
@@ -728,10 +729,10 @@ type ParametrizedSuite struct {
ParamCities []string
}
-func (s *ParametrizedSuite) BeforeAll(t provider.T) {
+func (s *ParametrizedSuite) InitTestParams() {
for i := 0; i < 10; i++ {
s.ParamCities = append(s.ParamCities, fake.City())
- }
+ }
}
func (s *ParametrizedSuite) TableTestCities(t provider.T, city string) {
@@ -805,3 +806,39 @@ func TestRunner(t *testing.T) {
Allure output:
![](.resources/example_setup_test.png)
+
+### [Add ALLURE_ID to the tests before executing BeforeAll function](examples/suite_demo/allureid_test.go)
+
+Function `AddAllureIDMapping(testName, allureID string)` allows to set ALLURE_ID label to the test during the suit's tests collecting step.
+If the code into `BeforeAll` function fails, Allure Report will not duplicate testcases in TestOps.
+
+Test code:
+
+```go
+package suite_demo
+
+import (
+ "testing"
+
+ "github.com/ozontech/allure-go/pkg/framework/provider"
+ "github.com/ozontech/allure-go/pkg/framework/suite"
+)
+
+type AllureIdSuite struct {
+ suite.Suite
+}
+
+func (s *AllureIdSuite) BeforeAll(t provider.T) {
+ // code that can fail here
+}
+
+func (s *AllureIdSuite) TestMyTestWithAllureID(t provider.T) {
+ // code of your test here
+}
+
+func TestNewDemo(t *testing.T) {
+ ais := new(AllureIdSuite)
+ ais.AddAllureIDMapping("TestMyTestWithAllureID", "12345")
+ suite.RunSuite(t, ais)
+}
+```
\ No newline at end of file
diff --git a/examples/suite_demo/allureid_test.go b/examples/suite_demo/allureid_test.go
new file mode 100644
index 0000000..2df0442
--- /dev/null
+++ b/examples/suite_demo/allureid_test.go
@@ -0,0 +1,26 @@
+package suite_demo
+
+import (
+ "testing"
+
+ "github.com/ozontech/allure-go/pkg/framework/provider"
+ "github.com/ozontech/allure-go/pkg/framework/suite"
+)
+
+type AllureIdSuite struct {
+ suite.Suite
+}
+
+func (s *AllureIdSuite) BeforeAll(t provider.T) {
+ // code that can fail here
+}
+
+func (s *AllureIdSuite) TestMyTestWithAllureID(t provider.T) {
+ // code of your test here
+}
+
+func TestNewDemo(t *testing.T) {
+ ais := new(AllureIdSuite)
+ ais.AddAllureIDMapping("TestMyTestWithAllureID", "12345")
+ suite.RunSuite(t, ais)
+}
diff --git a/pkg/framework/runner/interfaces.go b/pkg/framework/runner/interfaces.go
index 67fa66f..3754e16 100644
--- a/pkg/framework/runner/interfaces.go
+++ b/pkg/framework/runner/interfaces.go
@@ -32,9 +32,17 @@ type AllureAfterSuite interface {
AfterAll(t provider.T)
}
+// WithTestPramsSuite has an InitTestParams method, which will run before
+// collecting the tests in the suite.
+type WithTestPramsSuite interface {
+ InitTestParams()
+}
+
type TestSuite interface {
GetRunner() TestRunner
SetRunner(runner TestRunner)
+ AddAllureIDMapping(testName, allureID string)
+ FindAllureID(testName string) (id string, ok bool)
}
type TestingT interface {
diff --git a/pkg/framework/runner/suite_runner.go b/pkg/framework/runner/suite_runner.go
index 114e379..a6b678f 100644
--- a/pkg/framework/runner/suite_runner.go
+++ b/pkg/framework/runner/suite_runner.go
@@ -62,11 +62,46 @@ func newSuiteRunner(realT TestingT, packageName, suiteName, parentSuite string,
suite: suite,
}
r = collectTests(r, suite)
+ r = collectParametrizedTests(r, suite)
r = collectHooks(r, suite)
return r
}
+// collectParametrizedTests executes InitTestParams function, finds test methods with tableTestPrefix,
+// gets map with parameters, gets map with parameterized tests,
+// replaces tests in runner with parameterized tests with results
+func collectParametrizedTests(runner *suiteRunner, suite TestSuite) *suiteRunner {
+ if initTestParamsSuit, ok := suite.(WithTestPramsSuite); ok {
+ initTestParamsSuit.InitTestParams()
+ }
+ newTests := make(map[string]Test)
+ for k, v := range runner.tests {
+ newTests[k] = v
+ }
+ for name, test := range runner.tests {
+ if strings.HasPrefix(name, tableTestPrefix) {
+ params, err := getParams(runner.suite, name)
+ if err != nil {
+ panic(err)
+ }
+ temp := getParamTests(test, params)
+ delete(newTests, name)
+ for tName, body := range temp {
+ tResult := body.GetMeta().GetResult()
+ id, ok := suite.FindAllureID(tName)
+ if ok {
+ tResult.AddLabel(allure.IDAllureLabel(id))
+ }
+ newTests[tName] = body
+ runner.internalT.GetProvider().GetSuiteMeta().GetContainer().AddChild(tResult.UUID)
+ }
+ }
+ }
+ runner.tests = newTests
+ return runner
+}
+
// collectTests filters suite methods according to set regular expression and
// adds filtered methods to tests of runner
func collectTests(runner *suiteRunner, suite TestSuite) *suiteRunner {
@@ -81,7 +116,7 @@ func collectTests(runner *suiteRunner, suite TestSuite) *suiteRunner {
method := methodFinder.Method(i)
ok, err := methodFilter(method.Name)
if err != nil {
- _, _ = fmt.Fprintf(os.Stderr, "allire-go: invalid regexp for -m: %s\n", err)
+ _, _ = fmt.Fprintf(os.Stderr, "allure-go: invalid regexp for -m: %s\n", err)
os.Exit(1)
}
@@ -90,6 +125,10 @@ func collectTests(runner *suiteRunner, suite TestSuite) *suiteRunner {
}
testMeta := adapter.NewTestMeta(suiteFullName, suiteName, method.Name, packageName)
+ id, ok := suite.FindAllureID(method.Name)
+ if ok {
+ testMeta.GetResult().AddLabel(allure.IDAllureLabel(id))
+ }
runner.tests[method.Name] = &testMethod{
testMeta: testMeta,
testBody: method,
@@ -107,34 +146,6 @@ type parametrizedTest interface {
GetMeta() provider.TestMeta
}
-// parametrizedWrap executes beforeAll function, finds test methods with tableTestPrefix,
-// gets map with parameters, gets map with parameterized tests,
-// replaces tests in runner with parameterized tests with results
-func parametrizedWrap(runner *suiteRunner, beforeAll func(provider.T)) func(t provider.T) {
- return func(t provider.T) {
- beforeAll(t)
- newTests := make(map[string]Test)
- for k, v := range runner.tests {
- newTests[k] = v
- }
- for name, test := range runner.tests {
- if strings.HasPrefix(name, tableTestPrefix) {
- params, err := getParams(runner.suite, name)
- if err != nil {
- panic(err)
- }
- temp := getParamTests(test, params)
- delete(newTests, name)
- for tName, body := range temp {
- newTests[tName] = body
- runner.internalT.GetProvider().GetSuiteMeta().GetContainer().AddChild(body.GetMeta().GetResult().UUID)
- }
- }
- }
- runner.tests = newTests
- }
-}
-
// getParamTests create instance of TestAdapter for every param from params
// and returns map whose elements are a pair (, )
func getParamTests(parentTest Test, params map[string]interface{}) map[string]Test {
@@ -204,7 +215,7 @@ func getParams(suite TestSuite, methodName string) (res map[string]interface{},
func collectHooks(runner *suiteRunner, suite TestSuite) *suiteRunner {
if beforeAll, ok := suite.(AllureBeforeSuite); ok {
- runner.BeforeAll(parametrizedWrap(runner, beforeAll.BeforeAll))
+ runner.BeforeAll(beforeAll.BeforeAll)
}
if beforeEach, ok := suite.(AllureBeforeTest); ok {
diff --git a/pkg/framework/suite/suite.go b/pkg/framework/suite/suite.go
index 28e97ec..1a94b01 100644
--- a/pkg/framework/suite/suite.go
+++ b/pkg/framework/suite/suite.go
@@ -10,7 +10,20 @@ import (
)
type Suite struct {
- runner runner.TestRunner
+ runner runner.TestRunner
+ allureIDMapping map[string]string
+}
+
+func (s *Suite) AddAllureIDMapping(testName, allureID string) {
+ if s.allureIDMapping == nil {
+ s.allureIDMapping = make(map[string]string)
+ }
+ s.allureIDMapping[testName] = allureID
+}
+
+func (s *Suite) FindAllureID(testName string) (id string, ok bool) {
+ id, ok = s.allureIDMapping[testName]
+ return
}
func (s *Suite) GetRunner() runner.TestRunner {