Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setup and teardown for each test using std testing package

I am using go "testing" package. Running my tests like below.

func TestMain(m *testing.M) {     ...    // Setup    os.Exit(m.Run())    // Teardown } 

This will run a setup before any test is run, and a teardown after all tests are complete. And I do need this, as the setup sets the DB up. But also, I need, and yet to find out a way to run a per-test setup/teardown. For the unit tests I am running, I would like to clear the DB before every test, so that there are no issues with the content of the DB causing unexpected behavior.

like image 610
Virtually Real Avatar asked Feb 18 '17 01:02

Virtually Real


People also ask

What is test setUp and tearDown?

This is a set of keywords or instruction to be executed after the start of test suite or test case execution. We will work on a project setup, where will use both setup and teardown. The opening and closing of browser are the common steps in test cases.

What are setUp () and tearDown () methods in mobile app testing?

For that it has two important methods, setUp() and tearDown() . setUp() — This method is called before the invocation of each test method in the given class. tearDown() — This method is called after the invocation of each test method in given class.

Where will you use setUp () and tearDown () methods?

Prepare and Tear Down State for a Test Class XCTest runs setUp() once before the test class begins. If you need to clean up temporary files or capture any data that you want to analyze after the test class is complete, use the tearDown class method on XCTestCase .

What is tearDown in testing?

A teardown test case will execute at the end of your test run within a test folder. Teardown test cases are used to perform post test execution actions. For example, a teardown test case can be used to delete test data generated during test execution.


2 Answers

Update for Go 1.14 (Q1 2020)

The testing package now supports cleanup functions, called after a test or benchmark has finished, by calling T.Cleanup or B.Cleanup respectively. Example,

func TestFunction(t *testing.T) {     // setup code     // sub-tests     t.Run()      t.Run()      ...     // cleanup     t.Cleanup(func(){         //tear-down code     }) } 

Here, t.Cleanup runs after the test and all its sub-tests are complete.


Original answer (Feb. 2017)
As shown in the article "Go unit test setup and teardown" from Kare Nuorteva, you could use a setup function which returns... a teardown function to you defer.

See this gist:

func setupSubTest(t *testing.T) func(t *testing.T) {     t.Log("setup sub test")     return func(t *testing.T) {         t.Log("teardown sub test")     } } 

The setup function is in charge of defining and returning the teardown one.

For each test, for instance in a table-driven test scenario:

for _, tc := range cases {     t.Run(tc.name, func(t *testing.T) {         teardownSubTest := setupSubTest(t)         defer teardownSubTest(t)          result := Sum(tc.a, tc.b)         if result != tc.expected {             t.Fatalf("expected sum %v, but got %v", tc.expected, result)         }     }) } 
like image 142
VonC Avatar answered Sep 20 '22 00:09

VonC


If table driven test pattern works for you, you should stick with it. If you need something more generic and flexible feel free to give https://github.com/houqp/gtest a try.

Here is a quick example:

import (   "strings"   "testing"   "github.com/houqp/gtest" )  type SampleTests struct{}  // Setup and Teardown are invoked per test group run func (s *SampleTests) Setup(t *testing.T)      {} func (s *SampleTests) Teardown(t *testing.T)   {} // BeforeEach and AfterEach are invoked per test run func (s *SampleTests) BeforeEach(t *testing.T) {} func (s *SampleTests) AfterEach(t *testing.T)  {}  func (s *SampleTests) SubTestCompare(t *testing.T) {   if 1 != 1 {     t.FailNow()   } }  func (s *SampleTests) SubTestCheckPrefix(t *testing.T) {   if !strings.HasPrefix("abc", "ab") {     t.FailNow()   } }  func TestSampleTests(t *testing.T) {   gtest.RunSubTests(t, &SampleTests{}) } 
like image 43
houqp Avatar answered Sep 18 '22 00:09

houqp