SlideShare a Scribd company logo
TDD in Go with 
Ginkgo and Gomega 
Eddy Reyes - eddy@containable.io 
http://www.tasqr.io
About Me 
Eddy Reyes. Cofounder of Tasqr 
(www.tasqr.io) 
● Automates application deployment / 
configuration without code or config files. 
Previously hacked lots of code at: 
● IBM, Lifesize, Click Security
Overview of Presentation 
● Explain what TDD is 
o Not necessarily proselytizing that you must do it. 
o I dislike many TDD-related presentations, they don’t 
match my experience, they don’t stress what’s 
important IMO. 
● What Tools Does Go Have to Help You Do 
TDD? 
o Ginkgo and Gomega, many others
Further TDD Reading 
Uncle Bob Martin 
● http://blog.8thlight.com/uncle-bob/archive.html 
Kent Beck 
● Extreme Programming Explained (book) 
Is TDD Dead? (video debates) 
● Kent Beck, Martin Fowler, DHH 
● https://www.youtube.com/watch?v=z9quxZsLcfo (part 1)
What Isn’t TDD? 
● NOT just having written tests 
● NOT a way to feel like you’re going fast 
● NOT the Silver Bullet that saves software 
engineering 
● NOT like Axe, which makes you irresistible 
to the opposite sex :-)
What Is TDD? 
● A process you follow when writing software. 
● The process goes like this: 
o You write a test that defines an expected outcome in 
your program. 
o You watch the test fail. 
o You change the program until your test passes. 
● Adding tests to an already substantial 
untested program isn’t necessarily TDD.
How Do You Do TDD? 
● In order to effectively follow the TDD pattern, 
you must first understand your design. 
o Tests are rigid. Learning is free-form. 
o You learn by hacking and breaking things. 
o Tests ensure things don’t break. 
● TDD helps you SHIP, not LEARN
Learn vs. Ship 
● Learning is free-form exploration. 
Experiment, play, break things. 
o DO NOT SHIP THIS CODE! 
o After you learn your design, step away from the 
keyboard, and start anew. 
● Shipping 
o Code ends up in a product used by customers. 
o Quality is important!
Tests Are Design! 
● If tests are comprehensive, they are a formal 
specification of your program. 
● Writing a test is expressing the design of 
your program’s functionality. 
● To truly serve as a spec, tests must be: 
o Clean, readable 
o Follow some consistent notation
Test/Spec Notation 
GIVEN 
● Precondition 1...N 
WHEN 
● Call into your program 
THEN 
● Assert Condition 1...N
A Test Framework Needs... 
● Clean, simple notation 
● Clean setup/teardown of dependencies 
o Idempotent, independent tests! 
● Clean separation from tested code 
● Simple runner mechanism 
● Good reporting 
o test results 
o coverage maps
Testing in Go 
● Test runner 
o go test 
● Separates test code from product 
o *_test.go 
● Comes with a test writing library 
o “testing” package 
● Comes with coverage reporting tools 
o Beautiful HTML output
“testing” Package 
● Allows your to write test functions. 
● Nice benchmarking utility 
● Tests are basically blocks of code :( 
func TestXXX(t *testing.T) { 
// setup stuff 
// call your code 
if something.State != WhatIWant { 
t.Fail() 
} 
}
Better Test-Writing Library 
● go command has great tooling. 
● Need a better notation for specifying tests. 
… 
Ginkgo and Gomega is a step forward! 
… but not perfect!
Ginkgo and Gomega 
● Ginkgo 
o Compatible with “go test” but also comes with its 
own test runner 
o BDD-style test notation 
o Expressive structuring of tests 
● Gomega 
o “Matching” library 
o Allows for expressive assert-like statements
Ginkgo 
● Tests expressed as English statements 
o In the BDD tradition of Cucumber, et. al. 
var _ = Describe(“My component”, func() { 
It(“Does something special”, func() { 
MyFunction() 
Expect(MyVar).To(Equal(10)) 
}) 
})
Gomega 
● Assertion language 
Expect(number).To(Equal(10)) 
Expect(value).To(BeNumerically(“<”, 20)) 
Expect(someMap).To(Equal(otherMap)) // does reflect.DeepEqual() 
Expect(someMap).To(BeEquivalent(otherMap)) // allows different types 
Expect(myPtr).ToNot(BeNil()) 
Expect(flag).To(BeFalse()) 
Expect(err).ToNot(HaveOccurred()) 
Expect(err).To(MatchError(“my error message”))
Ginkgo and Dependencies 
● setup/teardown: 
var _ = Describe(“my config object”, func() { 
var ( 
configObj *config.MyConfig 
tempDir string 
) 
BeforeEach(func() { 
var err error 
tempDir, err = ioutil.TempDir(“”, “test-dir”) 
Expect(err).ToNot(HaveOccurred()) 
configObj = config.NewConfig() 
})
Ginkgo and Dependencies 
It(“Saves itself to file”, func() { 
configObj.Save(tempDir) 
restoredConfig := config.FromFile(configObj.Filename) 
Expect(*restoredConfig).To(Equal(*configObj)) 
}) 
AfterEach(func() { 
os.RemoveAll(tempDir) 
}) 
}) // end Describe()
Ginkgo and Dependencies 
● Ginkgo heavily relies on closures and 
closure variables to manage dependencies. 
o Resist the temptation to share state among tests! 
● Nested dependencies 
o Within a Describe block, you can nest: 
 Context block 
 More It’s and Before/AfterEach’s
Nested Dependencies 
var _ = Describe(“My component”) 
var configObj config.MyConfig 
BeforeEach(func() { 
configObj = config.NewConfig() 
}) 
It(“Does test1”, func() { 
// configObj is setup 
})
Nested Dependencies 
Context(“With a fake HTTP server configured”, func() { 
var testServer httptest.Server 
BeforeEach(func() { 
testServer = httptest.NewServer(<fake handler>) 
}) 
It(“Does test2”, func() { 
configObj.ServerUrl = testServer.URL 
configObj.DoSomething() ... 
}) 
})
Testing Notation + Ginkgo 
● Obviously, Ginkgo was not designed with my 
exact notation in mind… 
● However, it maps to it without too much 
difficulty.
Testing Notation + Ginkgo 
var _ = Describe(“my component”, func() { 
// GIVEN 
BeforeEach(func () { 
}) 
It(“Does something useful”, func() { 
// WHEN 
CallSomething() 
// THEN 
Expect(stuff).To((Equal(something)) 
}) 
})
Alternate Notation Style 
var _ = Describe(“my component”, func() { 
BeforeEach(func() {...}) // 
GIVEN 
It(“Does something useful”, func() { // WHEN 
closureVar = CallSomething() 
}) 
AfterEach(func() { 
Expect(closureVar).To(Equal(something)) // THEN 
}) 
})
Ginkgo Bootstrap 
● Ginkgo integrates with go test 
● You must use the ginkgo command to 
generate boilerplate code: 
$ cd mypackage/ # within $GOPATH/src 
$ ginkgo bootstrap 
… 
$ ls 
mypackage_suite_test.go
Ginkgo Bootstrap 
package mypackage_test // NOT THE SAME AS mypackage!!! 
import ( 
. "github.com/onsi/ginkgo" 
. "github.com/onsi/gomega" 
"testing" 
) 
func TestConfig(t *testing.T) { // go test integration boilerplate! 
RegisterFailHandler(Fail) 
RunSpecs(t, "Mypackage Suite") 
}
Ginkgo Generate 
● The generated suite calls the generated test 
files: 
$ ginkgo generate 
… 
$ ls 
mypackage_suite_test.go mypackage_test.go 
… 
$ cat mypackage_test.go 
...
Ginkgo Generate 
package mypackage_test // NOT THE SAME AS mypackage!! 
import ( 
. “mypackage” 
. “github.com/onsi/ginkgo” 
. “github.com/onsi/gomega” 
) 
var _ = Describe(“Mypackage test”, func() { 
})
Assessing Ginkgo/Gomega 
Test Notation 
● The BDD-style english annotations help 
readability a little bit... 
● Closures are a slippery slope! 
o Too much code: declare closure vars, must also 
initialize in BeforeEach to ensure test 
idempotency!
Assessing Ginkgo/Gomega 
● Complex dependencies are doable 
o Accomplished by nesting Describe/Context/ 
BeforeEach’s 
o However, your tests must be inserted in ever-more 
nested closures 
 Can get kinda complicated! 
● Gomega assertions 
o Flow nicely when read aloud 
o Too complex as a formal notation
Assessing Ginkgo/Gomega 
● Overall test notation grade: C+/B-o 
Depends on my mood and how complicated my test 
needs to get. 
o Worst part about it is that your test file easily grows 
way too long, and thus harder to comprehend as a 
spec. 
● Good enough to get our job done with high 
quality at Tasqr.
Go TDD Roundup 
Questions?

More Related Content

PDF
TDD in Python With Pytest
PPTX
Mocking in python
ODP
Automated testing in Python and beyond
 
PDF
Funcargs & other fun with pytest
ODP
Neo4j Graph Database, from PHP
PDF
Unit testing legacy code
PDF
Greach 2015 Spock workshop
PDF
Python Testing Fundamentals
 
TDD in Python With Pytest
Mocking in python
Automated testing in Python and beyond
 
Funcargs & other fun with pytest
Neo4j Graph Database, from PHP
Unit testing legacy code
Greach 2015 Spock workshop
Python Testing Fundamentals
 

What's hot (20)

PDF
POUG Meetup 1st MArch 2019 - utPLSQL v3 - Testing Framework for PL/SQL
PDF
Write unit test from scratch
PDF
Ukoug webinar - testing PLSQL APIs with utPLSQL v3
PDF
Unit testing (eng)
PPT
Presentation_C++UnitTest
PDF
Working With Legacy Code
PPTX
Debugging tricks you wish you knew - Tamir Dresher
PDF
Tdd presentation
PPT
Google C++ Testing Framework in Visual Studio 2008
PPT
Stopping the Rot - Putting Legacy C++ Under Test
PDF
Cursus phpunit
PPTX
Integration Group - Robot Framework
PDF
Developer Tests - Things to Know (Vilnius JUG)
PPTX
Cpp Testing Techniques Tips and Tricks - Cpp Europe
PPTX
Creating a reasonable project boilerplate
PDF
ES3-2020-P2 Bowling Game Kata
PPT
20111018 boost and gtest
PDF
Php unit (eng)
PDF
Robolectric android taipei
PDF
The Evil Tester's Guide to HTTP proxies Tutorial
POUG Meetup 1st MArch 2019 - utPLSQL v3 - Testing Framework for PL/SQL
Write unit test from scratch
Ukoug webinar - testing PLSQL APIs with utPLSQL v3
Unit testing (eng)
Presentation_C++UnitTest
Working With Legacy Code
Debugging tricks you wish you knew - Tamir Dresher
Tdd presentation
Google C++ Testing Framework in Visual Studio 2008
Stopping the Rot - Putting Legacy C++ Under Test
Cursus phpunit
Integration Group - Robot Framework
Developer Tests - Things to Know (Vilnius JUG)
Cpp Testing Techniques Tips and Tricks - Cpp Europe
Creating a reasonable project boilerplate
ES3-2020-P2 Bowling Game Kata
20111018 boost and gtest
Php unit (eng)
Robolectric android taipei
The Evil Tester's Guide to HTTP proxies Tutorial
Ad

Similar to TDD in Go with Ginkgo and Gomega (20)

PDF
Test Driven Development en Go con Ginkgo y Gomega
PDF
Spock pres
PDF
Behavior Driven Education: A Story of Learning ROR
PPTX
Test Driven Development in CQ5/AEM
PDF
North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017
PDF
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
PDF
How to write Testable Javascript
PDF
Test Driven Development in AEM/CQ5
 
PPTX
presentation des google test dans un contexte de tdd
PDF
Bdd and-testing
PDF
Behaviour Driven Development and Thinking About Testing
 
PPTX
Unit Testing and TDD 2017
PDF
Writing Tests with the Unity Test Framework
PDF
Hadoop: Big Data Stacks validation w/ iTest How to tame the elephant?
PDF
UPC Plone Testing Talk
PDF
Deliberate Practice, New Learning Styles (2015)
PPTX
Dart the Better JavaScript
PDF
Getting started with karate dsl
PDF
Test driven development - Zombie proof your code
PDF
TDD and Simple Design Workshop - Session 1 - March 2019
Test Driven Development en Go con Ginkgo y Gomega
Spock pres
Behavior Driven Education: A Story of Learning ROR
Test Driven Development in CQ5/AEM
North Virginia Coldfusion User Group Meetup - Testbox - July 19th 2017
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
How to write Testable Javascript
Test Driven Development in AEM/CQ5
 
presentation des google test dans un contexte de tdd
Bdd and-testing
Behaviour Driven Development and Thinking About Testing
 
Unit Testing and TDD 2017
Writing Tests with the Unity Test Framework
Hadoop: Big Data Stacks validation w/ iTest How to tame the elephant?
UPC Plone Testing Talk
Deliberate Practice, New Learning Styles (2015)
Dart the Better JavaScript
Getting started with karate dsl
Test driven development - Zombie proof your code
TDD and Simple Design Workshop - Session 1 - March 2019
Ad

Recently uploaded (20)

PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PDF
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
DOCX
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
PPTX
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPTX
history of c programming in notes for students .pptx
PDF
Autodesk AutoCAD Crack Free Download 2025
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
17 Powerful Integrations Your Next-Gen MLM Software Needs
PDF
Designing Intelligence for the Shop Floor.pdf
PPTX
L1 - Introduction to python Backend.pptx
PDF
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
PPTX
Monitoring Stack: Grafana, Loki & Promtail
PDF
iTop VPN Free 5.6.0.5262 Crack latest version 2025
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
Digital Systems & Binary Numbers (comprehensive )
PPTX
Why Generative AI is the Future of Content, Code & Creativity?
PDF
AutoCAD Professional Crack 2025 With License Key
PPTX
Oracle Fusion HCM Cloud Demo for Beginners
PDF
medical staffing services at VALiNTRY
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
Greta — No-Code AI for Building Full-Stack Web & Mobile Apps
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
Design an Analysis of Algorithms II-SECS-1021-03
history of c programming in notes for students .pptx
Autodesk AutoCAD Crack Free Download 2025
CHAPTER 2 - PM Management and IT Context
17 Powerful Integrations Your Next-Gen MLM Software Needs
Designing Intelligence for the Shop Floor.pdf
L1 - Introduction to python Backend.pptx
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
Monitoring Stack: Grafana, Loki & Promtail
iTop VPN Free 5.6.0.5262 Crack latest version 2025
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Digital Systems & Binary Numbers (comprehensive )
Why Generative AI is the Future of Content, Code & Creativity?
AutoCAD Professional Crack 2025 With License Key
Oracle Fusion HCM Cloud Demo for Beginners
medical staffing services at VALiNTRY

TDD in Go with Ginkgo and Gomega

  • 1. TDD in Go with Ginkgo and Gomega Eddy Reyes - [email protected] http://www.tasqr.io
  • 2. About Me Eddy Reyes. Cofounder of Tasqr (www.tasqr.io) ● Automates application deployment / configuration without code or config files. Previously hacked lots of code at: ● IBM, Lifesize, Click Security
  • 3. Overview of Presentation ● Explain what TDD is o Not necessarily proselytizing that you must do it. o I dislike many TDD-related presentations, they don’t match my experience, they don’t stress what’s important IMO. ● What Tools Does Go Have to Help You Do TDD? o Ginkgo and Gomega, many others
  • 4. Further TDD Reading Uncle Bob Martin ● http://blog.8thlight.com/uncle-bob/archive.html Kent Beck ● Extreme Programming Explained (book) Is TDD Dead? (video debates) ● Kent Beck, Martin Fowler, DHH ● https://www.youtube.com/watch?v=z9quxZsLcfo (part 1)
  • 5. What Isn’t TDD? ● NOT just having written tests ● NOT a way to feel like you’re going fast ● NOT the Silver Bullet that saves software engineering ● NOT like Axe, which makes you irresistible to the opposite sex :-)
  • 6. What Is TDD? ● A process you follow when writing software. ● The process goes like this: o You write a test that defines an expected outcome in your program. o You watch the test fail. o You change the program until your test passes. ● Adding tests to an already substantial untested program isn’t necessarily TDD.
  • 7. How Do You Do TDD? ● In order to effectively follow the TDD pattern, you must first understand your design. o Tests are rigid. Learning is free-form. o You learn by hacking and breaking things. o Tests ensure things don’t break. ● TDD helps you SHIP, not LEARN
  • 8. Learn vs. Ship ● Learning is free-form exploration. Experiment, play, break things. o DO NOT SHIP THIS CODE! o After you learn your design, step away from the keyboard, and start anew. ● Shipping o Code ends up in a product used by customers. o Quality is important!
  • 9. Tests Are Design! ● If tests are comprehensive, they are a formal specification of your program. ● Writing a test is expressing the design of your program’s functionality. ● To truly serve as a spec, tests must be: o Clean, readable o Follow some consistent notation
  • 10. Test/Spec Notation GIVEN ● Precondition 1...N WHEN ● Call into your program THEN ● Assert Condition 1...N
  • 11. A Test Framework Needs... ● Clean, simple notation ● Clean setup/teardown of dependencies o Idempotent, independent tests! ● Clean separation from tested code ● Simple runner mechanism ● Good reporting o test results o coverage maps
  • 12. Testing in Go ● Test runner o go test ● Separates test code from product o *_test.go ● Comes with a test writing library o “testing” package ● Comes with coverage reporting tools o Beautiful HTML output
  • 13. “testing” Package ● Allows your to write test functions. ● Nice benchmarking utility ● Tests are basically blocks of code :( func TestXXX(t *testing.T) { // setup stuff // call your code if something.State != WhatIWant { t.Fail() } }
  • 14. Better Test-Writing Library ● go command has great tooling. ● Need a better notation for specifying tests. … Ginkgo and Gomega is a step forward! … but not perfect!
  • 15. Ginkgo and Gomega ● Ginkgo o Compatible with “go test” but also comes with its own test runner o BDD-style test notation o Expressive structuring of tests ● Gomega o “Matching” library o Allows for expressive assert-like statements
  • 16. Ginkgo ● Tests expressed as English statements o In the BDD tradition of Cucumber, et. al. var _ = Describe(“My component”, func() { It(“Does something special”, func() { MyFunction() Expect(MyVar).To(Equal(10)) }) })
  • 17. Gomega ● Assertion language Expect(number).To(Equal(10)) Expect(value).To(BeNumerically(“<”, 20)) Expect(someMap).To(Equal(otherMap)) // does reflect.DeepEqual() Expect(someMap).To(BeEquivalent(otherMap)) // allows different types Expect(myPtr).ToNot(BeNil()) Expect(flag).To(BeFalse()) Expect(err).ToNot(HaveOccurred()) Expect(err).To(MatchError(“my error message”))
  • 18. Ginkgo and Dependencies ● setup/teardown: var _ = Describe(“my config object”, func() { var ( configObj *config.MyConfig tempDir string ) BeforeEach(func() { var err error tempDir, err = ioutil.TempDir(“”, “test-dir”) Expect(err).ToNot(HaveOccurred()) configObj = config.NewConfig() })
  • 19. Ginkgo and Dependencies It(“Saves itself to file”, func() { configObj.Save(tempDir) restoredConfig := config.FromFile(configObj.Filename) Expect(*restoredConfig).To(Equal(*configObj)) }) AfterEach(func() { os.RemoveAll(tempDir) }) }) // end Describe()
  • 20. Ginkgo and Dependencies ● Ginkgo heavily relies on closures and closure variables to manage dependencies. o Resist the temptation to share state among tests! ● Nested dependencies o Within a Describe block, you can nest:  Context block  More It’s and Before/AfterEach’s
  • 21. Nested Dependencies var _ = Describe(“My component”) var configObj config.MyConfig BeforeEach(func() { configObj = config.NewConfig() }) It(“Does test1”, func() { // configObj is setup })
  • 22. Nested Dependencies Context(“With a fake HTTP server configured”, func() { var testServer httptest.Server BeforeEach(func() { testServer = httptest.NewServer(<fake handler>) }) It(“Does test2”, func() { configObj.ServerUrl = testServer.URL configObj.DoSomething() ... }) })
  • 23. Testing Notation + Ginkgo ● Obviously, Ginkgo was not designed with my exact notation in mind… ● However, it maps to it without too much difficulty.
  • 24. Testing Notation + Ginkgo var _ = Describe(“my component”, func() { // GIVEN BeforeEach(func () { }) It(“Does something useful”, func() { // WHEN CallSomething() // THEN Expect(stuff).To((Equal(something)) }) })
  • 25. Alternate Notation Style var _ = Describe(“my component”, func() { BeforeEach(func() {...}) // GIVEN It(“Does something useful”, func() { // WHEN closureVar = CallSomething() }) AfterEach(func() { Expect(closureVar).To(Equal(something)) // THEN }) })
  • 26. Ginkgo Bootstrap ● Ginkgo integrates with go test ● You must use the ginkgo command to generate boilerplate code: $ cd mypackage/ # within $GOPATH/src $ ginkgo bootstrap … $ ls mypackage_suite_test.go
  • 27. Ginkgo Bootstrap package mypackage_test // NOT THE SAME AS mypackage!!! import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestConfig(t *testing.T) { // go test integration boilerplate! RegisterFailHandler(Fail) RunSpecs(t, "Mypackage Suite") }
  • 28. Ginkgo Generate ● The generated suite calls the generated test files: $ ginkgo generate … $ ls mypackage_suite_test.go mypackage_test.go … $ cat mypackage_test.go ...
  • 29. Ginkgo Generate package mypackage_test // NOT THE SAME AS mypackage!! import ( . “mypackage” . “github.com/onsi/ginkgo” . “github.com/onsi/gomega” ) var _ = Describe(“Mypackage test”, func() { })
  • 30. Assessing Ginkgo/Gomega Test Notation ● The BDD-style english annotations help readability a little bit... ● Closures are a slippery slope! o Too much code: declare closure vars, must also initialize in BeforeEach to ensure test idempotency!
  • 31. Assessing Ginkgo/Gomega ● Complex dependencies are doable o Accomplished by nesting Describe/Context/ BeforeEach’s o However, your tests must be inserted in ever-more nested closures  Can get kinda complicated! ● Gomega assertions o Flow nicely when read aloud o Too complex as a formal notation
  • 32. Assessing Ginkgo/Gomega ● Overall test notation grade: C+/B-o Depends on my mood and how complicated my test needs to get. o Worst part about it is that your test file easily grows way too long, and thus harder to comprehend as a spec. ● Good enough to get our job done with high quality at Tasqr.
  • 33. Go TDD Roundup Questions?