Repository: stretchr/testify
Pull request #674 (2018-09-26 20:49:05)

Fix equality assertion panic for values of aliased string type
Please consider this small patch that fixes panic in this egde-case:

```go
type wrapper string

func TestWrappedString(t *testing.T) {
	x := wrapper("x")
	y := wrapper("y")
	assert.Equal(t, x, y)
}
```
results in:

```
=== RUN   TestWrappedString
--- FAIL: TestWrappedString (0.00s)
panic: interface conversion: interface {} is main.wrapper, not string [recovered]
	panic: interface conversion: interface {} is main.wrapper, not string

goroutine 5 [running]:
testing.tRunner.func1(0xc4201260f0)
	/usr/local/go/src/testing/testing.go:742 +0x29d
panic(0x685740, 0xc4200688c0)
	/usr/local/go/src/runtime/panic.go:502 +0x229
github.com/stretchr/testify/assert.diff(0x66b7e0, 0xc42004ec60, 0x66b7e0, 0xc42004ec70, 0x0, 0x0)
	/home/vitaly/go/src/github.com/stretchr/testify/assert/assertions.go:1352 +0x453
github.com/stretchr/testify/assert.Equal(0x709f40, 0xc4201260f0, 0x66b7e0, 0xc42004ec60, 0x66b7e0, 0xc42004ec70, 0x0, 0x0, 0x0, 0x3174eb3300793a18)
	/home/vitaly/go/src/github.com/stretchr/testify/assert/assertions.go:338 +0x26a
_/tmp/dada.TestWrappedString(0xc4201260f0)
	/tmp/check/wrapper_test.go:14 +0xf7
testing.tRunner(0xc4201260f0, 0x6e9370)
	/usr/local/go/src/testing/testing.go:777 +0xd0
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:824 +0x2e0
FAIL	_/tmp/dada	0.005s

```

The problem is that not only values of `string` type satisfy condition `if reflect.TypeOf(value).Kind() == reflect.String`: aliased string types fall under this condition too. 


Patch:
diff --git a/.travis.yml b/.travis.yml
index f408b4c..da6ba0d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,14 +2,18 @@ language: go
 
 sudo: false
 
-go:
-  - "1.8"
-  - "1.9"
-  - "1.10"
-  - tip
-
-script:
-  - ./.travis.gogenerate.sh
-  - ./.travis.gofmt.sh
-  - ./.travis.govet.sh
-  - go test -v -race $(go list ./... | grep -v vendor)
+matrix:
+  include:
+    - go: "1.8.x"
+    - go: "1.9.x"
+    - go: "1.10.x"
+    - go: "1.11.x"
+      env: GO111MODULE=off
+    - go: "1.11.x"
+      env: GO111MODULE=on
+    - go: tip
+  script:
+    - ./.travis.gogenerate.sh
+    - ./.travis.gofmt.sh
+    - ./.travis.govet.sh
+    - go test -v -race $(go list ./... | grep -v vendor)
diff --git a/LICENSE b/LICENSE
index 473b670..f38ec59 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,22 +1,21 @@
-Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell
+MIT License
 
-Please consider promoting this project if you find it useful.
+Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell
 
-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:
+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:
 
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
 
-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.
+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.
diff --git a/README.md b/README.md
index 51b6df3..ef0197e 100644
--- a/README.md
+++ b/README.md
@@ -287,8 +287,10 @@ To install Testify, use `go get`:
 This will then make the following packages available to you:
 
     github.com/stretchr/testify/assert
+    github.com/stretchr/testify/require
     github.com/stretchr/testify/mock
-    github.com/stretchr/testify/http
+    github.com/stretchr/testify/suite
+    github.com/stretchr/testify/http (deprecated)
 
 Import the `testify/assert` package into your code using this template:
 
