08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
Unit Test & TDD Workshop: Write Tests First
1. Unit Test & TDD
Sendo Workshop
Viet Tran - Sendo Software Architect
viettranx@gmail.com
2. AGENDA
▸ Unit Test: What & Why
▸ Current problems at Sendo and solution
▸ Clean Architecture
▸ TDD - Test Development Driven
▸ Demo: Write Unit Test, the right way
3. WHAT IS UNIT TEST ?
Unit testing is a software development process in which the
smallest testable parts of an application, called units, are
individually and independently scrutinized for proper
operation.
4. WHY UNIT TEST ?
▸ Unit tests detect changes that may break a design contract
▸ Standardize: Unit testing improves the quality of code
▸ Unit testing helps reduce the cost of bug fixes
▸ It's fun
5. EXAMPLE FOR UNIT TEST
func Sum(x int, y int) int {
return x + y
}
func TestSum(t *testing.T) {
total := Sum(5, 5)
expect := 10
assert.Equal(t, 10, total, "should be qual")
}
6. EXAMPLE FOR UNIT TEST
func Sum(x int, y int) int {
return x + y
}
func TestSum(t *testing.T) {
tables := []struct {
args []int
expect int
}{
{[]int{5,5}, 10},
{[]int{8,9}, 17},
{[]int{1,0}, 1},
}
for _, c := tables {
actual := Sum(c.args[0], c.args[1])
assert.Equal(t, actual, c.expect, "should
be qual")
}
}
7. LAUNCHING TESTS
$ go test -v
This picks up any files matching packagename_test.go
$ go test -cover
PASS
coverage: 66.67% of statements
8. CURRENT PROBLEMS AT SENDO
▸ Have no Unit Test, QC have to test manually and full flow.
▸ High tightly coding, every change might break the others.
▸ Huge function body, very hard to maintain.
▸ CI/CD does not support Unit Test checking.
9. CURRENT PROBLEMS AT SENDO (CONTINUE)
LOGIC 1 LOGIC 2 LOGIC 3 LOGIC ...Huge Function
DBConcrete Objects REST CALL SERVICE CALL
It's very hard to maintain these stuff
10. Most of problems in software development
can be solved by delegation
11. HOW DOES DELEGATION WORKS ?
LOGIN CONCRETE LOGIN DB
I know who you are and what exactly you can do
I need to login Just wait until I finish my job
12. HOW DOES DELEGATION WORKS ? (CONTINUE)
LOGIN CONCRETE LOGIN DB
I don't know who you are but what exactly you can do
I need to login Just call and I will implement it.
DELEGATION / ABSTRACTION
13. HOW DOES DELEGATION WORKS ? COME TO TESTING
LOGIN TEST MOCK LOGIN DB
Independently testing: Testing without real DB connection
I need to run testing Simulate all cases of login function
DELEGATION / ABSTRACTION
15. UNIT TEST EXAMPLE: IS IT A GOOD PRACTICE ?
type Thing struct{}
func InsertThing(doc *Thing) error {
session, err := mgo.Dial("localhost")
if err != nil {
return errors.New("Can not connect to db")
}
defer session.Close()
db := session.DB("test")
db.Collection("things").Insert(doc); err != nil {
return errors.New("Can not insert thing")
}
return nil
}
16. UNIT TEST EXAMPLE: IS IT A GOOD PRACTICE ? (CONT.)
It's bad practice.
WHY ?
type Thing struct{}
func InsertThing(doc *Thing) error {
session, err := mgo.Dial("localhost")
if err != nil {
return errors.New("Can not connect to db")
}
defer session.Close()
db := session.DB("test")
db.Collection("things").Insert(doc); err != nil {
return errors.New("Can not insert thing")
}
return nil
}
17. UNIT TEST EXAMPLE (CONTINUE)
type Thing struct{}
func InsertThing(doc *Thing) error {
session, err := mgo.Dial("localhost")
if err != nil {
return errors.New("Can not connect to db")
}
defer session.Close()
db := session.DB("test")
db.Collection("things").Insert(doc); err != nil {
return errors.New("Can not insert thing")
}
return nil
}
CONNECT DB
INSERT THING
18. UNIT TEST EXAMPLE (CONTINUE)
func TestInsertThing(t *testing.T) {
doc := Thing{}
err := InsertThing(&doc)
assert.NotNil(t, err, "should be not nil")
}
A basic Unit Test for InsertThing
19. UNIT TEST EXAMPLE (COVERAGE)
type Thing struct{}
func InsertThing(doc *Thing) error {
session, err := mgo.Dial("localhost")
if err != nil {
return errors.New("Can not connect to db")
}
defer session.Close()
db := session.DB("test")
db.Collection("things").Insert(doc); err != nil {
return errors.New("Can not insert thing")
}
return nil
}
func TestInsertThing(t *testing.T) {
doc := Thing{}
err := InsertThing(&doc)
assert.NotNil(t, err, "should be not nil")
}
▸ We need a real DB Connection.
▸ We cannot cover all cases.
20. UNIT TEST EXAMPLE: SOLUTION
type Thing struct{}
type DataAccessLayer interface {
Insert(collectionName string, docs interface{}) error
}
func InsertThing(dal DataAccessLayer, doc *Thing) error {
if err := dal.Insert("things", doc); err != nil {
log.Println(err)
return err
}
return nil
}
▸ We don' t need a real DB Connection.
▸ We can cover all cases now.
21. So far, at Sendo, we've had a very big source base.
How to apply delegation ?
24. CLEAN ARCHITECTURE: SCALE TO FIT SENDO
USE CASE REPOSITORY MODEL
Implement all RPC methods
Business logic for each method
Implement data accessing
Computing/Processing data
Business model
Implement some validations
Independent flow: Interfaces
25. CLEAN ARCHITECTURE: SCALE TO FIT SENDO (EXAMPLE)
USE CASE REPOSITORY MODEL
UpdateProduct(product) Product
FindProductById(id)
UpdateProduct(product)
MONGO
FindProductById(id)
UpdateProduct(product)
REDIS
Very simple for micro services