2020-03-30 Weekend Learnings

March 31, 2020 • edited June 16, 2020

I’ve learned a little bit about frontend testing with chromium web drivers using Agouti and It has proven to be a really good option to write test in Go. Also we are in quarantine so I let you here a WebGL interactive animation to entertain you.

Enjoy

Agouti

Agouti is an universal WebDriver client for Go. I decided to use it because I’m already familiar with Ginkgo and Gomega and I think that it covers my use case, Which is testing simple web applications and APIs from the same code.

You can get started with the Ginkgo cli by running the bootstrap command with the –agouti flag

1
ginkgo bootstrap --agouti

This generates a bootstrap file with the following structure

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package Agouti_test

import (
	"testing"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/sclevine/agouti"
)

func TestAgouti(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Agouti Suite")
}

var agoutiDriver *agouti.WebDriver

var _ = BeforeSuite(func() {
	// Choose a WebDriver:

	// agoutiDriver = agouti.PhantomJS()
	// agoutiDriver = agouti.Selenium()
	agoutiDriver = agouti.ChromeDriver()

	Expect(agoutiDriver.Start()).To(Succeed())
})

var _ = AfterSuite(func() {
	Expect(agoutiDriver.Stop()).To(Succeed())
})

If you are familiar with Ginkgo, you will recognise everything in this file. It’s self explanatory. You have to pay attention to the selected web driver. From my experience, ChromeDriver works well. I do not recommend PhantomJS as it is deprecated.

Now you are ready to start writing your own browser tests. Following the example in the official page, you can create the structure using ginkgo cli.

1
ginkgo generate --agouti user_login
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package Agouti_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/sclevine/agouti"
	. "github.com/sclevine/agouti/matchers"

	. "UNKNOWN_PACKAGE_PATH"
)

var _ = Describe("UserLogin", func() {
	var page *agouti.Page

	BeforeEach(func() {
		var err error
		page, err = agoutiDriver.NewPage()
		Expect(err).NotTo(HaveOccurred())
	})

	AfterEach(func() {
		Expect(page.Destroy()).To(Succeed())
	})
})

I’m not going to copy an paste everything from that page here. Just go to Agouti webpage and read the tutorial.

Genereate a portable binary test

This is the main reason why I’ve chosen Go for writing test. I need to be able to write test and share them with other developers to execute it in their local environment. If you’ve tried to share applications in Python, Java or other programming languages that require heavy environment setup, it’s always annoying. With go, just give execution permissions and you are ready to Go.

To generate a binary from the current tests, you have to run the following command

1
2
3
go test -c
#or
ginkgo build

This will generate a binary file, in my case Agouti.test, that you can run to have the same effect as running go test.

1
./Agouti.test

There is one missing feature for being able to really use this approach. Flags! You can easily add your own flags using the init() function. Here is an example of a flag to select the driver. You can easily extend this to add your own flags. The trick is to define all the flags in the init() section. Note that we are not calling flag.Parse because it is internally called.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

(...)

var driverName string

func init() {
	flag.StringVar(&driverName, "driver", "chromedriver", "The driver to be used")
}

(...)

var _ = BeforeSuite(func() {

	// Choose a WebDriver:
	switch driverName {
	case "chromedriver":
		agoutiDriver = agouti.ChromeDriver()
	case "selenium":
		agoutiDriver = agouti.Selenium()
  default:
		Fail("Invalid driver")
	}

	Expect(agoutiDriver.Start()).To(Succeed())
})

(...)

Now you can run ginkgo with flags or the binary generated

1
2
ginkgo -- --driver selenium
./Agouti.test --driver selenium

If you start the Agouti.test with –help. you will find that all the ginkgo/test flags are still there. Therefore you can do interesting things such as focus specs by pattern, enable verbose output or enabling fail fast.

Conclusion

Go + Ginkgo + Gomega + Agouti are perfect to write portable test suites that can be executed in any system. The next steps will be to add some API testing directly with Go http library and to try Agouti inside a docker container. I think that the docker container will just work inside this image https://hub.docker.com/r/robcherry/docker-chromedriver/

References

blogweekendtestingqualitygo

Coronavirus Trend In Spain

Use Git to track Git versions