@@ -319,7 +321,7 @@ To update Testify to the latest version, use `go get -u github.com/stretchr/test
 Supported go versions
 ==================
 
-We support the three major Go versions, which are 1.8, 1.9 and 1.10 at the moment.
+We support the three major Go versions, which are 1.9, 1.10, and 1.11 at the moment.
 
 ------
 
@@ -329,3 +331,12 @@ Contributing
 Please feel free to submit issues, fork the repository and send pull requests!
 
 When submitting an issue, we ask that you please include a complete test function that demonstrates the issue.  Extra credit for those using Testify to write the test code that demonstrates it.
+
+Code generation is used. Look for `CODE GENERATED AUTOMATICALLY` at the top of some files. Run `go generate ./...` to update generated files.
+
+------
+
+License
+=======
+
+This project is licensed under the terms of the MIT license.
diff --git a/assert/assertion_format.go b/assert/assertion_format.go
index aa1c2b9..e0364e9 100644
--- a/assert/assertion_format.go
+++ b/assert/assertion_format.go
@@ -113,6 +113,17 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
 	return Error(t, err, append([]interface{}{msg}, args...)...)
 }
 
+// Eventuallyf asserts that given condition will be met in waitFor time,
+// periodically checking target function each tick.
+//
+//    assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
+func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return Eventually(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)
+}
+
 // Exactlyf asserts that two objects are equal in value and type.
 //
 //    assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
@@ -157,6 +168,31 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool
 	return FileExists(t, path, append([]interface{}{msg}, args...)...)
 }
 
+// Greaterf asserts that the first element is greater than the second
+//
+//    assert.Greaterf(t, 2, 1, "error message %s", "formatted")
+//    assert.Greaterf(t, float64(2, "error message %s", "formatted"), float64(1))
+//    assert.Greaterf(t, "b", "a", "error message %s", "formatted")
+func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return Greater(t, e1, e2, append([]interface{}{msg}, args...)...)
+}
+
+// GreaterOrEqualf asserts that the first element is greater than or equal to the second
+//
+//    assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted")
+//    assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted")
+//    assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted")
+//    assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted")
+func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return GreaterOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)
+}
+
 // HTTPBodyContainsf asserts that a specified handler returns a
 // body that contains a string.
 //
@@ -289,6 +325,14 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int
 	return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
+// YAMLEqf asserts that two YAML strings are equivalent.
+func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return YAMLEq(t, expected, actual, append([]interface{}{msg}, args...)...)
+}
+
 // Lenf asserts that the specified object has specific length.
 // Lenf also fails if the object has a type that len() not accept.
 //
@@ -300,6 +344,31 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf
 	return Len(t, object, length, append([]interface{}{msg}, args...)...)
 }
 
+// Lessf asserts that the first element is less than the second
+//
+//    assert.Lessf(t, 1, 2, "error message %s", "formatted")
+//    assert.Lessf(t, float64(1, "error message %s", "formatted"), float64(2))
+//    assert.Lessf(t, "a", "b", "error message %s", "formatted")
+func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return Less(t, e1, e2, append([]interface{}{msg}, args...)...)
+}
+
+// LessOrEqualf asserts that the first element is less than or equal to the second
+//
+//    assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted")
+//    assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted")
+//    assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted")
+//    assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted")
+func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)
+}
+
 // Nilf asserts that the specified object is nil.
 //
 //    assert.Nilf(t, err, "error message %s", "formatted")
@@ -444,6 +513,19 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in
 	return Regexp(t, rx, str, append([]interface{}{msg}, args...)...)
 }
 
+// Samef asserts that two pointers reference the same object.
+//
+//    assert.Samef(t, ptr1, ptr2, "error message %s", "formatted")
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	return Same(t, expected, actual, append([]interface{}{msg}, args...)...)
+}
+
 // Subsetf asserts that the specified list(array, slice...) contains all
 // elements given in the specified subset(array, slice...).
 //
diff --git a/assert/assertion_forward.go b/assert/assertion_forward.go
index de39f79..2683040 100644
--- a/assert/assertion_forward.go
+++ b/assert/assertion_forward.go
@@ -215,6 +215,28 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
 	return Errorf(a.t, err, msg, args...)
 }
 
+// Eventually asserts that given condition will be met in waitFor time,
+// periodically checking target function each tick.
+//
+//    a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond)
+func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return Eventually(a.t, condition, waitFor, tick, msgAndArgs...)
+}
+
+// Eventuallyf asserts that given condition will be met in waitFor time,
+// periodically checking target function each tick.
+//
+//    a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
+func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return Eventuallyf(a.t, condition, waitFor, tick, msg, args...)
+}
+
 // Exactly asserts that two objects are equal in value and type.
 //
 //    a.Exactly(int32(123), int64(123))
@@ -303,6 +325,56 @@ func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) b
 	return FileExistsf(a.t, path, msg, args...)
 }
 
+// Greater asserts that the first element is greater than the second
+//
+//    a.Greater(2, 1)
+//    a.Greater(float64(2), float64(1))
+//    a.Greater("b", "a")
+func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return Greater(a.t, e1, e2, msgAndArgs...)
+}
+
+// GreaterOrEqual asserts that the first element is greater than or equal to the second
+//
+//    a.GreaterOrEqual(2, 1)
+//    a.GreaterOrEqual(2, 2)
+//    a.GreaterOrEqual("b", "a")
+//    a.GreaterOrEqual("b", "b")
+func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return GreaterOrEqual(a.t, e1, e2, msgAndArgs...)
+}
+
+// GreaterOrEqualf asserts that the first element is greater than or equal to the second
+//
+//    a.GreaterOrEqualf(2, 1, "error message %s", "formatted")
+//    a.GreaterOrEqualf(2, 2, "error message %s", "formatted")
+//    a.GreaterOrEqualf("b", "a", "error message %s", "formatted")
+//    a.GreaterOrEqualf("b", "b", "error message %s", "formatted")
+func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return GreaterOrEqualf(a.t, e1, e2, msg, args...)
+}
+
+// Greaterf asserts that the first element is greater than the second
+//
+//    a.Greaterf(2, 1, "error message %s", "formatted")
+//    a.Greaterf(float64(2, "error message %s", "formatted"), float64(1))
+//    a.Greaterf("b", "a", "error message %s", "formatted")
+func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return Greaterf(a.t, e1, e2, msg, args...)
+}
+
 // HTTPBodyContains asserts that a specified handler returns a
 // body that contains a string.
 //
@@ -567,6 +639,22 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
 	return JSONEqf(a.t, expected, actual, msg, args...)
 }
 
+// YAMLEq asserts that two YAML strings are equivalent.
+func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return YAMLEq(a.t, expected, actual, msgAndArgs...)
+}
+
+// YAMLEqf asserts that two YAML strings are equivalent.
+func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return YAMLEqf(a.t, expected, actual, msg, args...)
+}
+
 // Len asserts that the specified object has specific length.
 // Len also fails if the object has a type that len() not accept.
 //
@@ -589,6 +677,56 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in
 	return Lenf(a.t, object, length, msg, args...)
 }
 
+// Less asserts that the first element is less than the second
+//
+//    a.Less(1, 2)
+//    a.Less(float64(1), float64(2))
+//    a.Less("a", "b")
+func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return Less(a.t, e1, e2, msgAndArgs...)
+}
+
+// LessOrEqual asserts that the first element is less than or equal to the second
+//
+//    a.LessOrEqual(1, 2)
+//    a.LessOrEqual(2, 2)
+//    a.LessOrEqual("a", "b")
+//    a.LessOrEqual("b", "b")
+func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return LessOrEqual(a.t, e1, e2, msgAndArgs...)
+}
+
+// LessOrEqualf asserts that the first element is less than or equal to the second
+//
+//    a.LessOrEqualf(1, 2, "error message %s", "formatted")
+//    a.LessOrEqualf(2, 2, "error message %s", "formatted")
+//    a.LessOrEqualf("a", "b", "error message %s", "formatted")
+//    a.LessOrEqualf("b", "b", "error message %s", "formatted")
+func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return LessOrEqualf(a.t, e1, e2, msg, args...)
+}
+
+// Lessf asserts that the first element is less than the second
+//
+//    a.Lessf(1, 2, "error message %s", "formatted")
+//    a.Lessf(float64(1, "error message %s", "formatted"), float64(2))
+//    a.Lessf("a", "b", "error message %s", "formatted")
+func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return Lessf(a.t, e1, e2, msg, args...)
+}
+
 // Nil asserts that the specified object is nil.
 //
 //    a.Nil(err)
@@ -877,6 +1015,32 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args .
 	return Regexpf(a.t, rx, str, msg, args...)
 }
 
+// Same asserts that two pointers reference the same object.
+//
+//    a.Same(ptr1, ptr2)
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return Same(a.t, expected, actual, msgAndArgs...)
+}
+
+// Samef asserts that two pointers reference the same object.
+//
+//    a.Samef(ptr1, ptr2, "error message %s", "formatted")
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	return Samef(a.t, expected, actual, msg, args...)
+}
+
 // Subset asserts that the specified list(array, slice...) contains all
 // elements given in the specified subset(array, slice...).
 //
diff --git a/assert/assertion_order.go b/assert/assertion_order.go
new file mode 100644
index 0000000..15a486c
--- /dev/null
+++ b/assert/assertion_order.go
@@ -0,0 +1,309 @@
+package assert
+
+import (
+	"fmt"
+	"reflect"
+)
+
+func compare(obj1, obj2 interface{}, kind reflect.Kind) (int, bool) {
+	switch kind {
+	case reflect.Int:
+		{
+			intobj1 := obj1.(int)
+			intobj2 := obj2.(int)
+			if intobj1 > intobj2 {
+				return -1, true
+			}
+			if intobj1 == intobj2 {
+				return 0, true
+			}
+			if intobj1 < intobj2 {
+				return 1, true
+			}
+		}
+	case reflect.Int8:
+		{
+			int8obj1 := obj1.(int8)
+			int8obj2 := obj2.(int8)
+			if int8obj1 > int8obj2 {
+				return -1, true
+			}
+			if int8obj1 == int8obj2 {
+				return 0, true
+			}
+			if int8obj1 < int8obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Int16:
+		{
+			int16obj1 := obj1.(int16)
+			int16obj2 := obj2.(int16)
+			if int16obj1 > int16obj2 {
+				return -1, true
+			}
+			if int16obj1 == int16obj2 {
+				return 0, true
+			}
+			if int16obj1 < int16obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Int32:
+		{
+			int32obj1 := obj1.(int32)
+			int32obj2 := obj2.(int32)
+			if int32obj1 > int32obj2 {
+				return -1, true
+			}
+			if int32obj1 == int32obj2 {
+				return 0, true
+			}
+			if int32obj1 < int32obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Int64:
+		{
+			int64obj1 := obj1.(int64)
+			int64obj2 := obj2.(int64)
+			if int64obj1 > int64obj2 {
+				return -1, true
+			}
+			if int64obj1 == int64obj2 {
+				return 0, true
+			}
+			if int64obj1 < int64obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Uint:
+		{
+			uintobj1 := obj1.(uint)
+			uintobj2 := obj2.(uint)
+			if uintobj1 > uintobj2 {
+				return -1, true
+			}
+			if uintobj1 == uintobj2 {
+				return 0, true
+			}
+			if uintobj1 < uintobj2 {
+				return 1, true
+			}
+		}
+	case reflect.Uint8:
+		{
+			uint8obj1 := obj1.(uint8)
+			uint8obj2 := obj2.(uint8)
+			if uint8obj1 > uint8obj2 {
+				return -1, true
+			}
+			if uint8obj1 == uint8obj2 {
+				return 0, true
+			}
+			if uint8obj1 < uint8obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Uint16:
+		{
+			uint16obj1 := obj1.(uint16)
+			uint16obj2 := obj2.(uint16)
+			if uint16obj1 > uint16obj2 {
+				return -1, true
+			}
+			if uint16obj1 == uint16obj2 {
+				return 0, true
+			}
+			if uint16obj1 < uint16obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Uint32:
+		{
+			uint32obj1 := obj1.(uint32)
+			uint32obj2 := obj2.(uint32)
+			if uint32obj1 > uint32obj2 {
+				return -1, true
+			}
+			if uint32obj1 == uint32obj2 {
+				return 0, true
+			}
+			if uint32obj1 < uint32obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Uint64:
+		{
+			uint64obj1 := obj1.(uint64)
+			uint64obj2 := obj2.(uint64)
+			if uint64obj1 > uint64obj2 {
+				return -1, true
+			}
+			if uint64obj1 == uint64obj2 {
+				return 0, true
+			}
+			if uint64obj1 < uint64obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Float32:
+		{
+			float32obj1 := obj1.(float32)
+			float32obj2 := obj2.(float32)
+			if float32obj1 > float32obj2 {
+				return -1, true
+			}
+			if float32obj1 == float32obj2 {
+				return 0, true
+			}
+			if float32obj1 < float32obj2 {
+				return 1, true
+			}
+		}
+	case reflect.Float64:
+		{
+			float64obj1 := obj1.(float64)
+			float64obj2 := obj2.(float64)
+			if float64obj1 > float64obj2 {
+				return -1, true
+			}
+			if float64obj1 == float64obj2 {
+				return 0, true
+			}
+			if float64obj1 < float64obj2 {
+				return 1, true
+			}
+		}
+	case reflect.String:
+		{
+			stringobj1 := obj1.(string)
+			stringobj2 := obj2.(string)
+			if stringobj1 > stringobj2 {
+				return -1, true
+			}
+			if stringobj1 == stringobj2 {
+				return 0, true
+			}
+			if stringobj1 < stringobj2 {
+				return 1, true
+			}
+		}
+	}
+
+	return 0, false
+}
+
+// Greater asserts that the first element is greater than the second
+//
+//    assert.Greater(t, 2, 1)
+//    assert.Greater(t, float64(2), float64(1))
+//    assert.Greater(t, "b", "a")
+func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+
+	e1Kind := reflect.ValueOf(e1).Kind()
+	e2Kind := reflect.ValueOf(e2).Kind()
+	if e1Kind != e2Kind {
+		return Fail(t, "Elements should be the same type", msgAndArgs...)
+	}
+
+	res, isComparable := compare(e1, e2, e1Kind)
+	if !isComparable {
+		return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...)
+	}
+
+	if res != -1 {
+		return Fail(t, fmt.Sprintf("\"%v\" is not greater than \"%v\"", e1, e2), msgAndArgs...)
+	}
+
+	return true
+}
+
+// GreaterOrEqual asserts that the first element is greater than or equal to the second
+//
+//    assert.GreaterOrEqual(t, 2, 1)
+//    assert.GreaterOrEqual(t, 2, 2)
+//    assert.GreaterOrEqual(t, "b", "a")
+//    assert.GreaterOrEqual(t, "b", "b")
+func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+
+	e1Kind := reflect.ValueOf(e1).Kind()
+	e2Kind := reflect.ValueOf(e2).Kind()
+	if e1Kind != e2Kind {
+		return Fail(t, "Elements should be the same type", msgAndArgs...)
+	}
+
+	res, isComparable := compare(e1, e2, e1Kind)
+	if !isComparable {
+		return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...)
+	}
+
+	if res != -1 && res != 0 {
+		return Fail(t, fmt.Sprintf("\"%v\" is not greater than or equal to \"%v\"", e1, e2), msgAndArgs...)
+	}
+
+	return true
+}
+
+// Less asserts that the first element is less than the second
+//
+//    assert.Less(t, 1, 2)
+//    assert.Less(t, float64(1), float64(2))
+//    assert.Less(t, "a", "b")
+func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+
+	e1Kind := reflect.ValueOf(e1).Kind()
+	e2Kind := reflect.ValueOf(e2).Kind()
+	if e1Kind != e2Kind {
+		return Fail(t, "Elements should be the same type", msgAndArgs...)
+	}
+
+	res, isComparable := compare(e1, e2, e1Kind)
+	if !isComparable {
+		return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...)
+	}
+
+	if res != 1 {
+		return Fail(t, fmt.Sprintf("\"%v\" is not less than \"%v\"", e1, e2), msgAndArgs...)
+	}
+
+	return true
+}
+
+// LessOrEqual asserts that the first element is less than or equal to the second
+//
+//    assert.LessOrEqual(t, 1, 2)
+//    assert.LessOrEqual(t, 2, 2)
+//    assert.LessOrEqual(t, "a", "b")
+//    assert.LessOrEqual(t, "b", "b")
+func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+
+	e1Kind := reflect.ValueOf(e1).Kind()
+	e2Kind := reflect.ValueOf(e2).Kind()
+	if e1Kind != e2Kind {
+		return Fail(t, "Elements should be the same type", msgAndArgs...)
+	}
+
+	res, isComparable := compare(e1, e2, e1Kind)
+	if !isComparable {
+		return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...)
+	}
+
+	if res != 1 && res != 0 {
+		return Fail(t, fmt.Sprintf("\"%v\" is not less than or equal to \"%v\"", e1, e2), msgAndArgs...)
+	}
+
+	return true
+}
diff --git a/assert/assertions.go b/assert/assertions.go
index 5bdec56..044da8b 100644
--- a/assert/assertions.go
+++ b/assert/assertions.go
@@ -18,6 +18,7 @@ import (
 
 	"github.com/davecgh/go-spew/spew"
 	"github.com/pmezard/go-difflib/difflib"
+	yaml "gopkg.in/yaml.v2"
 )
 
 //go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_format.go.tmpl
@@ -39,7 +40,7 @@ type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool
 // for table driven tests.
 type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool
 
-// ValuesAssertionFunc is a common function prototype when validating an error value.  Can be useful
+// ErrorAssertionFunc is a common function prototype when validating an error value.  Can be useful
 // for table driven tests.
 type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool
 
@@ -179,7 +180,11 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
 		return ""
 	}
 	if len(msgAndArgs) == 1 {
-		return msgAndArgs[0].(string)
+		msg := msgAndArgs[0]
+		if msgAsStr, ok := msg.(string); ok {
+			return msgAsStr
+		}
+		return fmt.Sprintf("%+v", msg)
 	}
 	if len(msgAndArgs) > 1 {
 		return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
@@ -346,6 +351,37 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{})
 
 }
 
+// Same asserts that two pointers reference the same object.
+//
+//    assert.Same(t, ptr1, ptr2)
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+
+	expectedPtr, actualPtr := reflect.ValueOf(expected), reflect.ValueOf(actual)
+	if expectedPtr.Kind() != reflect.Ptr || actualPtr.Kind() != reflect.Ptr {
+		return Fail(t, "Invalid operation: both arguments must be pointers", msgAndArgs...)
+	}
+
+	expectedType, actualType := reflect.TypeOf(expected), reflect.TypeOf(actual)
+	if expectedType != actualType {
+		return Fail(t, fmt.Sprintf("Pointer expected to be of type %v, but was %v",
+			expectedType, actualType), msgAndArgs...)
+	}
+
+	if expected != actual {
+		return Fail(t, fmt.Sprintf("Not same: \n"+
+			"expected: %p %#v\n"+
+			"actual  : %p %#v", expected, expected, actual, actual), msgAndArgs...)
+	}
+
+	return true
+}
+
 // formatUnequalValues takes two values of arbitrary types and returns string
 // representations appropriate to be presented to the user.
 //
@@ -415,6 +451,17 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
 	return Fail(t, "Expected value not to be nil.", msgAndArgs...)
 }
 
+// containsKind checks if a specified kind in the slice of kinds.
+func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool {
+	for i := 0; i < len(kinds); i++ {
+		if kind == kinds[i] {
+			return true
+		}
+	}
+
+	return false
+}
+
 // isNil checks if a specified object is nil or not, without Failing.
 func isNil(object interface{}) bool {
 	if object == nil {
@@ -423,7 +470,14 @@ func isNil(object interface{}) bool {
 
 	value := reflect.ValueOf(object)
 	kind := value.Kind()
-	if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() {
+	isNilableKind := containsKind(
+		[]reflect.Kind{
+			reflect.Chan, reflect.Func,
+			reflect.Interface, reflect.Map,
+			reflect.Ptr, reflect.Slice},
+		kind)
+
+	if isNilableKind && value.IsNil() {
 		return true
 	}
 
@@ -457,14 +511,14 @@ func isEmpty(object interface{}) bool {
 	// collection types are empty when they have no element
 	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
 		return objValue.Len() == 0
-	// pointers are empty if nil or if the value they point to is empty
+		// pointers are empty if nil or if the value they point to is empty
 	case reflect.Ptr:
 		if objValue.IsNil() {
 			return true
 		}
 		deref := objValue.Elem().Interface()
 		return isEmpty(deref)
-	// for all other types, compare against the zero value
+		// for all other types, compare against the zero value
 	default:
 		zero := reflect.Zero(objValue.Type())
 		return reflect.DeepEqual(object, zero.Interface())
@@ -607,7 +661,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{
 func includeElement(list interface{}, element interface{}) (ok, found bool) {
 
 	listValue := reflect.ValueOf(list)
-	elementValue := reflect.ValueOf(element)
+	listKind := reflect.TypeOf(list).Kind()
 	defer func() {
 		if e := recover(); e != nil {
 			ok = false
@@ -615,11 +669,12 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) {
 		}
 	}()
 
-	if reflect.TypeOf(list).Kind() == reflect.String {
+	if listKind == reflect.String {
+		elementValue := reflect.ValueOf(element)
 		return true, strings.Contains(listValue.String(), elementValue.String())
 	}
 
-	if reflect.TypeOf(list).Kind() == reflect.Map {
+	if listKind == reflect.Map {
 		mapKeys := listValue.MapKeys()
 		for i := 0; i < len(mapKeys); i++ {
 			if ObjectsAreEqual(mapKeys[i].Interface(), element) {
@@ -1315,6 +1370,24 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{
 	return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)
 }
 
+// YAMLEq asserts that two YAML strings are equivalent.
+func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	var expectedYAMLAsInterface, actualYAMLAsInterface interface{}
+
+	if err := yaml.Unmarshal([]byte(expected), &expectedYAMLAsInterface); err != nil {
+		return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...)
+	}
+
+	if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil {
+		return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...)
+	}
+
+	return Equal(t, expectedYAMLAsInterface, actualYAMLAsInterface, msgAndArgs...)
+}
+
 func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
 	t := reflect.TypeOf(v)
 	k := t.Kind()
@@ -1327,7 +1400,7 @@ func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
 }
 
 // diff returns a diff of both values as long as both are of the same type and
-// are a struct, map, slice or array. Otherwise it returns an empty string.
+// are a struct, map, slice, array or string. Otherwise it returns an empty string.
 func diff(expected interface{}, actual interface{}) string {
 	if expected == nil || actual == nil {
 		return ""
@@ -1345,12 +1418,12 @@ func diff(expected interface{}, actual interface{}) string {
 	}
 
 	var e, a string
-	if ek != reflect.String {
+	if et != reflect.TypeOf("") {
 		e = spewConfig.Sdump(expected)
 		a = spewConfig.Sdump(actual)
 	} else {
-		e = expected.(string)
-		a = actual.(string)
+		e = reflect.ValueOf(expected).String()
+		a = reflect.ValueOf(actual).String()
 	}
 
 	diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
@@ -1392,3 +1465,34 @@ var spewConfig = spew.ConfigState{
 type tHelper interface {
 	Helper()
 }
+
+// Eventually asserts that given condition will be met in waitFor time,
+// periodically checking target function each tick.
+//
+//    assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)
+func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+
+	timer := time.NewTimer(waitFor)
+	ticker := time.NewTicker(tick)
+	checkPassed := make(chan bool)
+	defer timer.Stop()
+	defer ticker.Stop()
+	defer close(checkPassed)
+	for {
+		select {
+		case <-timer.C:
+			return Fail(t, "Condition never satisfied", msgAndArgs...)
+		case result := <-checkPassed:
+			if result {
+				return true
+			}
+		case <-ticker.C:
+			go func() {
+				checkPassed <- condition()
+			}()
+		}
+	}
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..5053648
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,8 @@
+module github.com/stretchr/testify
+
+require (
+	github.com/davecgh/go-spew v1.1.0
+	github.com/pmezard/go-difflib v1.0.0
+	github.com/stretchr/objx v0.1.0
+	gopkg.in/yaml.v2 v2.2.2
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..cccb647
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,9 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/mock/mock.go b/mock/mock.go
index cc4f642..d6694ed 100644
--- a/mock/mock.go
+++ b/mock/mock.go
@@ -176,6 +176,7 @@ func (c *Call) Maybe() *Call {
 //    Mock.
 //       On("MyMethod", 1).Return(nil).
 //       On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
+//go:noinline
 func (c *Call) On(methodName string, arguments ...interface{}) *Call {
 	return c.Parent.On(methodName, arguments...)
 }
@@ -691,7 +692,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
 				output = fmt.Sprintf("%s\t%d: PASS:  %s matched by %s\n", output, i, actualFmt, matcher)
 			} else {
 				differences++
-				output = fmt.Sprintf("%s\t%d: PASS:  %s not matched by %s\n", output, i, actualFmt, matcher)
+				output = fmt.Sprintf("%s\t%d: FAIL:  %s not matched by %s\n", output, i, actualFmt, matcher)
 			}
 		} else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
 
diff --git a/require/require.go b/require/require.go
index 535f293..c5903f5 100644
--- a/require/require.go
+++ b/require/require.go
@@ -14,23 +14,23 @@ import (
 
 // Condition uses a Comparison to assert a complex condition.
 func Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) {
-	if assert.Condition(t, comp, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Condition(t, comp, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // Conditionf uses a Comparison to assert a complex condition.
 func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) {
-	if assert.Conditionf(t, comp, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Conditionf(t, comp, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -41,12 +41,12 @@ func Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interfac
 //    assert.Contains(t, ["Hello", "World"], "World")
 //    assert.Contains(t, {"Hello": "World"}, "Hello")
 func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
-	if assert.Contains(t, s, contains, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Contains(t, s, contains, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -57,34 +57,34 @@ func Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...int
 //    assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
 //    assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
 func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {
-	if assert.Containsf(t, s, contains, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Containsf(t, s, contains, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
 func DirExists(t TestingT, path string, msgAndArgs ...interface{}) {
-	if assert.DirExists(t, path, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.DirExists(t, path, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
 func DirExistsf(t TestingT, path string, msg string, args ...interface{}) {
-	if assert.DirExistsf(t, path, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.DirExistsf(t, path, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -94,12 +94,12 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) {
 //
 // assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
 func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) {
-	if assert.ElementsMatch(t, listA, listB, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.ElementsMatch(t, listA, listB, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -109,12 +109,12 @@ func ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs
 //
 // assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
 func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) {
-	if assert.ElementsMatchf(t, listA, listB, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.ElementsMatchf(t, listA, listB, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -123,12 +123,12 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
 //
 //  assert.Empty(t, obj)
 func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
-	if assert.Empty(t, object, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Empty(t, object, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -137,12 +137,12 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
 //
 //  assert.Emptyf(t, obj, "error message %s", "formatted")
 func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) {
-	if assert.Emptyf(t, object, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Emptyf(t, object, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -154,12 +154,12 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) {
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
-	if assert.Equal(t, expected, actual, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Equal(t, expected, actual, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -169,12 +169,12 @@ func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...i
 //   actualObj, err := SomeFunction()
 //   assert.EqualError(t, err,  expectedErrorString)
 func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {
-	if assert.EqualError(t, theError, errString, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.EqualError(t, theError, errString, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -184,12 +184,12 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte
 //   actualObj, err := SomeFunction()
 //   assert.EqualErrorf(t, err,  expectedErrorString, "error message %s", "formatted")
 func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) {
-	if assert.EqualErrorf(t, theError, errString, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.EqualErrorf(t, theError, errString, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -198,12 +198,12 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args
 //
 //    assert.EqualValues(t, uint32(123), int32(123))
 func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
-	if assert.EqualValues(t, expected, actual, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.EqualValues(t, expected, actual, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -212,12 +212,12 @@ func EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArg
 //
 //    assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
 func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
-	if assert.EqualValuesf(t, expected, actual, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.EqualValuesf(t, expected, actual, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -229,12 +229,12 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
-	if assert.Equalf(t, expected, actual, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Equalf(t, expected, actual, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -245,12 +245,12 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar
 // 	   assert.Equal(t, expectedError, err)
 //   }
 func Error(t TestingT, err error, msgAndArgs ...interface{}) {
-	if assert.Error(t, err, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Error(t, err, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -261,9 +261,37 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) {
 // 	   assert.Equal(t, expectedErrorf, err)
 //   }
 func Errorf(t TestingT, err error, msg string, args ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if assert.Errorf(t, err, msg, args...) {
 		return
 	}
+	t.FailNow()
+}
+
+// Eventually asserts that given condition will be met in waitFor time,
+// periodically checking target function each tick.
+//
+//    assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)
+func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {
+	if assert.Eventually(t, condition, waitFor, tick, msgAndArgs...) {
+		return
+	}
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	t.FailNow()
+}
+
+// Eventuallyf asserts that given condition will be met in waitFor time,
+// periodically checking target function each tick.
+//
+//    assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
+func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {
+	if assert.Eventuallyf(t, condition, waitFor, tick, msg, args...) {
+		return
+	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
@@ -274,12 +302,12 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) {
 //
 //    assert.Exactly(t, int32(123), int64(123))
 func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
-	if assert.Exactly(t, expected, actual, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Exactly(t, expected, actual, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -287,56 +315,56 @@ func Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ..
 //
 //    assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
 func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
-	if assert.Exactlyf(t, expected, actual, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Exactlyf(t, expected, actual, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // Fail reports a failure through
 func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
-	if assert.Fail(t, failureMessage, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Fail(t, failureMessage, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // FailNow fails test
 func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) {
-	if assert.FailNow(t, failureMessage, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.FailNow(t, failureMessage, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // FailNowf fails test
 func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) {
-	if assert.FailNowf(t, failureMessage, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.FailNowf(t, failureMessage, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // Failf reports a failure through
 func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) {
-	if assert.Failf(t, failureMessage, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Failf(t, failureMessage, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -344,12 +372,12 @@ func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) {
 //
 //    assert.False(t, myBool)
 func False(t TestingT, value bool, msgAndArgs ...interface{}) {
-	if assert.False(t, value, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.False(t, value, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -357,34 +385,96 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) {
 //
 //    assert.Falsef(t, myBool, "error message %s", "formatted")
 func Falsef(t TestingT, value bool, msg string, args ...interface{}) {
-	if assert.Falsef(t, value, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Falsef(t, value, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
 func FileExists(t TestingT, path string, msgAndArgs ...interface{}) {
-	if assert.FileExists(t, path, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.FileExists(t, path, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
 func FileExistsf(t TestingT, path string, msg string, args ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if assert.FileExistsf(t, path, msg, args...) {
 		return
 	}
+	t.FailNow()
+}
+
+// Greater asserts that the first element is greater than the second
+//
+//    assert.Greater(t, 2, 1)
+//    assert.Greater(t, float64(2), float64(1))
+//    assert.Greater(t, "b", "a")
+func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.Greater(t, e1, e2, msgAndArgs...) {
+		return
+	}
+	t.FailNow()
+}
+
+// GreaterOrEqual asserts that the first element is greater than or equal to the second
+//
+//    assert.GreaterOrEqual(t, 2, 1)
+//    assert.GreaterOrEqual(t, 2, 2)
+//    assert.GreaterOrEqual(t, "b", "a")
+//    assert.GreaterOrEqual(t, "b", "b")
+func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.GreaterOrEqual(t, e1, e2, msgAndArgs...) {
+		return
+	}
+	t.FailNow()
+}
+
+// GreaterOrEqualf asserts that the first element is greater than or equal to the second
+//
+//    assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted")
+//    assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted")
+//    assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted")
+//    assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted")
+func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.GreaterOrEqualf(t, e1, e2, msg, args...) {
+		return
+	}
+	t.FailNow()
+}
+
+// Greaterf asserts that the first element is greater than the second
+//
+//    assert.Greaterf(t, 2, 1, "error message %s", "formatted")
+//    assert.Greaterf(t, float64(2, "error message %s", "formatted"), float64(1))
+//    assert.Greaterf(t, "b", "a", "error message %s", "formatted")
+func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Greaterf(t, e1, e2, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -395,12 +485,12 @@ func FileExistsf(t TestingT, path string, msg string, args ...interface{}) {
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
-	if assert.HTTPBodyContains(t, handler, method, url, values, str, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPBodyContains(t, handler, method, url, values, str, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -411,12 +501,12 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url s
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
-	if assert.HTTPBodyContainsf(t, handler, method, url, values, str, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPBodyContainsf(t, handler, method, url, values, str, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -427,12 +517,12 @@ func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {
-	if assert.HTTPBodyNotContains(t, handler, method, url, values, str, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPBodyNotContains(t, handler, method, url, values, str, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -443,12 +533,12 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, ur
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {
-	if assert.HTTPBodyNotContainsf(t, handler, method, url, values, str, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPBodyNotContainsf(t, handler, method, url, values, str, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -458,12 +548,12 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
-	if assert.HTTPError(t, handler, method, url, values, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPError(t, handler, method, url, values, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -473,12 +563,12 @@ func HTTPError(t TestingT, handler http.HandlerFunc, method string, url string,
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
 func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
-	if assert.HTTPErrorf(t, handler, method, url, values, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPErrorf(t, handler, method, url, values, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -488,12 +578,12 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string,
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
-	if assert.HTTPRedirect(t, handler, method, url, values, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPRedirect(t, handler, method, url, values, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -503,12 +593,12 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url strin
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
 func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
-	if assert.HTTPRedirectf(t, handler, method, url, values, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPRedirectf(t, handler, method, url, values, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -518,12 +608,12 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {
-	if assert.HTTPSuccess(t, handler, method, url, values, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPSuccess(t, handler, method, url, values, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -533,12 +623,12 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {
-	if assert.HTTPSuccessf(t, handler, method, url, values, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.HTTPSuccessf(t, handler, method, url, values, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -546,12 +636,12 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin
 //
 //    assert.Implements(t, (*MyInterface)(nil), new(MyObject))
 func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {
-	if assert.Implements(t, interfaceObject, object, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Implements(t, interfaceObject, object, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -559,12 +649,12 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg
 //
 //    assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
 func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {
-	if assert.Implementsf(t, interfaceObject, object, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Implementsf(t, interfaceObject, object, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -572,56 +662,56 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms
 //
 // 	 assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
 func InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
-	if assert.InDelta(t, expected, actual, delta, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InDelta(t, expected, actual, delta, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
 func InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
-	if assert.InDeltaMapValues(t, expected, actual, delta, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InDeltaMapValues(t, expected, actual, delta, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
 func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
-	if assert.InDeltaMapValuesf(t, expected, actual, delta, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InDeltaMapValuesf(t, expected, actual, delta, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // InDeltaSlice is the same as InDelta, except it compares two slices.
 func InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {
-	if assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // InDeltaSlicef is the same as InDelta, except it compares two slices.
 func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
-	if assert.InDeltaSlicef(t, expected, actual, delta, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InDeltaSlicef(t, expected, actual, delta, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -629,132 +719,216 @@ func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta f
 //
 // 	 assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
 func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {
-	if assert.InDeltaf(t, expected, actual, delta, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InDeltaf(t, expected, actual, delta, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // InEpsilon asserts that expected and actual have a relative error less than epsilon
 func InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
-	if assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
 func InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {
-	if assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
 func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
-	if assert.InEpsilonSlicef(t, expected, actual, epsilon, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InEpsilonSlicef(t, expected, actual, epsilon, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // InEpsilonf asserts that expected and actual have a relative error less than epsilon
 func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {
-	if assert.InEpsilonf(t, expected, actual, epsilon, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.InEpsilonf(t, expected, actual, epsilon, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // IsType asserts that the specified objects are of the same type.
 func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {
-	if assert.IsType(t, expectedType, object, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.IsType(t, expectedType, object, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // IsTypef asserts that the specified objects are of the same type.
 func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if assert.IsTypef(t, expectedType, object, msg, args...) {
 		return
 	}
+	t.FailNow()
+}
+
+// JSONEq asserts that two JSON strings are equivalent.
+//
+//  assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.JSONEq(t, expected, actual, msgAndArgs...) {
+		return
+	}
+	t.FailNow()
+}
+
+// JSONEqf asserts that two JSON strings are equivalent.
+//
+//  assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
+func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.JSONEqf(t, expected, actual, msg, args...) {
+		return
+	}
+	t.FailNow()
+}
+
+// YAMLEq asserts that two YAML strings are equivalent.
+func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.YAMLEq(t, expected, actual, msgAndArgs...) {
+		return
+	}
+	t.FailNow()
+}
+
+// YAMLEqf asserts that two YAML strings are equivalent.
+func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.YAMLEqf(t, expected, actual, msg, args...) {
+		return
+	}
+	t.FailNow()
+}
+
+// Len asserts that the specified object has specific length.
+// Len also fails if the object has a type that len() not accept.
+//
+//    assert.Len(t, mySlice, 3)
+func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.Len(t, object, length, msgAndArgs...) {
+		return
+	}
+	t.FailNow()
+}
+
+// Lenf asserts that the specified object has specific length.
+// Lenf also fails if the object has a type that len() not accept.
+//
+//    assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
+func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Lenf(t, object, length, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
-// JSONEq asserts that two JSON strings are equivalent.
+// Less asserts that the first element is less than the second
 //
-//  assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
-func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {
-	if assert.JSONEq(t, expected, actual, msgAndArgs...) {
-		return
-	}
+//    assert.Less(t, 1, 2)
+//    assert.Less(t, float64(1), float64(2))
+//    assert.Less(t, "a", "b")
+func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Less(t, e1, e2, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
-// JSONEqf asserts that two JSON strings are equivalent.
+// LessOrEqual asserts that the first element is less than or equal to the second
 //
-//  assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
-func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {
-	if assert.JSONEqf(t, expected, actual, msg, args...) {
-		return
-	}
+//    assert.LessOrEqual(t, 1, 2)
+//    assert.LessOrEqual(t, 2, 2)
+//    assert.LessOrEqual(t, "a", "b")
+//    assert.LessOrEqual(t, "b", "b")
+func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.LessOrEqual(t, e1, e2, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
-// Len asserts that the specified object has specific length.
-// Len also fails if the object has a type that len() not accept.
+// LessOrEqualf asserts that the first element is less than or equal to the second
 //
-//    assert.Len(t, mySlice, 3)
-func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {
-	if assert.Len(t, object, length, msgAndArgs...) {
-		return
-	}
+//    assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted")
+//    assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted")
+//    assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted")
+//    assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted")
+func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.LessOrEqualf(t, e1, e2, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
-// Lenf asserts that the specified object has specific length.
-// Lenf also fails if the object has a type that len() not accept.
+// Lessf asserts that the first element is less than the second
 //
-//    assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
-func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) {
-	if assert.Lenf(t, object, length, msg, args...) {
-		return
-	}
+//    assert.Lessf(t, 1, 2, "error message %s", "formatted")
+//    assert.Lessf(t, float64(1, "error message %s", "formatted"), float64(2))
+//    assert.Lessf(t, "a", "b", "error message %s", "formatted")
+func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Lessf(t, e1, e2, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -762,12 +936,12 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf
 //
 //    assert.Nil(t, err)
 func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
-	if assert.Nil(t, object, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Nil(t, object, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -775,12 +949,12 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
 //
 //    assert.Nilf(t, err, "error message %s", "formatted")
 func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {
-	if assert.Nilf(t, object, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Nilf(t, object, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -791,12 +965,12 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
 func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
-	if assert.NoError(t, err, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NoError(t, err, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -807,12 +981,12 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
 func NoErrorf(t TestingT, err error, msg string, args ...interface{}) {
-	if assert.NoErrorf(t, err, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NoErrorf(t, err, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -823,12 +997,12 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) {
 //    assert.NotContains(t, ["Hello", "World"], "Earth")
 //    assert.NotContains(t, {"Hello": "World"}, "Earth")
 func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {
-	if assert.NotContains(t, s, contains, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotContains(t, s, contains, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -839,12 +1013,12 @@ func NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...
 //    assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
 //    assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
 func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {
-	if assert.NotContainsf(t, s, contains, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotContainsf(t, s, contains, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -855,12 +1029,12 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a
 //    assert.Equal(t, "two", obj[1])
 //  }
 func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
-	if assert.NotEmpty(t, object, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotEmpty(t, object, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -871,12 +1045,12 @@ func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {
 //    assert.Equal(t, "two", obj[1])
 //  }
 func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) {
-	if assert.NotEmptyf(t, object, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotEmptyf(t, object, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -887,12 +1061,12 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{})
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
-	if assert.NotEqual(t, expected, actual, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotEqual(t, expected, actual, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -903,12 +1077,12 @@ func NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs .
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
-	if assert.NotEqualf(t, expected, actual, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotEqualf(t, expected, actual, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -916,12 +1090,12 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string,
 //
 //    assert.NotNil(t, err)
 func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
-	if assert.NotNil(t, object, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotNil(t, object, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -929,12 +1103,12 @@ func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {
 //
 //    assert.NotNilf(t, err, "error message %s", "formatted")
 func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) {
-	if assert.NotNilf(t, object, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotNilf(t, object, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -942,12 +1116,12 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) {
 //
 //   assert.NotPanics(t, func(){ RemainCalm() })
 func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
-	if assert.NotPanics(t, f, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotPanics(t, f, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -955,12 +1129,12 @@ func NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
 //
 //   assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
 func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {
-	if assert.NotPanicsf(t, f, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotPanicsf(t, f, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -969,12 +1143,12 @@ func NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interfac
 //  assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
 //  assert.NotRegexp(t, "^start", "it's not starting")
 func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
-	if assert.NotRegexp(t, rx, str, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotRegexp(t, rx, str, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -983,12 +1157,12 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
 //  assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
 //  assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
 func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {
-	if assert.NotRegexpf(t, rx, str, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotRegexpf(t, rx, str, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -997,12 +1171,12 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ..
 //
 //    assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
 func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
-	if assert.NotSubset(t, list, subset, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotSubset(t, list, subset, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1011,34 +1185,34 @@ func NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...i
 //
 //    assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
 func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
-	if assert.NotSubsetf(t, list, subset, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotSubsetf(t, list, subset, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // NotZero asserts that i is not the zero value for its type.
 func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
-	if assert.NotZero(t, i, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotZero(t, i, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // NotZerof asserts that i is not the zero value for its type.
 func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) {
-	if assert.NotZerof(t, i, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.NotZerof(t, i, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1046,12 +1220,12 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) {
 //
 //   assert.Panics(t, func(){ GoCrazy() })
 func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
-	if assert.Panics(t, f, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Panics(t, f, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1060,12 +1234,12 @@ func Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
 //
 //   assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
 func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {
-	if assert.PanicsWithValue(t, expected, f, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.PanicsWithValue(t, expected, f, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1074,12 +1248,12 @@ func PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, m
 //
 //   assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
 func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {
-	if assert.PanicsWithValuef(t, expected, f, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.PanicsWithValuef(t, expected, f, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1087,12 +1261,12 @@ func PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc,
 //
 //   assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
 func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {
-	if assert.Panicsf(t, f, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Panicsf(t, f, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1101,12 +1275,12 @@ func Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}
 //  assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
 //  assert.Regexp(t, "start...$", "it's not starting")
 func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {
-	if assert.Regexp(t, rx, str, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Regexp(t, rx, str, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1115,12 +1289,44 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface
 //  assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
 //  assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
 func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if assert.Regexpf(t, rx, str, msg, args...) {
 		return
 	}
+	t.FailNow()
+}
+
+// Same asserts that two pointers reference the same object.
+//
+//    assert.Same(t, ptr1, ptr2)
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if assert.Same(t, expected, actual, msgAndArgs...) {
+		return
+	}
+	t.FailNow()
+}
+
+// Samef asserts that two pointers reference the same object.
+//
+//    assert.Samef(t, ptr1, ptr2, "error message %s", "formatted")
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Samef(t, expected, actual, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1129,12 +1335,12 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in
 //
 //    assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
 func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {
-	if assert.Subset(t, list, subset, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Subset(t, list, subset, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1143,12 +1349,12 @@ func Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...inte
 //
 //    assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
 func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {
-	if assert.Subsetf(t, list, subset, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Subsetf(t, list, subset, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1156,12 +1362,12 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args
 //
 //    assert.True(t, myBool)
 func True(t TestingT, value bool, msgAndArgs ...interface{}) {
-	if assert.True(t, value, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.True(t, value, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1169,12 +1375,12 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) {
 //
 //    assert.Truef(t, myBool, "error message %s", "formatted")
 func Truef(t TestingT, value bool, msg string, args ...interface{}) {
-	if assert.Truef(t, value, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Truef(t, value, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1182,12 +1388,12 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) {
 //
 //   assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
 func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {
-	if assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
@@ -1195,33 +1401,33 @@ func WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time
 //
 //   assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
 func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {
-	if assert.WithinDurationf(t, expected, actual, delta, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.WithinDurationf(t, expected, actual, delta, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
 
 // Zero asserts that i is the zero value for its type.
 func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {
-	if assert.Zero(t, i, msgAndArgs...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Zero(t, i, msgAndArgs...) {
+		return
+	}
 	t.FailNow()
 }
 
 // Zerof asserts that i is the zero value for its type.
 func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) {
-	if assert.Zerof(t, i, msg, args...) {
-		return
-	}
 	if h, ok := t.(tHelper); ok {
 		h.Helper()
 	}
+	if assert.Zerof(t, i, msg, args...) {
+		return
+	}
 	t.FailNow()
 }
diff --git a/require/require.go.tmpl b/require/require.go.tmpl
index 6ffc751..55e42dd 100644
--- a/require/require.go.tmpl
+++ b/require/require.go.tmpl
@@ -1,6 +1,6 @@
 {{.Comment}}
 func {{.DocInfo.Name}}(t TestingT, {{.Params}}) {
-	if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return }
 	if h, ok := t.(tHelper); ok { h.Helper() }
+	if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return }
 	t.FailNow()
 }
diff --git a/require/require_forward.go b/require/require_forward.go
index 9fe41db..804fae0 100644
--- a/require/require_forward.go
+++ b/require/require_forward.go
@@ -216,6 +216,28 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) {
 	Errorf(a.t, err, msg, args...)
 }
 
+// Eventually asserts that given condition will be met in waitFor time,
+// periodically checking target function each tick.
+//
+//    a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond)
+func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	Eventually(a.t, condition, waitFor, tick, msgAndArgs...)
+}
+
+// Eventuallyf asserts that given condition will be met in waitFor time,
+// periodically checking target function each tick.
+//
+//    a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted")
+func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	Eventuallyf(a.t, condition, waitFor, tick, msg, args...)
+}
+
 // Exactly asserts that two objects are equal in value and type.
 //
 //    a.Exactly(int32(123), int64(123))
@@ -304,6 +326,56 @@ func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) {
 	FileExistsf(a.t, path, msg, args...)
 }
 
+// Greater asserts that the first element is greater than the second
+//
+//    a.Greater(2, 1)
+//    a.Greater(float64(2), float64(1))
+//    a.Greater("b", "a")
+func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	Greater(a.t, e1, e2, msgAndArgs...)
+}
+
+// GreaterOrEqual asserts that the first element is greater than or equal to the second
+//
+//    a.GreaterOrEqual(2, 1)
+//    a.GreaterOrEqual(2, 2)
+//    a.GreaterOrEqual("b", "a")
+//    a.GreaterOrEqual("b", "b")
+func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	GreaterOrEqual(a.t, e1, e2, msgAndArgs...)
+}
+
+// GreaterOrEqualf asserts that the first element is greater than or equal to the second
+//
+//    a.GreaterOrEqualf(2, 1, "error message %s", "formatted")
+//    a.GreaterOrEqualf(2, 2, "error message %s", "formatted")
+//    a.GreaterOrEqualf("b", "a", "error message %s", "formatted")
+//    a.GreaterOrEqualf("b", "b", "error message %s", "formatted")
+func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	GreaterOrEqualf(a.t, e1, e2, msg, args...)
+}
+
+// Greaterf asserts that the first element is greater than the second
+//
+//    a.Greaterf(2, 1, "error message %s", "formatted")
+//    a.Greaterf(float64(2, "error message %s", "formatted"), float64(1))
+//    a.Greaterf("b", "a", "error message %s", "formatted")
+func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	Greaterf(a.t, e1, e2, msg, args...)
+}
+
 // HTTPBodyContains asserts that a specified handler returns a
 // body that contains a string.
 //
@@ -568,6 +640,22 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
 	JSONEqf(a.t, expected, actual, msg, args...)
 }
 
+// YAMLEq asserts that two YAML strings are equivalent.
+func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	YAMLEq(a.t, expected, actual, msgAndArgs...)
+}
+
+// YAMLEqf asserts that two YAML strings are equivalent.
+func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	YAMLEqf(a.t, expected, actual, msg, args...)
+}
+
 // Len asserts that the specified object has specific length.
 // Len also fails if the object has a type that len() not accept.
 //
@@ -590,6 +678,56 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in
 	Lenf(a.t, object, length, msg, args...)
 }
 
+// Less asserts that the first element is less than the second
+//
+//    a.Less(1, 2)
+//    a.Less(float64(1), float64(2))
+//    a.Less("a", "b")
+func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	Less(a.t, e1, e2, msgAndArgs...)
+}
+
+// LessOrEqual asserts that the first element is less than or equal to the second
+//
+//    a.LessOrEqual(1, 2)
+//    a.LessOrEqual(2, 2)
+//    a.LessOrEqual("a", "b")
+//    a.LessOrEqual("b", "b")
+func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	LessOrEqual(a.t, e1, e2, msgAndArgs...)
+}
+
+// LessOrEqualf asserts that the first element is less than or equal to the second
+//
+//    a.LessOrEqualf(1, 2, "error message %s", "formatted")
+//    a.LessOrEqualf(2, 2, "error message %s", "formatted")
+//    a.LessOrEqualf("a", "b", "error message %s", "formatted")
+//    a.LessOrEqualf("b", "b", "error message %s", "formatted")
+func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	LessOrEqualf(a.t, e1, e2, msg, args...)
+}
+
+// Lessf asserts that the first element is less than the second
+//
+//    a.Lessf(1, 2, "error message %s", "formatted")
+//    a.Lessf(float64(1, "error message %s", "formatted"), float64(2))
+//    a.Lessf("a", "b", "error message %s", "formatted")
+func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	Lessf(a.t, e1, e2, msg, args...)
+}
+
 // Nil asserts that the specified object is nil.
 //
 //    a.Nil(err)
@@ -878,6 +1016,32 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args .
 	Regexpf(a.t, rx, str, msg, args...)
 }
 
+// Same asserts that two pointers reference the same object.
+//
+//    a.Same(ptr1, ptr2)
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	Same(a.t, expected, actual, msgAndArgs...)
+}
+
+// Samef asserts that two pointers reference the same object.
+//
+//    a.Samef(ptr1, ptr2, "error message %s", "formatted")
+//
+// Both arguments must be pointer variables. Pointer variable sameness is
+// determined based on the equality of both type and value.
+func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
+	Samef(a.t, expected, actual, msg, args...)
+}
+
 // Subset asserts that the specified list(array, slice...) contains all
 // elements given in the specified subset(array, slice...).
 //
diff --git a/require/requirements.go b/require/requirements.go
index 690583a..6b85c5e 100644
--- a/require/requirements.go
+++ b/require/requirements.go
@@ -22,7 +22,7 @@ type ValueAssertionFunc func(TestingT, interface{}, ...interface{})
 // for table driven tests.
 type BoolAssertionFunc func(TestingT, bool, ...interface{})
 
-// ValuesAssertionFunc is a common function prototype when validating an error value.  Can be useful
+// ErrorAssertionFunc is a common function prototype when validating an error value.  Can be useful
 // for table driven tests.
 type ErrorAssertionFunc func(TestingT, error, ...interface{})
 
diff --git a/suite/suite.go b/suite/suite.go
index e20afbc..d708d7d 100644
--- a/suite/suite.go
+++ b/suite/suite.go
@@ -6,6 +6,7 @@ import (
 	"os"
 	"reflect"
 	"regexp"
+	"runtime/debug"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
@@ -55,20 +56,35 @@ func (suite *Suite) Assert() *assert.Assertions {
 	return suite.Assertions
 }
 
+func failOnPanic(t *testing.T) {
+	r := recover()
+	if r != nil {
+		t.Errorf("test panicked: %v\n%s", r, debug.Stack())
+		t.FailNow()
+	}
+}
+
+// Run provides suite functionality around golang subtests.  It should be
+// called in place of t.Run(name, func(t *testing.T)) in test suite code.
+// The passed-in func will be executed as a subtest with a fresh instance of t.
+// Provides compatibility with go test pkg -run TestSuite/TestName/SubTestName.
+func (suite *Suite) Run(name string, subtest func()) bool {
+	oldT := suite.T()
+	defer suite.SetT(oldT)
+	return oldT.Run(name, func(t *testing.T) {
+		suite.SetT(t)
+		subtest()
+	})
+}
+
 // Run takes a testing suite and runs all of the tests attached
 // to it.
 func Run(t *testing.T, suite TestingSuite) {
 	suite.SetT(t)
+	defer failOnPanic(t)
 
-	if setupAllSuite, ok := suite.(SetupAllSuite); ok {
-		setupAllSuite.SetupSuite()
-	}
-	defer func() {
-		if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
-			tearDownAllSuite.TearDownSuite()
-		}
-	}()
-
+	suiteSetupDone := false
+	
 	methodFinder := reflect.TypeOf(suite)
 	tests := []testing.InternalTest{}
 	for index := 0; index < methodFinder.NumMethod(); index++ {
@@ -78,32 +94,46 @@ func Run(t *testing.T, suite TestingSuite) {
 			fmt.Fprintf(os.Stderr, "testify: invalid regexp for -m: %s\n", err)
 			os.Exit(1)
 		}
-		if ok {
-			test := testing.InternalTest{
-				Name: method.Name,
-				F: func(t *testing.T) {
-					parentT := suite.T()
-					suite.SetT(t)
-					if setupTestSuite, ok := suite.(SetupTestSuite); ok {
-						setupTestSuite.SetupTest()
+		if !ok {
+			continue
+		}
+		if !suiteSetupDone {
+			if setupAllSuite, ok := suite.(SetupAllSuite); ok {
+				setupAllSuite.SetupSuite()
+			}
+			defer func() {
+				if tearDownAllSuite, ok := suite.(TearDownAllSuite); ok {
+					tearDownAllSuite.TearDownSuite()
+				}
+			}()
+			suiteSetupDone = true
+		}
+		test := testing.InternalTest{
+			Name: method.Name,
+			F: func(t *testing.T) {
+				parentT := suite.T()
+				suite.SetT(t)
+				defer failOnPanic(t)
+
+				if setupTestSuite, ok := suite.(SetupTestSuite); ok {
+					setupTestSuite.SetupTest()
+				}
+				if beforeTestSuite, ok := suite.(BeforeTest); ok {
+					beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
+				}
+				defer func() {
+					if afterTestSuite, ok := suite.(AfterTest); ok {
+						afterTestSuite.AfterTest(methodFinder.Elem().Name(), method.Name)
 					}
-					if beforeTestSuite, ok := suite.(BeforeTest); ok {
-						beforeTestSuite.BeforeTest(methodFinder.Elem().Name(), method.Name)
+					if tearDownTestSuite, ok := suite.(TearDownTestSuite); ok {
+						tearDownTestSuite.TearDownTest()
 					}
-					defer func() {
-						if afterTestSuite, ok := suite.(AfterTest); ok {
-							afterTestSuite.AfterTest(methodFinder.Elem().Name(), method.Name)
-						}
-						if tearDownTestSuite, ok := suite.(TearDownTestSuite); ok {
-							tearDownTestSuite.TearDownTest()
-						}
-						suite.SetT(parentT)
-					}()
-					method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
-				},
-			}
-			tests = append(tests, test)
+					suite.SetT(parentT)
+				}()
+				method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
+			},
 		}
+		tests = append(tests, test)
 	}
 	runTests(t, tests)
 }


Test patch:
diff --git a/assert/assertion_order_test.go b/assert/assertion_order_test.go
new file mode 100644
index 0000000..4dd897a
--- /dev/null
+++ b/assert/assertion_order_test.go
@@ -0,0 +1,118 @@
+package assert
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestCompare(t *testing.T) {
+	for _, currCase := range []struct {
+		less    interface{}
+		greater interface{}
+		cType   string
+	}{
+		{less: "a", greater: "b", cType: "string"},
+		{less: int(1), greater: int(2), cType: "int"},
+		{less: int8(1), greater: int8(2), cType: "int8"},
+		{less: int16(1), greater: int16(2), cType: "int16"},
+		{less: int32(1), greater: int32(2), cType: "int32"},
+		{less: int64(1), greater: int64(2), cType: "int64"},
+		{less: uint8(1), greater: uint8(2), cType: "uint8"},
+		{less: uint16(1), greater: uint16(2), cType: "uint16"},
+		{less: uint32(1), greater: uint32(2), cType: "uint32"},
+		{less: uint64(1), greater: uint64(2), cType: "uint64"},
+		{less: float32(1), greater: float32(2), cType: "float32"},
+		{less: float64(1), greater: float64(2), cType: "float64"},
+	} {
+		resLess, isComparable := compare(currCase.less, currCase.greater, reflect.ValueOf(currCase.less).Kind())
+		if !isComparable {
+			t.Error("object should be comparable for type " + currCase.cType)
+		}
+
+		if resLess != 1 {
+			t.Errorf("object less should be less than greater for type " + currCase.cType)
+		}
+
+		resGreater, isComparable := compare(currCase.greater, currCase.less, reflect.ValueOf(currCase.less).Kind())
+		if !isComparable {
+			t.Error("object are comparable for type " + currCase.cType)
+		}
+
+		if resGreater != -1 {
+			t.Errorf("object greater should be greater than less for type " + currCase.cType)
+		}
+
+		resEqual, isComparable := compare(currCase.less, currCase.less, reflect.ValueOf(currCase.less).Kind())
+		if !isComparable {
+			t.Error("object are comparable for type " + currCase.cType)
+		}
+
+		if resEqual != 0 {
+			t.Errorf("objects should be equal for type " + currCase.cType)
+		}
+	}
+}
+
+func TestGreater(t *testing.T) {
+	mockT := new(testing.T)
+
+	if !Greater(mockT, 2, 1) {
+		t.Error("Greater should return true")
+	}
+
+	if Greater(mockT, 1, 1) {
+		t.Error("Greater should return false")
+	}
+
+	if Greater(mockT, 1, 2) {
+		t.Error("Greater should return false")
+	}
+}
+
+func TestGreaterOrEqual(t *testing.T) {
+	mockT := new(testing.T)
+
+	if !GreaterOrEqual(mockT, 2, 1) {
+		t.Error("Greater should return true")
+	}
+
+	if !GreaterOrEqual(mockT, 1, 1) {
+		t.Error("Greater should return true")
+	}
+
+	if GreaterOrEqual(mockT, 1, 2) {
+		t.Error("Greater should return false")
+	}
+}
+
+func TestLess(t *testing.T) {
+	mockT := new(testing.T)
+
+	if !Less(mockT, 1, 2) {
+		t.Error("Less should return true")
+	}
+
+	if Less(mockT, 1, 1) {
+		t.Error("Less should return false")
+	}
+
+	if Less(mockT, 2, 1) {
+		t.Error("Less should return false")
+	}
+}
+
+func TestLessOrEqual(t *testing.T) {
+	mockT := new(testing.T)
+
+	if !LessOrEqual(mockT, 1, 2) {
+		t.Error("Greater should return true")
+	}
+
+	if !LessOrEqual(mockT, 1, 1) {
+		t.Error("Greater should return true")
+	}
+
+	if LessOrEqual(mockT, 2, 1) {
+		t.Error("Greater should return false")
+	}
+}
diff --git a/assert/assertions_test.go b/assert/assertions_test.go
index 91b5ee9..a4a9585 100644
--- a/assert/assertions_test.go
+++ b/assert/assertions_test.go
@@ -175,6 +175,8 @@ func TestIsType(t *testing.T) {
 
 }
 
+type myType string
+
 func TestEqual(t *testing.T) {
 
 	mockT := new(testing.T)
@@ -200,6 +202,9 @@ func TestEqual(t *testing.T) {
 	if !Equal(mockT, uint64(123), uint64(123)) {
 		t.Error("Equal should return true")
 	}
+	if !Equal(mockT, myType("1"), myType("1")) {
+		t.Error("Equal should return true")
+	}
 	if !Equal(mockT, &struct{}{}, &struct{}{}) {
 		t.Error("Equal should return true (pointer equality is based on equality of underlying value)")
 	}
@@ -207,6 +212,32 @@ func TestEqual(t *testing.T) {
 	if Equal(mockT, m["bar"], "something") {
 		t.Error("Equal should return false")
 	}
+	if Equal(mockT, myType("1"), myType("2")) {
+		t.Error("Equal should return false")
+	}
+}
+
+func TestSame(t *testing.T) {
+
+	mockT := new(testing.T)
+
+	ptr := func(i int) *int {
+		return &i
+	}
+
+	if Same(mockT, ptr(1), ptr(1)) {
+		t.Error("Same should return false")
+	}
+	if Same(mockT, 1, 1) {
+		t.Error("Same should return false")
+	}
+	p := ptr(2)
+	if Same(mockT, p, *p) {
+		t.Error("Same should return false")
+	}
+	if !Same(mockT, p, p) {
+		t.Error("Same should return true")
+	}
 }
 
 // bufferT implements TestingT. Its implementation of Errorf writes the output that would be produced by
@@ -275,6 +306,8 @@ func TestEqualFormatting(t *testing.T) {
 	}{
 		{equalWant: "want", equalGot: "got", want: "\tassertions.go:\\d+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n"},
 		{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{"hello, %v!", "world"}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+hello, world!\n"},
+		{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{123}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+123\n"},
+		{equalWant: "want", equalGot: "got", msgAndArgs: []interface{}{struct{ a string }{"hello"}}, want: "\tassertions.go:[0-9]+: \n\t+Error Trace:\t\n\t+Error:\\s+Not equal:\\s+\n\\s+expected: \"want\"\n\\s+actual\\s+: \"got\"\n\\s+Diff:\n\\s+-+ Expected\n\\s+\\++ Actual\n\\s+@@ -1 \\+1 @@\n\\s+-want\n\\s+\\+got\n\\s+Messages:\\s+{a:hello}\n"},
 	} {
 		mockT := &bufferT{}
 		Equal(mockT, currCase.equalWant, currCase.equalGot, currCase.msgAndArgs...)
@@ -1410,6 +1443,81 @@ func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
 	False(t, JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`))
 }
 
