github.com/hernad/nomad@v1.6.112/e2e/framework/doc.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 /* 5 Package framework implements a model for developing end-to-end test suites. The 6 model includes a top level Framework which TestSuites can be added to. TestSuites 7 include conditions under which the suite will run and a list of TestCase 8 implementations to run. TestCases can be implemented with methods that run 9 before/after each and all tests. 10 11 # Writing Tests 12 13 Tests follow a similar patterns as go tests. They are functions that must start 14 with 'Test' and instead of a *testing.T argument, a *framework.F is passed and 15 they must have a receiver that implements the TestCase interface. 16 A crude example as follows: 17 18 // foo_test.go 19 type MyTestCase struct { 20 framework.TC 21 } 22 23 func (tc *MyTestCase) TestMyFoo(f *framework.F) { 24 f.T().Log("bar") 25 } 26 27 func TestCalledFromGoTest(t *testing.T){ 28 framework.New().AddSuites(&framework.TestSuite{ 29 Component: "foo", 30 Cases: []framework.TestCase{ 31 new(MyTestCase), 32 }, 33 }).Run(t) 34 } 35 36 Test cases should embed the TC struct which satisfies the TestCase interface. 37 Optionally a TestCase can also implement the Name() function which returns 38 a string to name the test case. By default the name is the name of the struct 39 type, which in the above example would be "MyTestCase" 40 41 Test cases may also optionally implement additional interfaces to define setup 42 and teardown logic: 43 44 BeforeEachTest 45 AfterEachTest 46 BeforeAllTests 47 AfterAllTests 48 49 The test case struct allows you to setup and teardown state in the struct that 50 can be consumed by the tests. For example: 51 52 type ComplexNomadTC struct { 53 framework.TC 54 jobID string 55 } 56 57 func (tc *ComplexNomadTC) BeforeEach(f *framework.F){ 58 // Do some complex job setup with a unique prefix string 59 jobID, err := doSomeComplexSetup(tc.Nomad(), f.ID()) 60 f.NoError(err) 61 f.Set("jobID", jobID) 62 } 63 64 func (tc *ComplexNomadTC) TestSomeScenario(f *framework.F){ 65 jobID := f.Value("jobID").(string) 66 doTestThingWithJob(f, tc.Nomad(), jobID) 67 } 68 69 func (tc *ComplexNomadTC) TestOtherScenario(f *framework.F){ 70 jobID := f.Value("jobID").(string) 71 doOtherTestThingWithJob(f, tc.Nomad(), jobID) 72 } 73 74 func (tc *ComplexNomadTC) AfterEach(f *framework.F){ 75 jobID := f.Value("jobID").(string) 76 _, _, err := tc.Nomad().Jobs().Deregister(jobID, true, nil) 77 f.NoError(err) 78 } 79 80 As demonstrated in the previous example, TC also exposes functions that return 81 configured api clients including Nomad, Consul and Vault. If Consul or Vault 82 are not provisioned their respective getter functions will return nil. 83 84 # Testify Integration 85 86 Test cases expose a T() function to fetch the current *testing.T context. 87 While this means the author is able to most other testing libraries, 88 github.com/stretch/testify is recommended and integrated into the framework. 89 The TC struct also embeds testify assertions that are preconfigured with the 90 current testing context. Additionally TC comes with a Require() method that 91 yields a testify Require if that flavor is desired. 92 93 func (tc *MyTestCase) TestWithTestify() { 94 err := someErrFunc() 95 tc.NoError(err) 96 // Or tc.Require().NoError(err) 97 } 98 99 # Parallelism 100 101 The test framework honors go test's parallel feature under certain conditions. 102 A TestSuite can be created with the Parallel field set to true to enable 103 parallel execution of the test cases of the suite. Tests within a test case 104 will be executed sequentially unless f.T().Parallel() is called. Note that if 105 multiple tests are to be executed in parallel, access to TC is not syncronized. 106 The *framework.F offers a way to store state between before/after each method if 107 desired. 108 109 func (tc *MyTestCase) BeforeEach(f *framework.F){ 110 jobID, _ := doSomeComplexSetup(tc.Nomad(), f.ID()) 111 f.Set("jobID", jobID) 112 } 113 114 func (tc *MyTestCase) TestParallel(f *framework.F){ 115 f.T().Parallel() 116 jobID := f.Value("jobID").(string) 117 } 118 119 Since test cases have the potential to work with a shared Nomad cluster in parallel 120 any resources created or destroyed must be prefixed with a unique identifier for 121 each test case. The framework.F struct exposes an ID() function that will return a 122 string that is unique with in a test. Therefore, multiple tests with in the case 123 can reliably create unique IDs between tests and setup/teardown. The string 124 returned is 8 alpha numeric characters. 125 */ 126 127 // Deprecated: no longer use e2e/framework for new tests; see TestExample for new e2e test structure. 128 package framework