├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── assert ├── assert.go └── assert_test.go ├── check ├── check.go └── check_test.go ├── example.go └── example_test.go /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizor-games/golang-unittest/63cfe03863473feec8e14c628ef9a5007da7b03d/.gitignore -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.8.x 5 | - 1.9.x 6 | - 1.10.x 7 | - 1.11.x 8 | - master 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Vizor Games 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # golang asserts and checks 2 | 3 | [![Build Status](https://travis-ci.org/vizor-games/golang-unittest.svg)](https://travis-ci.org/vizor-games/golang-unittest) 4 | 5 | Two set of assert and check functions for hard and soft unit test assertions in Go. The golang creators reject to create own testing framework, see [Go FAQ about testing framework](https://golang.org/doc/faq#testing_framework). 6 | 7 | Inspired by: 8 | * [golang-assert](https://github.com/stfsy/golang-assert) 9 | * [python unittest library](https://docs.python.org/3.6/library/unittest.html) 10 | 11 | Improvements: 12 | * check functions 13 | * frendlier error messages, including correct code line from tests 14 | * In function for strings 15 | * Error, NilError functions for functions that returns more than one parameter 16 | * NilErr - short way to check no errors 17 | 18 | The check functions are soft assertions. Failing tests will only be reported to the console via *t.Errorf()*. 19 | The assert functions are hard assertions. Failing tests will be reported to the console via *t.Failf()* and skip the current test execution. 20 | 21 | 22 | ## Check equal 23 | 24 | ```go 25 | import "https://github.com/vizor-games/golang-unittest/check" 26 | 27 | type Person struct { 28 | name string 29 | age int 30 | } 31 | 32 | var paul = Person{ 33 | name: "Paul", 34 | age: 32, 35 | } 36 | 37 | paul2 := paul 38 | 39 | func TestEqual(t *testing.T) { 40 | check.Equal(t, paul, paul2, "Paul equals Paul") 41 | } 42 | ``` 43 | 44 | ## Assert not equal 45 | 46 | ```go 47 | var peter = Person{ 48 | name: "Peter", 49 | age: 21, 50 | } 51 | 52 | func TestNotEqual(t *testing.T) { 53 | assert.NotEqual(t, paul, peter, "Paul does not equal Peter") 54 | ``` 55 | 56 | ## Functions that returns additional error value 57 | 58 | Use assert.J or check.J to convert args... to []interface{}: 59 | 60 | ```go 61 | func TestError(t *testing.T) { 62 | // "err is not nil for unexist file" 63 | assert.Error(t, assert.J(os.Open("unexist.file"))) 64 | } 65 | ``` 66 | 67 | ## Installation 68 | 69 | New way: 70 | ```bash 71 | vgo get github.com/vizor-games/golang-unittest 72 | ``` 73 | 74 | Old way: 75 | ```bash 76 | go get github.com/vizor-games/golang-unittest 77 | ``` 78 | 79 | ## Run tests 80 | 81 | ```bash 82 | go test -v # -v - verbose 83 | go test ./assert 84 | go test ./check 85 | ``` 86 | 87 | ## License 88 | 89 | This project is distributed under the MIT license. 90 | -------------------------------------------------------------------------------- /assert/assert.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "runtime" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func assert(t *testing.T, actual interface{}, expected interface{}, message string, expectation bool) { 10 | if (expected == actual) != expectation { 11 | if message == "" { 12 | message = "Test" 13 | } 14 | buf := make([]byte, 1024) 15 | runtime.Stack(buf, false) 16 | tracepieces := strings.Split(string(buf), "\n") 17 | 18 | // 6-th points to assert-line in test class 19 | if expectation { 20 | t.Fatalf("from %s: %s failed: Expected |%v|, but got |%v|", tracepieces[6], message, expected, actual) 21 | } else { 22 | t.Fatalf("from %s: %s failed: Expected not |%v|, but got |%v|", tracepieces[6], message, expected, actual) 23 | } 24 | } 25 | } 26 | 27 | // Equal checks two parameters have the same type and value 28 | func Equal(t *testing.T, actual interface{}, expected interface{}, message string) { 29 | assert(t, actual, expected, message, true) 30 | } 31 | 32 | // In checks the second string parameter is in the first string parameter 33 | func In(t *testing.T, actual string, substring string, message string) { 34 | if strings.Index(actual, substring) < 0 { 35 | if message == "" { 36 | message = "Test" 37 | } 38 | t.Fatalf("%s failed: Expected substring |%v| in |%v|", message, substring, actual) 39 | } 40 | } 41 | 42 | // NotEqual checks two parameters have the different type or value 43 | func NotEqual(t *testing.T, actual interface{}, expected interface{}, message string) { 44 | assert(t, actual, expected, message, false) 45 | } 46 | 47 | func Error(t *testing.T, params []interface{}) { 48 | assert(t, params[1], nil, "assert.Error", false) 49 | } 50 | 51 | func NilError(t *testing.T, params []interface{}) { 52 | assert(t, params[1], nil, "assert.NilError", true) 53 | } 54 | 55 | func NilErr(t *testing.T, err error) { 56 | assert(t, err, nil, "assert.NilErr", true) 57 | } 58 | 59 | func J(a ...interface{}) []interface{} { 60 | return a 61 | } 62 | -------------------------------------------------------------------------------- /assert/assert_test.go: -------------------------------------------------------------------------------- 1 | package assert 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | type Person struct { 9 | name string 10 | age int 11 | } 12 | 13 | var paul = Person{ 14 | name: "Paul", 15 | age: 32, 16 | } 17 | 18 | var peter = Person{ 19 | name: "Peter", 20 | age: 21, 21 | } 22 | 23 | func TestEqual(t *testing.T) { 24 | Equal(t, paul, paul, "Paul equals Paul") 25 | } 26 | 27 | func TestNotEqual(t *testing.T) { 28 | NotEqual(t, paul, peter, "Paul does not equal Peter") 29 | } 30 | 31 | func TestNotEqualNil(t *testing.T) { 32 | NotEqual(t, paul, nil, "Paul is not nil") 33 | } 34 | 35 | func TestNilEqualNil(t *testing.T) { 36 | Equal(t, nil, nil, "Nil is nil") 37 | } 38 | 39 | func TestIn(t *testing.T) { 40 | In(t, "Paul does not equal Peter", "Paul", "Paul is substring of message") 41 | } 42 | 43 | func TestError(t *testing.T) { 44 | // "err is not nil for unexist file" 45 | Error(t, J(os.Open("unexist.file"))) 46 | } 47 | 48 | func TestNilError(t *testing.T) { 49 | NilError(t, J(os.OpenFile("tempfile.txt", os.O_RDWR|os.O_CREATE, 0755))) 50 | os.Remove("tempfile.txt") 51 | } 52 | 53 | func TestNilErr(t *testing.T) { 54 | NilErr(t, nil) 55 | } 56 | -------------------------------------------------------------------------------- /check/check.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "runtime" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func check(t *testing.T, actual interface{}, expected interface{}, message string, expectation bool) { 10 | if (expected == actual) != expectation { 11 | if message == "" { 12 | message = "Test" 13 | } 14 | buf := make([]byte, 1024) 15 | runtime.Stack(buf, false) 16 | tracepieces := strings.Split(string(buf), "\n") 17 | 18 | // 6-th points to check-line in test class 19 | if expectation { 20 | t.Fatalf("from %s: %s failed: Expected |%v|, but got |%v|", tracepieces[6], message, expected, actual) 21 | } else { 22 | t.Fatalf("from %s: %s failed: Expected not |%v|, but got |%v|", tracepieces[6], message, expected, actual) 23 | } 24 | } 25 | } 26 | 27 | func Equal(t *testing.T, actual interface{}, expected interface{}, message string) { 28 | check(t, actual, expected, message, true) 29 | } 30 | 31 | func In(t *testing.T, actual string, substring string, message string) { 32 | if strings.Index(actual, substring) < 0 { 33 | if message == "" { 34 | message = "Test" 35 | } 36 | t.Errorf("%s failed: Expected substring |%v| in |%v|", message, substring, actual) 37 | } 38 | } 39 | 40 | func NotEqual(t *testing.T, actual interface{}, expected interface{}, message string) { 41 | check(t, actual, expected, message, false) 42 | } 43 | 44 | func Error(t *testing.T, params []interface{}) { 45 | check(t, params[1], nil, "check.Error", false) 46 | } 47 | 48 | func NilError(t *testing.T, params []interface{}) { 49 | check(t, params[1], nil, "check.NilError", true) 50 | } 51 | 52 | func NilErr(t *testing.T, err error) { 53 | check(t, err, nil, "check.NilErr", true) 54 | } 55 | 56 | func J(a ...interface{}) []interface{} { 57 | return a 58 | } 59 | -------------------------------------------------------------------------------- /check/check_test.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | type Person struct { 9 | name string 10 | age int 11 | } 12 | 13 | var paul = Person{ 14 | name: "Paul", 15 | age: 32, 16 | } 17 | 18 | var peter = Person{ 19 | name: "Peter", 20 | age: 21, 21 | } 22 | 23 | func TestEqual(t *testing.T) { 24 | Equal(t, paul, paul, "Paul equals Paul") 25 | } 26 | 27 | func TestNotEqual(t *testing.T) { 28 | NotEqual(t, paul, peter, "Paul does not equal Peter") 29 | } 30 | 31 | func TestNotEqualNil(t *testing.T) { 32 | NotEqual(t, paul, nil, "Paul is not nil") 33 | } 34 | 35 | func TestNilEqualNil(t *testing.T) { 36 | Equal(t, nil, nil, "Nil is nil") 37 | } 38 | 39 | func TestIn(t *testing.T) { 40 | In(t, "Paul does not equal Peter", "Paul", "Paul is substring of message") 41 | } 42 | 43 | func TestError(t *testing.T) { 44 | // "err is not nil for unexist file" 45 | Error(t, J(os.Open("unexist.file"))) 46 | } 47 | 48 | func TestNilError(t *testing.T) { 49 | NilError(t, J(os.OpenFile("tempfile.txt", os.O_RDWR|os.O_CREATE, 0755))) 50 | os.Remove("tempfile.txt") 51 | } 52 | 53 | func TestNilErr(t *testing.T) { 54 | NilErr(t, nil) 55 | } 56 | -------------------------------------------------------------------------------- /example.go: -------------------------------------------------------------------------------- 1 | package golangassert 2 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 1 | package golangassert 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/vizor-games/golang-unittest/assert" 8 | "github.com/vizor-games/golang-unittest/check" 9 | ) 10 | 11 | type Person struct { 12 | name string 13 | age int 14 | } 15 | 16 | var paul = Person{ 17 | name: "Paul", 18 | age: 32, 19 | } 20 | 21 | var peter = Person{ 22 | name: "Peter", 23 | age: 21, 24 | } 25 | 26 | func TestEqual(t *testing.T) { 27 | assert.Equal(t, paul, paul, "Paul equals Paul") 28 | check.Equal(t, paul, paul, "Paul equals Paul") 29 | } 30 | 31 | func TestNotEqual(t *testing.T) { 32 | assert.NotEqual(t, paul, peter, "Paul does not equal Peter") 33 | check.NotEqual(t, paul, peter, "Paul does not equal Peter") 34 | } 35 | 36 | func TestNotEqualNil(t *testing.T) { 37 | assert.NotEqual(t, paul, nil, "Paul is not nil") 38 | check.NotEqual(t, paul, nil, "Paul is not nil") 39 | } 40 | 41 | func TestNilEqualNil(t *testing.T) { 42 | assert.Equal(t, nil, nil, "Nil is nil") 43 | check.Equal(t, nil, nil, "Nil is nil") 44 | } 45 | 46 | func TestIn(t *testing.T) { 47 | assert.In(t, "Paul does not equal Peter", "Paul", "Paul is substring of message") 48 | check.In(t, "Paul does not equal Peter", "Paul", "Paul is substring of message") 49 | } 50 | 51 | func TestError(t *testing.T) { 52 | // "err is not nil for unexist file" 53 | assert.Error(t, assert.J(os.Open("unexist.file"))) 54 | check.Error(t, check.J(os.Open("unexist.file"))) 55 | } 56 | 57 | func TestNilError(t *testing.T) { 58 | assert.NilError(t, assert.J(os.OpenFile("tempfile.txt", os.O_RDWR|os.O_CREATE, 0755))) 59 | check.NilError(t, check.J(os.OpenFile("tempfile.txt", os.O_RDWR|os.O_CREATE, 0755))) 60 | os.Remove("tempfile.txt") 61 | } 62 | 63 | func TestNilErr(t *testing.T) { 64 | assert.NilErr(t, nil) 65 | check.NilErr(t, nil) 66 | } 67 | --------------------------------------------------------------------------------