+func TestYAMLEq_EqualYAMLString(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`))
+}
+
+func TestYAMLEq_EquivalentButNotEqual(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`))
+}
+
+func TestYAMLEq_HashOfArraysAndHashes(t *testing.T) {
+	mockT := new(testing.T)
+	expected := `
+numeric: 1.5
+array:
+  - foo: bar
+  - 1
+  - "string"
+  - ["nested", "array", 5.5]
+hash:
+  nested: hash
+  nested_slice: [this, is, nested]
+string: "foo"
+`
+
+	actual := `
+numeric: 1.5
+hash:
+  nested: hash
+  nested_slice: [this, is, nested]
+string: "foo"
+array:
+  - foo: bar
+  - 1
+  - "string"
+  - ["nested", "array", 5.5]
+`
+	True(t, YAMLEq(mockT, expected, actual))
+}
+
+func TestYAMLEq_Array(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`))
+}
+
+func TestYAMLEq_HashAndArrayNotEquivalent(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`))
+}
+
+func TestYAMLEq_HashesNotEquivalent(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, YAMLEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`))
+}
+
+func TestYAMLEq_ActualIsSimpleString(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, YAMLEq(mockT, `{"foo": "bar"}`, "Simple String"))
+}
+
+func TestYAMLEq_ExpectedIsSimpleString(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, YAMLEq(mockT, "Simple String", `{"foo": "bar", "hello": "world"}`))
+}
+
+func TestYAMLEq_ExpectedAndActualSimpleString(t *testing.T) {
+	mockT := new(testing.T)
+	True(t, YAMLEq(mockT, "Simple String", "Simple String"))
+}
+
+func TestYAMLEq_ArraysOfDifferentOrder(t *testing.T) {
+	mockT := new(testing.T)
+	False(t, YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`))
+}
+
 func TestDiff(t *testing.T) {
 	expected := `
 
@@ -1791,3 +1899,25 @@ func TestErrorAssertionFunc(t *testing.T) {
 		})
 	}
 }
+
+func TestEventuallyFalse(t *testing.T) {
+	mockT := new(testing.T)
+
+	condition := func() bool {
+		return false
+	}
+
+	False(t, Eventually(mockT, condition, 100*time.Millisecond, 20*time.Millisecond))
+}
+
+func TestEventuallyTrue(t *testing.T) {
+	state := 0
+	condition := func() bool {
+		defer func() {
+			state = state + 1
+		}()
+		return state == 2
+	}
+
+	True(t, Eventually(t, condition, 100*time.Millisecond, 20*time.Millisecond))
+}
diff --git a/assert/forward_assertions_test.go b/assert/forward_assertions_test.go
index 22e1df1..4d83d6a 100644
--- a/assert/forward_assertions_test.go
+++ b/assert/forward_assertions_test.go
@@ -609,3 +609,101 @@ func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
 		t.Error("JSONEq should return false")
 	}
 }
+
+func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) {
+	assert := New(new(testing.T))
+	if !assert.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) {
+		t.Error("YAMLEq should return true")
+	}
+
+}
+
+func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) {
+	assert := New(new(testing.T))
+	if !assert.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
+		t.Error("YAMLEq should return true")
+	}
+
+}
+
+func TestYAMLEqWrapper_HashOfArraysAndHashes(t *testing.T) {
+	assert := New(new(testing.T))
+	expected := `
+numeric: 1.5
+array:
+  - foo: bar
+  - 1
+  - "string"
+  - ["nested", "array", 5.5]
+hash:
+  nested: hash
+  nested_slice: [this, is, nested]
+string: "foo"
+`
+
+	actual := `
+numeric: 1.5
+hash:
+  nested: hash
+  nested_slice: [this, is, nested]
+string: "foo"
+array:
+  - foo: bar
+  - 1
+  - "string"
+  - ["nested", "array", 5.5]
+`
+	if !assert.YAMLEq(expected, actual) {
+		t.Error("YAMLEq should return true")
+	}
+}
+
+func TestYAMLEqWrapper_Array(t *testing.T) {
+	assert := New(new(testing.T))
+	if !assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) {
+		t.Error("YAMLEq should return true")
+	}
+
+}
+
+func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) {
+		t.Error("YAMLEq should return false")
+	}
+}
+
+func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.YAMLEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) {
+		t.Error("YAMLEq should return false")
+	}
+}
+
+func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.YAMLEq(`{"foo": "bar"}`, "Simple String") {
+		t.Error("YAMLEq should return false")
+	}
+}
+
+func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.YAMLEq("Simple String", `{"foo": "bar", "hello": "world"}`) {
+		t.Error("YAMLEq should return false")
+	}
+}
+
+func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) {
+	assert := New(new(testing.T))
+	if !assert.YAMLEq("Simple String", "Simple String") {
+		t.Error("YAMLEq should return true")
+	}
+}
+
+func TestYAMLEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
+	assert := New(new(testing.T))
+	if assert.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) {
+		t.Error("YAMLEq should return false")
+	}
+}
diff --git a/mock/mock_test.go b/mock/mock_test.go
index 978eae2..2608f5a 100644
--- a/mock/mock_test.go
+++ b/mock/mock_test.go
@@ -32,6 +32,7 @@ func (i *TestExampleImplementation) TheExampleMethod(a, b, c int) (int, error) {
 	return args.Int(0), errors.New("Whoops")
 }
 
+//go:noinline
 func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) {
 	i.Called(yesorno)
 }
@@ -1492,6 +1493,7 @@ func unexpectedCallRegex(method, calledArg, expectedArg, diff string) string {
 		rMethod, calledArg, rMethod, expectedArg, diff)
 }
 
+//go:noinline
 func ConcurrencyTestMethod(m *Mock) {
 	m.Called()
 }
diff --git a/require/forward_requirements_test.go b/require/forward_requirements_test.go
index b120ae3..1ec65fa 100644
--- a/require/forward_requirements_test.go
+++ b/require/forward_requirements_test.go
@@ -383,3 +383,129 @@ func TestJSONEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
 		t.Error("Check should fail")
 	}
 }
+
+func TestYAMLEqWrapper_EqualYAMLString(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEqWrapper_EquivalentButNotEqual(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEqWrapper_HashOfArraysAndHashes(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	expected := `
+numeric: 1.5
+array:
+  - foo: bar
+  - 1
+  - "string"
+  - ["nested", "array", 5.5]
+hash:
+  nested: hash
+  nested_slice: [this, is, nested]
+string: "foo"
+`
+
+	actual := `
+numeric: 1.5
+hash:
+  nested: hash
+  nested_slice: [this, is, nested]
+string: "foo"
+array:
+  - foo: bar
+  - 1
+  - "string"
+  - ["nested", "array", 5.5]
+`
+
+	mockRequire.YAMLEq(expected, actual)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEqWrapper_Array(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEqWrapper_HashAndArrayNotEquivalent(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestYAMLEqWrapper_HashesNotEquivalent(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq(`{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestYAMLEqWrapper_ActualIsSimpleString(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq(`{"foo": "bar"}`, "Simple String")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestYAMLEqWrapper_ExpectedIsSimpleString(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq("Simple String", `{"foo": "bar", "hello": "world"}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestYAMLEqWrapper_ExpectedAndActualSimpleString(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq("Simple String", "Simple String")
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEqWrapper_ArraysOfDifferentOrder(t *testing.T) {
+	mockT := new(MockT)
+	mockRequire := New(mockT)
+
+	mockRequire.YAMLEq(`["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
diff --git a/require/requirements_test.go b/require/requirements_test.go
index 39467d9..c4d0afa 100644
--- a/require/requirements_test.go
+++ b/require/requirements_test.go
@@ -369,6 +369,111 @@ func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) {
 	}
 }
 
+func TestYAMLEq_EqualYAMLString(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEq_EquivalentButNotEqual(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEq_HashOfArraysAndHashes(t *testing.T) {
+	mockT := new(MockT)
+	expected := `
+numeric: 1.5
+array:
+  - foo: bar
+  - 1
+  - "string"
+  - ["nested", "array", 5.5]
+hash:
+  nested: hash
+  nested_slice: [this, is, nested]
+string: "foo"
+`
+
+	actual := `
+numeric: 1.5
+hash:
+  nested: hash
+  nested_slice: [this, is, nested]
+string: "foo"
+array:
+  - foo: bar
+  - 1
+  - "string"
+  - ["nested", "array", 5.5]
+`
+	YAMLEq(mockT, expected, actual)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEq_Array(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`)
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEq_HashAndArrayNotEquivalent(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestYAMLEq_HashesNotEquivalent(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestYAMLEq_ActualIsSimpleString(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, `{"foo": "bar"}`, "Simple String")
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestYAMLEq_ExpectedIsSimpleString(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, "Simple String", `{"foo": "bar", "hello": "world"}`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
+func TestYAMLEq_ExpectedAndActualSimpleString(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, "Simple String", "Simple String")
+	if mockT.Failed {
+		t.Error("Check should pass")
+	}
+}
+
+func TestYAMLEq_ArraysOfDifferentOrder(t *testing.T) {
+	mockT := new(MockT)
+	YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`)
+	if !mockT.Failed {
+		t.Error("Check should fail")
+	}
+}
+
 func ExampleComparisonAssertionFunc() {
 	t := &testing.T{} // provided by test
 
diff --git a/suite/suite_test.go b/suite/suite_test.go
index b75fa4a..26dddbd 100644
--- a/suite/suite_test.go
+++ b/suite/suite_test.go
@@ -42,6 +42,99 @@ func (s *SuiteRequireTwice) TestRequireTwo() {
 	r.Equal(1, 2)
 }
 
+type panickingSuite struct {
+	Suite
+	panicInSetupSuite    bool
+	panicInSetupTest     bool
+	panicInBeforeTest    bool
+	panicInTest          bool
+	panicInAfterTest     bool
+	panicInTearDownTest  bool
+	panicInTearDownSuite bool
+}
+
+func (s *panickingSuite) SetupSuite() {
+	if s.panicInSetupSuite {
+		panic("oops in setup suite")
+	}
+}
+
+func (s *panickingSuite) SetupTest() {
+	if s.panicInSetupTest {
+		panic("oops in setup test")
+	}
+}
+
+func (s *panickingSuite) BeforeTest(_, _ string) {
+	if s.panicInBeforeTest {
+		panic("oops in before test")
+	}
+}
+
+func (s *panickingSuite) Test() {
+	if s.panicInTest {
+		panic("oops in test")
+	}
+}
+
+func (s *panickingSuite) AfterTest(_, _ string) {
+	if s.panicInAfterTest {
+		panic("oops in after test")
+	}
+}
+
+func (s *panickingSuite) TearDownTest() {
+	if s.panicInTearDownTest {
+		panic("oops in tear down test")
+	}
+}
+
+func (s *panickingSuite) TearDownSuite() {
+	if s.panicInTearDownSuite {
+		panic("oops in tear down suite")
+	}
+}
+
+func TestSuiteRecoverPanic(t *testing.T) {
+	ok := true
+	panickingTests := []testing.InternalTest{
+		{
+			Name: "TestPanicInSetupSuite",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupSuite: true}) },
+		},
+		{
+			Name: "TestPanicInSetupTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInSetupTest: true}) },
+		},
+		{
+			Name: "TestPanicInBeforeTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInBeforeTest: true}) },
+		},
+		{
+			Name: "TestPanicInTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTest: true}) },
+		},
+		{
+			Name: "TestPanicInAfterTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInAfterTest: true}) },
+		},
+		{
+			Name: "TestPanicInTearDownTest",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownTest: true}) },
+		},
+		{
+			Name: "TestPanicInTearDownSuite",
+			F:    func(t *testing.T) { Run(t, &panickingSuite{panicInTearDownSuite: true}) },
+		},
+	}
+
+	require.NotPanics(t, func() {
+		ok = testing.RunTests(allTestsFilter, panickingTests)
+	})
+
+	assert.False(t, ok)
+}
+
 // This suite is intended to store values to make sure that only
 // testing-suite-related methods are run.  It's also a fully
 // functional example of a testing suite, using setup/teardown methods
@@ -59,6 +152,7 @@ type SuiteTester struct {
 	TearDownTestRunCount  int
 	TestOneRunCount       int
 	TestTwoRunCount       int
+	TestSubtestRunCount   int
 	NonTestMethodRunCount int
 
 	SuiteNameBefore []string
@@ -71,15 +165,6 @@ type SuiteTester struct {
 	TimeAfter  []time.Time
 }
 
-type SuiteSkipTester struct {
-	// Include our basic suite logic.
-	Suite
-
-	// Keep counts of how many times each method is run.
-	SetupSuiteRunCount    int
-	TearDownSuiteRunCount int
-}
-
 // The SetupSuite method will be run by testify once, at the very
 // start of the testing suite, before any tests are run.
 func (suite *SuiteTester) SetupSuite() {
@@ -98,21 +183,12 @@ func (suite *SuiteTester) AfterTest(suiteName, testName string) {
 	suite.TimeAfter = append(suite.TimeAfter, time.Now())
 }
 
-func (suite *SuiteSkipTester) SetupSuite() {
-	suite.SetupSuiteRunCount++
-	suite.T().Skip()
-}
-
 // The TearDownSuite method will be run by testify once, at the very
 // end of the testing suite, after all tests have been run.
 func (suite *SuiteTester) TearDownSuite() {
 	suite.TearDownSuiteRunCount++
 }
 
-func (suite *SuiteSkipTester) TearDownSuite() {
-	suite.TearDownSuiteRunCount++
-}
-
 // The SetupTest method will be run before every test in the suite.
 func (suite *SuiteTester) SetupTest() {
 	suite.SetupTestRunCount++
@@ -153,6 +229,51 @@ func (suite *SuiteTester) NonTestMethod() {
 	suite.NonTestMethodRunCount++
 }
 
+func (suite *SuiteTester) TestSubtest() {
+	suite.TestSubtestRunCount++
+
+	for _, t := range []struct {
+		testName string
+	}{
+		{"first"},
+		{"second"},
+	} {
+		suiteT := suite.T()
+		suite.Run(t.testName, func() {
+			// We should get a different *testing.T for subtests, so that
+			// go test recognizes them as proper subtests for output formatting
+			// and running individual subtests
+			subTestT := suite.T()
+			suite.NotEqual(subTestT, suiteT)
+		})
+		suite.Equal(suiteT, suite.T())
+	}
+}
+
+type SuiteSkipTester struct {
+	// Include our basic suite logic.
+	Suite
+
+	// Keep counts of how many times each method is run.
+	SetupSuiteRunCount    int
+	TearDownSuiteRunCount int
+}
+
+func (suite *SuiteSkipTester) SetupSuite() {
+	suite.SetupSuiteRunCount++
+	suite.T().Skip()
+}
+
+func (suite *SuiteSkipTester) TestNothing() {
+	// SetupSuite is only called when at least one test satisfies
+	// test filter. For this suite to be set up (and then tore down)
+	// it is necessary to add at least one test method.
+}
+
+func (suite *SuiteSkipTester) TearDownSuite() {
+	suite.TearDownSuiteRunCount++
+}
+
 // TestRunSuite will be run by the 'go test' command, so within it, we
 // can run our suite using the Run(*testing.T, TestingSuite) function.
 func TestRunSuite(t *testing.T) {
@@ -168,18 +289,20 @@ func TestRunSuite(t *testing.T) {
 	assert.Equal(t, suiteTester.SetupSuiteRunCount, 1)
 	assert.Equal(t, suiteTester.TearDownSuiteRunCount, 1)
 
-	assert.Equal(t, len(suiteTester.SuiteNameAfter), 3)
-	assert.Equal(t, len(suiteTester.SuiteNameBefore), 3)
-	assert.Equal(t, len(suiteTester.TestNameAfter), 3)
-	assert.Equal(t, len(suiteTester.TestNameBefore), 3)
+	assert.Equal(t, len(suiteTester.SuiteNameAfter), 4)
+	assert.Equal(t, len(suiteTester.SuiteNameBefore), 4)
+	assert.Equal(t, len(suiteTester.TestNameAfter), 4)
+	assert.Equal(t, len(suiteTester.TestNameBefore), 4)
 
 	assert.Contains(t, suiteTester.TestNameAfter, "TestOne")
 	assert.Contains(t, suiteTester.TestNameAfter, "TestTwo")
 	assert.Contains(t, suiteTester.TestNameAfter, "TestSkip")
+	assert.Contains(t, suiteTester.TestNameAfter, "TestSubtest")
 
 	assert.Contains(t, suiteTester.TestNameBefore, "TestOne")
 	assert.Contains(t, suiteTester.TestNameBefore, "TestTwo")
 	assert.Contains(t, suiteTester.TestNameBefore, "TestSkip")
+	assert.Contains(t, suiteTester.TestNameBefore, "TestSubtest")
 
 	for _, suiteName := range suiteTester.SuiteNameAfter {
 		assert.Equal(t, "SuiteTester", suiteName)
@@ -197,15 +320,16 @@ func TestRunSuite(t *testing.T) {
 		assert.False(t, when.IsZero())
 	}
 
-	// There are three test methods (TestOne, TestTwo, and TestSkip), so
+	// There are four test methods (TestOne, TestTwo, TestSkip, and TestSubtest), so
 	// the SetupTest and TearDownTest methods (which should be run once for
-	// each test) should have been run three times.
-	assert.Equal(t, suiteTester.SetupTestRunCount, 3)
-	assert.Equal(t, suiteTester.TearDownTestRunCount, 3)
+	// each test) should have been run four times.
+	assert.Equal(t, suiteTester.SetupTestRunCount, 4)
+	assert.Equal(t, suiteTester.TearDownTestRunCount, 4)
 
 	// Each test should have been run once.
 	assert.Equal(t, suiteTester.TestOneRunCount, 1)
 	assert.Equal(t, suiteTester.TestTwoRunCount, 1)
+	assert.Equal(t, suiteTester.TestSubtestRunCount, 1)
 
 	// Methods that don't match the test method identifier shouldn't
 	// have been run at all.
@@ -222,6 +346,33 @@ func TestRunSuite(t *testing.T) {
 
 }
 
+// This suite has no Test... methods. It's setup and teardown must be skipped.
+type SuiteSetupSkipTester struct {
+	Suite
+
+	setUp bool
+	toreDown bool
+}
+
+func (s *SuiteSetupSkipTester) SetupSuite() {
+	s.setUp = true
+}
+
+func (s *SuiteSetupSkipTester) NonTestMethod() {
+
+}
+
+func (s *SuiteSetupSkipTester) TearDownSuite() {
+	s.toreDown = true
+}
+
+func TestSkippingSuiteSetup(t *testing.T) {
+	suiteTester := new(SuiteSetupSkipTester)
+	Run(t, suiteTester)
+	assert.False(t, suiteTester.setUp)
+	assert.False(t, suiteTester.toreDown)
+}
+
 func TestSuiteGetters(t *testing.T) {
 	suite := new(SuiteTester)
 	suite.SetT(t)