You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by oc...@apache.org on 2022/02/21 22:42:40 UTC

[trafficcontrol] branch master updated: Refactor cachegroup tests (#6554)

This is an automated email from the ASF dual-hosted git repository.

ocket8888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 09ae784  Refactor cachegroup tests (#6554)
09ae784 is described below

commit 09ae78447d3b03a586e3ad454961d43f761a7fd8
Author: Eric Holguin <14...@users.noreply.github.com>
AuthorDate: Mon Feb 21 15:42:26 2022 -0700

    Refactor cachegroup tests (#6554)
    
    * Added functions that perform specific checks
    
    * Refactored test structure
    
    * Added stretchr/testify license
    
    * Added the stretchr/testify dependancy
    
    * Added testify dependency licenses
    
    * Fix object order for checking equality
    
    * Fix test issues and clean up
    
    * Update test names and clean up create delete funcs
    
    * Add GoDocs make check functions more generic
    
    * Add keyed fields, change struct to use requestOptions
    
    * Add assertion functions
    
    * Use new assertion functions
    
    * Removed no longer used dependency
    
    * Added time variables and fix assert messages
    
    * Removed sprintf statements
    
    * Added failure messages and made messages an interface
    
    * Changed exactly function message
    
    * remove new lines in message output
    
    * Updated check functions to use tc.Alerts
    
    * Undo negative test cases for testing
    
    * Remove redundant error print message
---
 traffic_ops/testing/api/assert/assertions.go   |  144 +++
 traffic_ops/testing/api/utils/utils.go         |   66 ++
 traffic_ops/testing/api/v4/cachegroups_test.go | 1235 ++++++++----------------
 3 files changed, 589 insertions(+), 856 deletions(-)

diff --git a/traffic_ops/testing/api/assert/assertions.go b/traffic_ops/testing/api/assert/assertions.go
new file mode 100644
index 0000000..0d9f78d
--- /dev/null
+++ b/traffic_ops/testing/api/assert/assertions.go
@@ -0,0 +1,144 @@
+package assert
+
+/*
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+import (
+	"fmt"
+	"reflect"
+	"testing"
+)
+
+// failureOutput checks if there is a message to be parsed and concatenates with a failure message.
+func failureOutput(failureMessage string, msgAndArgs ...interface{}) string {
+	output := failureMessage
+	message := ""
+	if len(msgAndArgs) == 1 {
+		msg := msgAndArgs[0]
+		if msgAsStr, ok := msg.(string); ok {
+			message = msgAsStr
+		}
+		message = fmt.Sprintf("%+v", msg)
+	}
+	if len(msgAndArgs) > 1 {
+		message = fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
+	}
+	if len(message) > 0 {
+		output = output + " Messages: " + message
+	}
+	return output
+}
+
+// Equal asserts that two objects are equal.
+func Equal(t *testing.T, a, b interface{}, msgAndArgs ...interface{}) bool {
+	t.Helper()
+	if a != b {
+		msg := failureOutput(fmt.Sprintf("Not equal. Expected: %v Actual: %v", a, b), msgAndArgs...)
+		t.Error(msg)
+		return false
+	}
+	return true
+}
+
+// RequireEqual asserts that two objects are equal.
+// It marks the test as failed and stops execution.
+func RequireEqual(t *testing.T, a, b interface{}, msgAndArgs ...interface{}) {
+	t.Helper()
+	if !Equal(t, a, b, msgAndArgs...) {
+		t.FailNow()
+	}
+}
+
+// Error asserts that a function returned an error (i.e. not `nil`).
+func Error(t *testing.T, err error, msgAndArgs ...interface{}) bool {
+	t.Helper()
+	if err == nil {
+		msg := failureOutput("An error is expected but got nil.", msgAndArgs...)
+		t.Error(msg)
+		return false
+	}
+	return true
+}
+
+// Exactly asserts that two objects are equal in value and type.
+func Exactly(t *testing.T, a, b interface{}, msgAndArgs ...interface{}) bool {
+	t.Helper()
+	if !reflect.DeepEqual(a, b) {
+		msg := failureOutput(fmt.Sprintf("Not exactly equal. Expected: %v Actual: %v", a, b), msgAndArgs...)
+		t.Error(msg)
+		return false
+	}
+	return true
+}
+
+// GreaterOrEqual asserts that the first element is greater than or equal to the second
+func GreaterOrEqual(t *testing.T, a, b int, msgAndArgs ...interface{}) bool {
+	t.Helper()
+	if a >= b {
+		return true
+	}
+	msg := failureOutput(fmt.Sprintf("\"%v\" is not greater than or equal to \"%v\"", a, b), msgAndArgs...)
+	t.Error(msg)
+	return false
+}
+
+// RequireGreaterOrEqual asserts that the first element is greater than or equal to the second
+// It marks the test as failed and stops execution.
+func RequireGreaterOrEqual(t *testing.T, a, b int, msgAndArgs ...interface{}) {
+	t.Helper()
+	if !GreaterOrEqual(t, a, b, msgAndArgs...) {
+		t.FailNow()
+	}
+}
+
+// NoError asserts that a function returned no error (i.e. `nil`).
+func NoError(t *testing.T, err error, msgAndArgs ...interface{}) bool {
+	t.Helper()
+	if err != nil {
+		msg := failureOutput(fmt.Sprintf("Received unexpected error: %+v", err), msgAndArgs...)
+		t.Error(msg)
+		return false
+	}
+	return true
+}
+
+// RequireNoError asserts that a function returned no error (i.e. `nil`).
+// It marks the test as failed and stops execution.
+func RequireNoError(t *testing.T, err error, msgAndArgs ...interface{}) {
+	t.Helper()
+	if !NoError(t, err, msgAndArgs...) {
+		t.FailNow()
+	}
+}
+
+// NotNil asserts that the specified object is not nil.
+func NotNil(t *testing.T, a interface{}, msgAndArgs ...interface{}) bool {
+	t.Helper()
+	if a == nil {
+		msg := failureOutput("Expected value not to be nil.", msgAndArgs...)
+		t.Error(msg)
+		return false
+	}
+	return true
+}
+
+// RequireNotNil asserts that the specified object is not nil.
+// It marks the test as failed and stops execution.
+func RequireNotNil(t *testing.T, a interface{}, msgAndArgs ...interface{}) {
+	t.Helper()
+	if !NotNil(t, a, msgAndArgs...) {
+		t.FailNow()
+	}
+}
diff --git a/traffic_ops/testing/api/utils/utils.go b/traffic_ops/testing/api/utils/utils.go
index 8de3279..eab8b1e 100644
--- a/traffic_ops/testing/api/utils/utils.go
+++ b/traffic_ops/testing/api/utils/utils.go
@@ -17,8 +17,13 @@ package utils
 
 import (
 	"encoding/json"
+	"reflect"
 	"sort"
 	"testing"
+
+	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 )
 
 type ErrorAndMessage struct {
@@ -73,3 +78,64 @@ func Compare(t *testing.T, expected []string, alertsStrs []string) {
 		}
 	}
 }
+
+// CkReqFunc defines the reusable signature for all other functions that perform checks.
+// Common parameters that are checked include the request's info, response, alerts, and errors.
+type CkReqFunc func(*testing.T, toclientlib.ReqInf, interface{}, tc.Alerts, error)
+
+// CkRequest wraps CkReqFunc functions, to be concise and reduce lexical tokens
+// i.e. Instead of `[]CkReqFunc {` we can use `CkRequest(` in test case declarations.
+func CkRequest(c ...CkReqFunc) []CkReqFunc {
+	return c
+}
+
+// NoError checks that no error was returned (i.e. `nil`).
+func NoError() CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, _ tc.Alerts, err error) {
+		assert.NoError(t, err, "Expected no error. Got: %v", err)
+	}
+}
+
+// HasError checks that an error was returned (i.e. not `nil`).
+func HasError() CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, _ interface{}, alerts tc.Alerts, err error) {
+		assert.Error(t, err, "Expected error. Got: %v", alerts)
+	}
+}
+
+// HasStatus checks that the status code from the request is as expected.
+func HasStatus(expectedStatus int) CkReqFunc {
+	return func(t *testing.T, reqInf toclientlib.ReqInf, _ interface{}, _ tc.Alerts, _ error) {
+		assert.Equal(t, expectedStatus, reqInf.StatusCode, "Expected Status Code: %d Got: %d", expectedStatus, reqInf.StatusCode)
+	}
+}
+
+// ResponseHasLength checks that the length of the response is as expected.
+// Determines that response is a slice before checking the length of the reflected value.
+func ResponseHasLength(expected int) CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		rt := reflect.TypeOf(resp)
+		switch rt.Kind() {
+		case reflect.Slice:
+			actual := reflect.ValueOf(resp).Len()
+			assert.Equal(t, expected, actual, "Expected response object length: %d Got: %d", expected, actual)
+		default:
+			t.Errorf("Expected response to be an array. Got: %v", rt)
+		}
+	}
+}
+
+// ResponseLengthGreaterOrEqual checks that the response is greater or equal to the expected length.
+// Determines that response is a slice before checking the length of the reflected value.
+func ResponseLengthGreaterOrEqual(expected int) CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		rt := reflect.TypeOf(resp)
+		switch rt.Kind() {
+		case reflect.Slice:
+			actual := reflect.ValueOf(resp).Len()
+			assert.GreaterOrEqual(t, actual, expected, "Expected response object length: %d Got: %d", expected, actual)
+		default:
+			t.Errorf("Expected response to be an array. Got: %v", rt)
+		}
+	}
+}
diff --git a/traffic_ops/testing/api/v4/cachegroups_test.go b/traffic_ops/testing/api/v4/cachegroups_test.go
index e956d3b..005d6c3 100644
--- a/traffic_ops/testing/api/v4/cachegroups_test.go
+++ b/traffic_ops/testing/api/v4/cachegroups_test.go
@@ -16,10 +16,9 @@ package v4
 */
 
 import (
-	"fmt"
+	"encoding/json"
 	"net/http"
 	"net/url"
-	"reflect"
 	"strconv"
 	"testing"
 	"time"
@@ -27,66 +26,357 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-rfc"
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/lib/go-util"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/assert"
+	"github.com/apache/trafficcontrol/traffic_ops/testing/api/utils"
+	"github.com/apache/trafficcontrol/traffic_ops/toclientlib"
 	client "github.com/apache/trafficcontrol/traffic_ops/v4-client"
 )
 
 func TestCacheGroups(t *testing.T) {
 	WithObjs(t, []TCObj{Types, Parameters, CacheGroups, CDNs, Profiles, Statuses, Divisions, Regions, PhysLocations, Servers, Topologies}, func() {
-		ReadUpdateTestCacheGroupWithNullLatLong(t)
-		GetTestCacheGroupsIMS(t)
-		GetTestCacheGroupsByNameIMS(t)
-		GetTestCacheGroupsByShortNameIMS(t)
-		GetTestCacheGroups(t)
-		GetTestCacheGroupsByName(t)
-		GetTestCacheGroupsByShortName(t)
-		GetTestCacheGroupsByTopology(t)
-		CheckCacheGroupsAuthentication(t)
+
+		tomorrow := time.Now().AddDate(0, 0, 1).Format(time.RFC1123)
 		currentTime := time.Now().UTC().Add(-5 * time.Second)
-		time := currentTime.Format(time.RFC1123)
-		var header http.Header
-		header = make(map[string][]string)
-		header.Set(rfc.IfModifiedSince, time)
-		header.Set(rfc.IfUnmodifiedSince, time)
-		UpdateTestCacheGroups(t)
-		UpdateTestCacheGroupsWithHeaders(t, header)
-		GetTestCacheGroupsAfterChangeIMS(t, header)
-		header = make(map[string][]string)
-		etag := rfc.ETag(currentTime)
-		header.Set(rfc.IfMatch, etag)
-		UpdateTestCacheGroupsWithHeaders(t, header)
-		GetTestPaginationSupportCg(t)
-		GetTestCacheGroupsByInvalidId(t)
-		GetTestCacheGroupsByInvalidType(t)
-		GetTestCacheGroupsByType(t)
-		DeleteTestCacheGroupsByInvalidId(t)
-		UpdateCachegroupWithLocks(t)
+		currentTimeRFC := currentTime.Format(time.RFC1123)
+
+		methodTests := map[string]map[string]struct {
+			endpointId    func() int
+			clientSession *client.Session
+			requestOpts   client.RequestOptions
+			requestBody   map[string]interface{}
+			expectations  []utils.CkReqFunc
+		}{
+			"GET": {
+				"OK when VALID NAME parameter AND Lat/Long are 0": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"name": {"nullLatLongCG"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1), ValidateResponseFields()),
+				},
+				"NOT MODIFIED when NO CHANGES made": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{Header: http.Header{rfc.IfModifiedSince: {tomorrow}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"NOT MODIFIED when VALID NAME parameter when NO CHANGES made": {
+					clientSession: TOSession,
+					requestOpts: client.RequestOptions{
+						Header:          http.Header{rfc.IfModifiedSince: {tomorrow}},
+						QueryParameters: url.Values{"name": {"originCachegroup"}},
+					},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"NOT MODIFIED when VALID SHORTNAME parameter when NO CHANGES made": {
+					clientSession: TOSession,
+					requestOpts: client.RequestOptions{
+						Header:          http.Header{rfc.IfModifiedSince: {tomorrow}},
+						QueryParameters: url.Values{"shortName": {"mog1"}},
+					},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusNotModified)),
+				},
+				"OK when VALID request": {
+					clientSession: TOSession, expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+				"OK when VALID NAME parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"name": {"parentCachegroup"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						ValidateExpectedField("Name", "parentCachegroup")),
+				},
+				"OK when VALID SHORTNAME parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"shortName": {"pg2"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(1),
+						ValidateExpectedField("ShortName", "pg2")),
+				},
+				"OK when VALID TOPOLOGY parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"topology": {"mso-topology"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+				"OK when VALID TYPE parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"type": {"ORG_LOC"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseLengthGreaterOrEqual(1),
+						ValidateExpectedField("TypeName", "ORG_LOC")),
+				},
+				"EMPTY RESPONSE when INVALID ID parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"id": {"10000"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(0)),
+				},
+				"EMPTY RESPONSE when INVALID TYPE parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"type": {"10000"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), utils.ResponseHasLength(0)),
+				},
+				"FIRST RESULT when LIMIT=1": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), ValidatePagination("limit")),
+				},
+				"SECOND RESULT when LIMIT=1 OFFSET=1": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}, "offset": {"1"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), ValidatePagination("offset")),
+				},
+				"SECOND RESULT when LIMIT=1 PAGE=2": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"orderby": {"id"}, "limit": {"1"}, "page": {"2"}}},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK), ValidatePagination("page")),
+				},
+				"BAD REQUEST when INVALID LIMIT parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"limit": {"-2"}}},
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when INVALID OFFSET parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "offset": {"0"}}},
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"BAD REQUEST when INVALID PAGE parameter": {
+					clientSession: TOSession, requestOpts: client.RequestOptions{QueryParameters: url.Values{"limit": {"1"}, "page": {"0"}}},
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"UNAUTHORIZED when NOT LOGGED IN": {
+					clientSession: NoAuthTOSession, expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusUnauthorized)),
+				},
+			},
+			"POST": {
+				"UNAUTHORIZED when NOT LOGGED IN": {
+					clientSession: NoAuthTOSession, expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusUnauthorized)),
+				},
+			},
+			"PUT": {
+				"OK when VALID request": {
+					endpointId: GetCacheGroupId(t, "cachegroup1"), clientSession: TOSession,
+					requestBody: map[string]interface{}{
+						"latitude":            17.5,
+						"longitude":           17.5,
+						"name":                "cachegroup1",
+						"shortName":           "newShortName",
+						"localizationMethods": []string{"CZ"},
+						"fallbacks":           []string{"fallback1"},
+						"typeName":            "EDGE_LOC",
+						"typeId":              -1,
+					},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+				"OK when updating CG with null Lat/Long": {
+					endpointId: GetCacheGroupId(t, "nullLatLongCG"), clientSession: TOSession,
+					requestBody: map[string]interface{}{
+						"name":      "nullLatLongCG",
+						"shortName": "null-ll",
+						"typeName":  "EDGE_LOC",
+						"fallbacks": []string{"fallback1"},
+						"typeId":    -1,
+					},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+				"BAD REQUEST when updating TYPE of CG in TOPOLOGY": {
+					endpointId: GetCacheGroupId(t, "topology-edge-cg-01"), clientSession: TOSession,
+					requestBody: map[string]interface{}{
+						"id":        -1,
+						"latitude":  0,
+						"longitude": 0,
+						"name":      "topology-edge-cg-01",
+						"shortName": "te1",
+						"typeName":  "MID_LOC",
+						"typeId":    -1,
+					},
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusBadRequest)),
+				},
+				"PRECONDITION FAILED when updating with IMS & IUS Headers": {
+					endpointId: GetCacheGroupId(t, "parentCachegroup"), clientSession: TOSession,
+					requestOpts: client.RequestOptions{
+						Header: http.Header{
+							rfc.IfModifiedSince: {currentTimeRFC}, rfc.IfUnmodifiedSince: {currentTimeRFC},
+						},
+					},
+					requestBody: map[string]interface{}{
+						"latitude":  0,
+						"longitude": 0,
+						"name":      "parentCachegroup",
+						"shortName": "pg1",
+						"typeName":  "MID_LOC",
+						"typeId":    -1,
+					},
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"PRECONDITION FAILED when updating with IFMATCH ETAG Header": {
+					endpointId: GetCacheGroupId(t, "parentCachegroup2"), clientSession: TOSession,
+					requestBody: map[string]interface{}{
+						"latitude":  0,
+						"longitude": 0,
+						"name":      "parentCachegroup2",
+						"shortName": "pg2",
+						"typeName":  "MID_LOC",
+						"typeId":    -1,
+					},
+					requestOpts:  client.RequestOptions{Header: http.Header{rfc.IfMatch: {rfc.ETag(currentTime)}}},
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusPreconditionFailed)),
+				},
+				"UNAUTHORIZED when NOT LOGGED IN": {
+					endpointId: GetCacheGroupId(t, "cachegroup1"), clientSession: NoAuthTOSession,
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusUnauthorized)),
+				},
+			},
+			"DELETE": {
+				"NOT FOUND when INVALID ID parameter": {
+					endpointId: func() int { return 111111 }, clientSession: TOSession,
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusNotFound)),
+				},
+				"UNAUTHORIZED when NOT LOGGED IN": {
+					endpointId: GetCacheGroupId(t, "cachegroup1"), clientSession: NoAuthTOSession,
+					expectations: utils.CkRequest(utils.HasError(), utils.HasStatus(http.StatusUnauthorized)),
+				},
+			},
+			"GET AFTER CHANGES": {
+				"OK when CHANGES made": {
+					clientSession: TOSession,
+					requestOpts: client.RequestOptions{
+						Header: http.Header{
+							rfc.IfModifiedSince: {currentTimeRFC}, rfc.IfUnmodifiedSince: {currentTimeRFC},
+						},
+					},
+					expectations: utils.CkRequest(utils.NoError(), utils.HasStatus(http.StatusOK)),
+				},
+			},
+			"CDNLOCK": {
+				"FORBIDDEN when updating CG when CDN LOCK EXISTS": {},
+			},
+		}
+
+		for method, testCases := range methodTests {
+			t.Run(method, func(t *testing.T) {
+				for name, testCase := range testCases {
+					cg := tc.CacheGroupNullable{}
+
+					if testCase.requestOpts.QueryParameters.Has("type") {
+						val := testCase.requestOpts.QueryParameters.Get("type")
+						if _, err := strconv.Atoi(val); err != nil {
+							testCase.requestOpts.QueryParameters.Set("type", strconv.Itoa(GetTypeId(t, val)))
+						}
+					}
+
+					if testCase.requestBody != nil {
+						if _, ok := testCase.requestBody["id"]; ok {
+							testCase.requestBody["id"] = testCase.endpointId()
+						}
+						if typeId, ok := testCase.requestBody["typeId"]; ok {
+							if typeId == -1 {
+								if typeName, ok := testCase.requestBody["typeName"]; ok {
+									testCase.requestBody["typeId"] = GetTypeId(t, typeName.(string))
+								}
+							}
+						}
+						dat, err := json.Marshal(testCase.requestBody)
+						assert.NoError(t, err, "Error occurred when marshalling request body: %v", err)
+						err = json.Unmarshal(dat, &cg)
+						assert.NoError(t, err, "Error occurred when unmarshalling request body: %v", err)
+					}
+
+					switch method {
+					case "GET", "GET AFTER CHANGES":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.clientSession.GetCacheGroups(testCase.requestOpts)
+							for _, check := range testCase.expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "POST":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.clientSession.CreateCacheGroup(cg, testCase.requestOpts)
+							for _, check := range testCase.expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "PUT":
+						t.Run(name, func(t *testing.T) {
+							resp, reqInf, err := testCase.clientSession.UpdateCacheGroup(testCase.endpointId(), cg, testCase.requestOpts)
+							for _, check := range testCase.expectations {
+								check(t, reqInf, resp.Response, resp.Alerts, err)
+							}
+						})
+					case "DELETE":
+						t.Run(name, func(t *testing.T) {
+							alerts, reqInf, err := testCase.clientSession.DeleteCacheGroup(testCase.endpointId(), testCase.requestOpts)
+							for _, check := range testCase.expectations {
+								check(t, reqInf, nil, alerts, err)
+							}
+						})
+					case "CDNLOCK":
+						t.Run(name, func(t *testing.T) {
+							UpdateCachegroupWithLocks(t)
+						})
+					}
+				}
+			})
+		}
 	})
 }
 
-func ReadUpdateTestCacheGroupWithNullLatLong(t *testing.T) {
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Add("name", "nullLatLongCG")
-	resp, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("expected no error GETting cachegroups, but got %v", err)
-	}
-	if len(resp.Response) != 1 {
-		t.Fatalf("expected just one cachegroup, but got %d", len(resp.Response))
-	}
-	cg := resp.Response[0]
-	if cg.ID == nil {
-		t.Fatalf("got nil ID")
+func ValidateExpectedField(field string, expected string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		cgResp := resp.([]tc.CacheGroupNullable)
+		cg := cgResp[0]
+		switch field {
+		case "Name":
+			assert.Equal(t, expected, *cg.Name, "Expected name to be %v, but got %v", expected, *cg.Name)
+		case "ShortName":
+			assert.Equal(t, expected, *cg.ShortName, "Expected shortName to be %v, but got %v", expected, *cg.ShortName)
+		case "TypeName":
+			assert.Equal(t, expected, *cg.Type, "Expected type to be %v, but got %v", expected, *cg.Type)
+		default:
+			t.Errorf("Expected field: %v, does not exist in response", field)
+		}
 	}
-	if cg.Latitude == nil || cg.Longitude == nil {
-		t.Fatalf("expected lat/long to be not nil")
+}
+
+func ValidateResponseFields() utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		cgResp := resp.([]tc.CacheGroupNullable)
+		cg := cgResp[0]
+		assert.NotNil(t, cg.ID, "Expected response id to not be nil")
+		assert.NotNil(t, cg.Latitude, "Expected latitude to not be nil")
+		assert.NotNil(t, cg.Longitude, "Expected longitude to not be nil")
+		assert.Equal(t, 0.0, *cg.Longitude, "Expected Longitude to be 0, but got %v", cg.Longitude)
+		assert.Equal(t, 0.0, *cg.Latitude, "Expected Latitude to be 0, but got %v", cg.Latitude)
 	}
-	if *cg.Latitude != 0 || *cg.Longitude != 0 {
-		t.Errorf("expected lat/long to be 0 and 0, but got %f and %f", *cg.Latitude, *cg.Longitude)
+}
+
+func ValidatePagination(paginationParam string) utils.CkReqFunc {
+	return func(t *testing.T, _ toclientlib.ReqInf, resp interface{}, _ tc.Alerts, _ error) {
+		paginationResp := resp.([]tc.CacheGroupNullable)
+
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("orderby", "id")
+		respBase, _, err := TOSession.GetCacheGroups(opts)
+		assert.RequireNoError(t, err, "cannot get Cache Groups: %v - alerts: %+v", err, respBase.Alerts)
+
+		cachegroup := respBase.Response
+		assert.RequireGreaterOrEqual(t, len(cachegroup), 3, "Need at least 3 Cache Groups in Traffic Ops to test pagination support, found: %d", len(cachegroup))
+		switch paginationParam {
+		case "limit:":
+			assert.Exactly(t, cachegroup[:1], paginationResp, "expected GET Cachegroups with limit = 1 to return first result")
+		case "offset":
+			assert.Exactly(t, cachegroup[1:2], paginationResp, "expected GET cachegroup with limit = 1, offset = 1 to return second result")
+		case "page":
+			assert.Exactly(t, cachegroup[1:2], paginationResp, "expected GET cachegroup with limit = 1, page = 2 to return second result")
+		}
 	}
-	cg.FallbackToClosest = util.BoolPtr(false)
-	_, _, err = TOSession.UpdateCacheGroup(*cg.ID, cg, client.NewRequestOptions())
-	if err != nil {
-		t.Errorf("expected no error updating a cachegroup with null lat/long, but got %v", err)
+}
+
+func GetTypeId(t *testing.T, typeName string) int {
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("name", typeName)
+	resp, _, err := TOSession.GetTypes(opts)
+
+	assert.RequireNoError(t, err, "Get Types Request failed with error: %v", err)
+	assert.RequireEqual(t, 1, len(resp.Response), "Expected response object length 1, but got %d", len(resp.Response))
+	assert.RequireNotNil(t, &resp.Response[0].ID, "Expected id to not be nil")
+
+	return resp.Response[0].ID
+}
+
+func GetCacheGroupId(t *testing.T, cacheGroupName string) func() int {
+	return func() int {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("name", cacheGroupName)
+
+		resp, _, err := TOSession.GetCacheGroups(opts)
+		assert.RequireNoError(t, err, "Get Cache Groups Request failed with error: %v", err)
+		assert.RequireEqual(t, len(resp.Response), 1, "Expected response object length 1, but got %d", len(resp.Response))
+		assert.RequireNotNil(t, resp.Response[0].ID, "Expected id to not be nil")
+
+		return *resp.Response[0].ID
 	}
 }
 
@@ -96,22 +386,17 @@ func UpdateCachegroupWithLocks(t *testing.T) {
 	opts := client.NewRequestOptions()
 	opts.QueryParameters.Add("name", "cachegroup1")
 	cgResp, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("couldn't get cachegroup: %v", err)
-	}
-	if len(cgResp.Response) != 1 {
-		t.Fatalf("expected only one cachegroup in response, but got %d, quitting", len(cgResp.Response))
-	}
+	assert.RequireNoError(t, err, "couldn't get cachegroup: %v", err)
+	assert.RequireEqual(t, 1, len(cgResp.Response), "expected only one cachegroup in response, but got %d, quitting", len(cgResp.Response))
+
 	opts.QueryParameters.Del("name")
 	opts.QueryParameters.Add("cachegroupName", "cachegroup1")
 	serversResp, _, err := TOSession.GetServers(opts)
-	if err != nil {
-		t.Fatalf("couldn't get servers for cachegroup: %v", err)
-	}
+	assert.RequireNoError(t, err, "couldn't get servers for cachegroup: %v", err)
+
 	servers = serversResp.Response
-	if len(servers) == 0 {
-		t.Fatalf("couldn't get a cachegroup with 1 or more servers assigned, quitting")
-	}
+	assert.RequireGreaterOrEqual(t, len(servers), 1, "couldn't get a cachegroup with 1 or more servers assigned, quitting")
+
 	server := servers[0]
 	if server.CDNName != nil {
 		cdnName = *server.CDNName
@@ -119,12 +404,9 @@ func UpdateCachegroupWithLocks(t *testing.T) {
 		opts = client.RequestOptions{}
 		opts.QueryParameters.Add("id", strconv.Itoa(*server.CDNID))
 		cdnResp, _, err := TOSession.GetCDNs(opts)
-		if err != nil {
-			t.Fatalf("couldn't get CDN: %v", err)
-		}
-		if len(cdnResp.Response) != 1 {
-			t.Fatalf("expected only one CDN in response, but got %d", len(cdnResp.Response))
-		}
+		assert.RequireNoError(t, err, "couldn't get CDN: %v", err)
+		assert.RequireEqual(t, 1, len(cdnResp.Response), "expected only one CDN in response, but got %d", len(cdnResp.Response))
+
 		cdnName = cdnResp.Response[0].Name
 	}
 
@@ -140,16 +422,13 @@ func UpdateCachegroupWithLocks(t *testing.T) {
 	user1.TenantID = 1
 	user1.FullName = util.StrPtr("firstName LastName")
 	_, _, err = TOSession.CreateUser(user1, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("could not create test user with username: %s. err: %v", user1.Username, err)
-	}
+	assert.RequireNoError(t, err, "could not create test user with username: %s. err: %v", user1.Username, err)
+
 	defer ForceDeleteTestUsersByUsernames(t, []string{"lock_user1"})
 
 	// Establish a session with the newly created non admin level user
 	userSession, _, err := client.LoginWithAgent(Config.TrafficOps.URL, user1.Username, *user1.LocalPassword, true, "to-api-v4-client-tests", false, toReqTimeout)
-	if err != nil {
-		t.Fatalf("could not login with user lock_user1: %v", err)
-	}
+	assert.RequireNoError(t, err, "could not login with user lock_user1: %v", err)
 
 	// Create a lock for this user
 	_, _, err = userSession.CreateCDNLock(tc.CDNLock{
@@ -157,171 +436,26 @@ func UpdateCachegroupWithLocks(t *testing.T) {
 		Message: util.StrPtr("test lock"),
 		Soft:    util.BoolPtr(false),
 	}, client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("couldn't create cdn lock: %v", err)
-	}
+	assert.RequireNoError(t, err, "couldn't create cdn lock: %v", err)
+
 	cg := cgResp.Response[0]
 
 	// Try to update a cachegroup on a CDN that another user has a hard lock on -> this should fail
 	cg.ShortName = util.StrPtr("changedShortName")
 	_, reqInf, err := TOSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{})
-	if err == nil {
-		t.Error("expected an error while updating a cachegroup for a CDN for which a hard lock is held by another user, but got nothing")
-	}
-	if reqInf.StatusCode != http.StatusForbidden {
-		t.Errorf("expected a 403 forbidden status while updating a cachegroup for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
-	}
+	assert.Error(t, err, "expected an error while updating a cachegroup for a CDN for which a hard lock is held by another user, but got nothing")
+	assert.Equal(t, http.StatusForbidden, reqInf.StatusCode, "expected a 403 forbidden status while updating a cachegroup for a CDN for which a hard lock is held by another user, but got %d", reqInf.StatusCode)
 
 	// Try to update a cachegroup on a CDN that the same user has a hard lock on -> this should succeed
 	_, reqInf, err = userSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("expected no error while updating a cachegroup for a CDN for which a hard lock is held by the same user, but got %v", err)
-	}
+	assert.NoError(t, err, "expected no error while updating a cachegroup for a CDN for which a hard lock is held by the same user, but got %v", err)
 
 	// Delete the lock
 	_, _, err = userSession.DeleteCDNLocks(client.RequestOptions{QueryParameters: url.Values{"cdn": []string{cdnName}}})
-	if err != nil {
-		t.Errorf("expected no error while deleting other user's lock using admin endpoint, but got %v", err)
-	}
-}
-
-func UpdateTestCacheGroupsWithHeaders(t *testing.T, h http.Header) {
-	if len(testData.CacheGroups) < 1 {
-		t.Fatal("Need at least one Cache Group to test updating Cache Groups")
-	}
-	firstCG := testData.CacheGroups[0]
-	if firstCG.Name == nil {
-		t.Fatal("Found Cache Group with null or undefined name in testing data")
-	}
-
-	opts := client.RequestOptions{
-		Header:          h,
-		QueryParameters: url.Values{},
-	}
-	opts.QueryParameters.Set("name", *firstCG.Name)
-
-	resp, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("cannot get Cache Group '%s': %v - alerts: %+v", *firstCG.Name, err, resp.Alerts)
-	}
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected exactly one Cache Group to exist with name '%s', but got: %d", *firstCG.Name, len(resp.Response))
-	}
-
-	cg := resp.Response[0]
-	if cg.TypeID == nil {
-		t.Fatalf("Traffic Ops returned Cache Group '%s' with null or undefined typeId", *firstCG.Name)
-	}
-	if cg.ID == nil {
-		t.Fatalf("Traffic Ops returned Cache Group '%s' with null or undefined id", *firstCG.Name)
-	}
-	expectedShortName := "blah"
-	cg.ShortName = &expectedShortName
-
-	// fix the type id for test
-	typeOpts := client.NewRequestOptions()
-	typeOpts.QueryParameters.Set("id", strconv.Itoa(*cg.TypeID))
-	typeResp, _, err := TOSession.GetTypes(typeOpts)
-	if err != nil {
-		t.Fatalf("Failed to fetch Type #%d: %v - alerts: %+v", *cg.TypeID, err, typeResp.Alerts)
-	}
-	if len(typeResp.Response) != 1 {
-		t.Fatalf("Expected exactly one Type to exist with ID %d, but got: %d", *cg.TypeID, len(typeResp.Response))
-	}
-
-	cg.TypeID = &typeResp.Response[0].ID
-	_, reqInf, err := TOSession.UpdateCacheGroup(*cg.ID, cg, opts)
-	if err == nil {
-		t.Errorf("Expected an error showing Precondition Failed, got none")
-	}
-	if reqInf.StatusCode != http.StatusPreconditionFailed {
-		t.Errorf("Expected status code 412, got %v", reqInf.StatusCode)
-	}
-}
-
-func GetTestCacheGroupsAfterChangeIMS(t *testing.T, header http.Header) {
-	opts := client.RequestOptions{
-		Header: header,
-	}
-	resp, reqInf, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("Expected no error, but got %v - alerts: %+v", err, resp.Alerts)
-	}
-	if reqInf.StatusCode != http.StatusOK {
-		t.Fatalf("Expected 200 status code, got %v", reqInf.StatusCode)
-	}
-
-	currentTime := time.Now().UTC()
-	currentTime = currentTime.Add(1 * time.Second)
-	timeStr := currentTime.Format(time.RFC1123)
-	opts.Header.Set(rfc.IfModifiedSince, timeStr)
-	resp, reqInf, err = TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Errorf("Expected no error, but got %v - alerts: %+v", err, resp.Alerts)
-	}
-	if reqInf.StatusCode != http.StatusNotModified {
-		t.Fatalf("Expected 304 status code, got %v", reqInf.StatusCode)
-	}
-}
-
-func GetTestCacheGroupsByShortNameIMS(t *testing.T) {
-	opts := client.NewRequestOptions()
-	futureTime := time.Now().AddDate(0, 0, 1)
-	time := futureTime.Format(time.RFC1123)
-	opts.Header.Set(rfc.IfModifiedSince, time)
-	for _, cg := range testData.CacheGroups {
-		if cg.ShortName == nil {
-			t.Error("found Cache Group with null or undefined 'short name' in test data")
-			continue
-		}
-		opts.QueryParameters.Set("shortName", *cg.ShortName)
-		resp, reqInf, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("Expected no error, but got %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Errorf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
-	}
-}
-
-func GetTestCacheGroupsByNameIMS(t *testing.T) {
-	opts := client.NewRequestOptions()
-	futureTime := time.Now().AddDate(0, 0, 1)
-	time := futureTime.Format(time.RFC1123)
-	opts.Header.Set(rfc.IfModifiedSince, time)
-	for _, cg := range testData.CacheGroups {
-		if cg.Name == nil {
-			t.Error("found Cache Group with null or undefined name in test data")
-			continue
-		}
-		opts.QueryParameters.Set("name", *cg.Name)
-		resp, reqInf, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("Expected no error, but got %v - alerts: %+v", err, resp.Alerts)
-		}
-		if reqInf.StatusCode != http.StatusNotModified {
-			t.Errorf("Expected 304 status code, got %v", reqInf.StatusCode)
-		}
-	}
-}
-
-func GetTestCacheGroupsIMS(t *testing.T) {
-	opts := client.NewRequestOptions()
-	futureTime := time.Now().AddDate(0, 0, 1)
-	time := futureTime.Format(time.RFC1123)
-	opts.Header.Set(rfc.IfModifiedSince, time)
-	resp, reqInf, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Errorf("Expected no error, but got %v - alerts: %+v", err, resp.Alerts)
-	}
-	if reqInf.StatusCode != http.StatusNotModified {
-		t.Errorf("Expected 304 status code, got %v", reqInf.StatusCode)
-	}
+	assert.NoError(t, err, "expected no error while deleting other user's lock using admin endpoint, but got %v", err)
 }
 
 func CreateTestCacheGroups(t *testing.T) {
-
 	for _, cg := range testData.CacheGroups {
 
 		resp, _, err := TOSession.CreateCacheGroup(cg, client.RequestOptions{})
@@ -340,418 +474,8 @@ func CreateTestCacheGroups(t *testing.T) {
 		if cg.Type != nil && resp.Response.Type == nil {
 			t.Error("Type is null in response when it should have a value")
 		}
-		if resp.Response.LocalizationMethods == nil {
-			t.Error("Localization methods are null")
-		}
-		if resp.Response.Fallbacks == nil {
-			t.Error("Fallbacks are null")
-		}
-	}
-}
-
-func GetTestCacheGroups(t *testing.T) {
-	resp, _, err := TOSession.GetCacheGroups(client.RequestOptions{})
-	if err != nil {
-		t.Errorf("cannot get Cache Groups: %v - alerts: %+v", err, resp.Alerts)
-	}
-	expectedCachegroups := make(map[string]struct{}, len(testData.CacheGroups))
-	for _, cg := range testData.CacheGroups {
-		if cg.Name == nil {
-			t.Error("Found Cache Group in testing data with null or undefined name")
-			continue
-		}
-		expectedCachegroups[*cg.Name] = struct{}{}
-	}
-	foundCachegroups := make(map[string]struct{}, len(expectedCachegroups))
-	for _, cg := range resp.Response {
-		if cg.Name == nil {
-			t.Error("Traffic Ops returned a Cache Group with null or undefined name")
-			continue
-		}
-		if _, expected := expectedCachegroups[*cg.Name]; !expected {
-			t.Errorf("got unexpected cachegroup: %s", *cg.Name)
-		}
-		if _, found := foundCachegroups[*cg.Name]; !found {
-			foundCachegroups[*cg.Name] = struct{}{}
-		} else {
-			t.Errorf("GET returned duplicate cachegroup: %s", *cg.Name)
-		}
-	}
-}
-
-func GetTestCacheGroupsByName(t *testing.T) {
-	opts := client.NewRequestOptions()
-	for _, cg := range testData.CacheGroups {
-		if cg.Name == nil {
-			t.Error("found Cache Group with null or undefined name in test data")
-			continue
-		}
-		opts.QueryParameters.Set("name", *cg.Name)
-		resp, _, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("cannot get CacheGroup by name '%s': %v - alerts: %+v", *cg.Name, err, resp)
-		}
-		if len(resp.Response) < 1 {
-			t.Errorf("Expected exactly one Cache Group with name '%s', but got none", *cg.Name)
-			continue
-		}
-		if len(resp.Response) > 1 {
-			t.Errorf("Expected exactly one Cache Group with name '%s', but got %d", *cg.Name, len(resp.Response))
-			t.Log("Testing will proceed using the first Cache Group found in the response")
-		}
-		respCG := resp.Response[0]
-		if respCG.Name == nil {
-			t.Errorf("Cache Group as returned by Traffic Ops had null or undefined name (should be '%s')", *cg.Name)
-		}
-		if *respCG.Name != *cg.Name {
-			t.Errorf("name expected: %s, actual: %s", *cg.Name, *respCG.Name)
-		}
-	}
-}
-
-func GetTestCacheGroupsByShortName(t *testing.T) {
-	opts := client.NewRequestOptions()
-	for _, cg := range testData.CacheGroups {
-		if cg.ShortName == nil {
-			t.Error("found Cache Group with null or undefined 'short name' in test data")
-			continue
-		}
-		opts.QueryParameters.Set("shortName", *cg.ShortName)
-		resp, _, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("cannot get Cache Group by 'short name': %v - alerts: %+v", err, resp.Alerts)
-		}
-		if len(resp.Response) > 1 {
-			t.Errorf("Expected exactly one Cache Group with name '%s', but got %d", *cg.ShortName, len(resp.Response))
-			t.Log("Testing will proceed using the first Cache Group found in the response")
-		}
-		respCG := resp.Response[0]
-		if respCG.ShortName == nil {
-			t.Errorf("Cache Group as returned by Traffic Ops had null or undefined name (should be '%s')", *cg.ShortName)
-		}
-		if *respCG.ShortName != *cg.ShortName {
-			t.Errorf("short name expected: %s, actual: %s", *cg.ShortName, *respCG.ShortName)
-		}
-	}
-}
-
-func GetTestCacheGroupsByTopology(t *testing.T) {
-	opts := client.NewRequestOptions()
-	for _, top := range testData.Topologies {
-		opts.QueryParameters.Set("topology", top.Name)
-		resp, _, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("cannot get Cache Groups by Topology '%s': %v - alerts: %v", top.Name, err, resp.Alerts)
-		}
-		expectedCGs := topologyCachegroups(top)
-		for _, cg := range resp.Response {
-			if cg.Name == nil {
-				t.Errorf("Traffic Ops returned a Cache Group in Topology '%s' with null or undefined name", top.Name)
-				continue
-			}
-			if _, exists := expectedCGs[*cg.Name]; !exists {
-				t.Errorf("GET cachegroups by topology - expected one of: %v, actual: %s", expectedCGs, *cg.Name)
-			}
-		}
-	}
-}
-
-func topologyCachegroups(top tc.Topology) map[string]struct{} {
-	res := make(map[string]struct{}, len(top.Nodes))
-	for _, node := range top.Nodes {
-		res[node.Cachegroup] = struct{}{}
-	}
-	return res
-}
-
-func UpdateTestCacheGroups(t *testing.T) {
-	if len(testData.CacheGroups) < 1 {
-		t.Fatal("Need at least one Cache Group to test updating Cache Groups")
-	}
-	firstCG := testData.CacheGroups[0]
-	if firstCG.Name == nil {
-		t.Fatal("Cache Group selected for testing had a null or undefined name")
-	}
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("name", *firstCG.Name)
-	resp, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("cannot get Cache Group by name '%s': %v - alerts: %+v", *firstCG.Name, err, resp.Alerts)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg := resp.Response[0]
-	if cg.TypeID == nil {
-		t.Fatal("Cache Group returned from Traffic Ops had null or undefined typeId")
-	}
-	if cg.ID == nil {
-		t.Fatal("Cache Group returned from Traffic Ops had null or undefined id")
-	}
-	expectedShortName := "blah"
-	cg.ShortName = &expectedShortName
-
-	// fix the type id for test
-	typeOpts := client.NewRequestOptions()
-	typeOpts.QueryParameters.Set("id", strconv.Itoa(*cg.TypeID))
-	typeResp, _, err := TOSession.GetTypes(typeOpts)
-	if err != nil {
-		t.Errorf("could not lookup an ID for the Type of this Cache Group: %v - alerts: %+v", err, typeResp.Alerts)
-	}
-	if len(typeResp.Response) == 0 {
-		t.Fatal("got an empty response for types")
-	}
-	cg.TypeID = &typeResp.Response[0].ID
-	opts.QueryParameters = url.Values{}
-	updResp, _, err := TOSession.UpdateCacheGroup(*cg.ID, cg, opts)
-	if err != nil {
-		t.Errorf("cannot update Cache Group: %v - alerts: %+v", err, updResp.Alerts)
-	}
-
-	// Check response to make sure fields aren't null
-	if cg.ParentName != nil && updResp.Response.ParentName == nil {
-		t.Error("Parent cachegroup is null in response when it should have a value")
-	}
-	if cg.SecondaryParentName != nil && updResp.Response.SecondaryParentName == nil {
-		t.Error("Secondary parent cachegroup is null in response when it should have a value\n")
-	}
-	if cg.Type != nil && updResp.Response.Type == nil {
-		t.Error("Type is null in response when it should have a value\n")
-	}
-	if updResp.Response.LocalizationMethods == nil {
-		t.Error("Localization methods are null")
-	}
-	if updResp.Response.Fallbacks == nil {
-		t.Error("Fallbacks are null")
-	}
-
-	// Retrieve the CacheGroup to check CacheGroup name got updated
-	opts.QueryParameters.Set("id", strconv.Itoa(*cg.ID))
-	resp, _, err = TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("cannot GET CacheGroup by name: '%s', %v", *firstCG.Name, err)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg = resp.Response[0]
-	if cg.ShortName == nil {
-		t.Fatal("Traffic Ops returned a Cache Group with nullor undefined short name")
-	}
-	if *cg.ShortName != expectedShortName {
-		t.Errorf("results do not match actual: %s, expected: %s", *cg.ShortName, expectedShortName)
-	}
-	if cg.ID == nil {
-		t.Fatal("Cache Group returned from Traffic Ops had null or undefined id")
-	}
-
-	// test coordinate updates
-	expectedLat := 7.0
-	expectedLong := 8.0
-	cg.Latitude = &expectedLat
-	cg.Longitude = &expectedLong
-	updResp, _, err = TOSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("cannot UPDATE CacheGroup by id: %v - alerts: %+v", err, updResp.Alerts)
-	}
-
-	resp, _, err = TOSession.GetCacheGroups(opts)
-
-	if err != nil {
-		t.Fatalf("cannot GET CacheGroup by id: '%d', %v", *cg.ID, err)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg = resp.Response[0]
-	if cg.Latitude == nil {
-		t.Fatal("Cache Group returned from Traffic Ops had null or undefined latitude")
-	}
-	if cg.Longitude == nil {
-		t.Fatal("Cache Group returned from Traffic Ops had null or undefined longitude")
-	}
-	if cg.ID == nil {
-		t.Fatal("Cache Group returned from Traffic Ops had null or undefined id")
-	}
-	if *cg.Latitude != expectedLat {
-		t.Errorf("failed to update latitude (expected = %f, actual = %f)", expectedLat, *cg.Latitude)
-	}
-	if *cg.Longitude != expectedLong {
-		t.Errorf("failed to update longitude (expected = %f, actual = %f)", expectedLong, *cg.Longitude)
-	}
-
-	// test localizationMethods
-	expectedMethods := []tc.LocalizationMethod{tc.LocalizationMethodGeo}
-	cg.LocalizationMethods = &expectedMethods
-	updResp, _, err = TOSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("cannot UPDATE CacheGroup by ID %d: %v - alerts: %+v", *cg.ID, err, updResp.Alerts)
-	}
-
-	opts.QueryParameters.Set("id", strconv.Itoa(*cg.ID))
-	resp, _, err = TOSession.GetCacheGroups(opts)
-
-	if err != nil {
-		t.Errorf("cannot GET CacheGroup by ID %d: %v - alerts: %+v", *cg.ID, err, resp.Alerts)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg = resp.Response[0]
-	if cg.LocalizationMethods == nil {
-		t.Fatal("Traffic Ops returned Cache Group with null or undefined localizationMethods")
-	}
-	if !reflect.DeepEqual(expectedMethods, *cg.LocalizationMethods) {
-		t.Errorf("failed to update localizationMethods (expected = %v, actual = %v)", expectedMethods, *cg.LocalizationMethods)
-	}
-
-	// test cachegroup fallbacks
-
-	// Retrieve the CacheGroup to check CacheGroup name got updated
-	firstEdgeCGName := "cachegroup1"
-	opts.QueryParameters = url.Values{}
-	opts.QueryParameters.Set("name", firstEdgeCGName)
-	resp, _, err = TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Errorf("cannot get Cache Group by name '%s': %v - alerts: %+v", firstEdgeCGName, err, resp.Alerts)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg = resp.Response[0]
-	if cg.Name == nil {
-		t.Error("Cache Group returned from Traffic Ops had null or undefined name")
-	} else if *cg.Name != firstEdgeCGName {
-		t.Errorf("results do not match actual: %s, expected: %s", *cg.Name, firstEdgeCGName)
-	}
-	if cg.ID == nil {
-		t.Fatal("Cache Group returned from Traffic Ops had null or undefined id")
-	}
-
-	// Test adding fallbacks when previously nil
-	expectedFallbacks := []string{"fallback1", "fallback2"}
-	cg.Fallbacks = &expectedFallbacks
-	updResp, _, err = TOSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("cannot update Cache Group by ID: %v - alerts: %+v", err, updResp.Alerts)
-	}
-
-	opts.QueryParameters = url.Values{}
-	opts.QueryParameters.Set("id", strconv.Itoa(*cg.ID))
-	resp, _, err = TOSession.GetCacheGroups(opts)
-
-	if err != nil {
-		t.Errorf("cannot GET CacheGroup by ID #%d: %v - alerts: %+v", *cg.ID, err, resp.Alerts)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg = resp.Response[0]
-	if cg.Fallbacks == nil {
-		t.Error("Cache Group returned by Traffic Ops had null or undefined fallbacks")
-	} else if !reflect.DeepEqual(expectedFallbacks, *cg.Fallbacks) {
-		t.Errorf("failed to update fallbacks (expected = %v, actual = %v)", expectedFallbacks, *cg.Fallbacks)
-	}
-	if cg.ID == nil {
-		t.Fatal("Cache Group returned by Traffic Ops had null or undefined ID")
-	}
-
-	// Test adding fallback to existing list
-	expectedFallbacks = []string{"fallback1", "fallback2", "fallback3"}
-	cg.Fallbacks = &expectedFallbacks
-	updResp, _, err = TOSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("cannot update Cache Group by ID: %v - %+v)", err, updResp.Alerts)
-	}
-
-	opts.QueryParameters.Set("id", strconv.Itoa(*cg.ID))
-	resp, _, err = TOSession.GetCacheGroups(opts)
-
-	if err != nil {
-		t.Errorf("cannot get Cache Group by id #%d: %v - alerts: %+v", *cg.ID, err, resp.Alerts)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg = resp.Response[0]
-	if cg.Fallbacks == nil {
-		t.Error("Cache Group returned by Traffic Ops had null or undefined fallbacks")
-	} else if !reflect.DeepEqual(expectedFallbacks, *cg.Fallbacks) {
-		t.Errorf("failed to update fallbacks (expected = %v, actual = %v)", expectedFallbacks, *cg.Fallbacks)
-	}
-	if cg.ID == nil {
-		t.Fatal("Cache Group returned by Traffic Ops had null or undefined ID")
-	}
-
-	// Test removing fallbacks
-	expectedFallbacks = []string{}
-	cg.Fallbacks = &expectedFallbacks
-	updResp, _, err = TOSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{})
-	if err != nil {
-		t.Errorf("cannot update Cache Group by ID: %v - alerts: %+v", err, updResp.Alerts)
-	}
-
-	opts.QueryParameters.Set("id", strconv.Itoa(*cg.ID))
-	resp, _, err = TOSession.GetCacheGroups(opts)
-
-	if err != nil {
-		t.Errorf("cannot get Cache Group by ID: '%d', %v", *cg.ID, err)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg = resp.Response[0]
-	if cg.Fallbacks == nil {
-		t.Error("Cache Group returned by Traffic Ops had null or undefined fallbacks")
-	} else if !reflect.DeepEqual(expectedFallbacks, *cg.Fallbacks) {
-		t.Errorf("failed to update fallbacks (expected = %v, actual = %v)", expectedFallbacks, *cg.Fallbacks)
-	}
-	if cg.ID == nil {
-		t.Fatal("Cache Group returned by Traffic Ops had null or undefined ID")
-	}
-
-	const topologyEdgeCGName = "topology-edge-cg-01"
-	opts.QueryParameters = url.Values{}
-	opts.QueryParameters.Set("name", topologyEdgeCGName)
-	resp, _, err = TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("cannot get Cache Group by name '%s': %v - alerts: %+v", topologyEdgeCGName, err, resp.Alerts)
-	}
-	if len(resp.Response) == 0 {
-		t.Fatal("got an empty response for cachegroups")
-	}
-	cg = resp.Response[0]
-	if cg.TypeID == nil {
-		t.Fatal("Cache Group returned by Traffic Ops had null or undefined typeId")
-	}
-	if cg.ID == nil {
-		t.Fatal("Cache Group returned by Traffic Ops had null or undefined ID")
-	}
-
-	var cacheGroupEdgeType, cacheGroupMidType tc.Type
-	types, _, err := TOSession.GetTypes(client.RequestOptions{})
-	if err != nil {
-		t.Fatalf("unable to get Types: %v - alerts: %+v", err, types.Alerts)
-	}
-	for _, typeObject := range types.Response {
-		switch typeObject.Name {
-		case tc.CacheGroupEdgeTypeName:
-			cacheGroupEdgeType = typeObject
-		case tc.CacheGroupMidTypeName:
-			cacheGroupMidType = typeObject
-		}
-	}
-	if *cg.TypeID != cacheGroupEdgeType.ID {
-		t.Fatalf("expected cachegroup %s to have type %s, actual type was %s", topologyEdgeCGName, tc.CacheGroupEdgeTypeName, *cg.Type)
-	}
-	*cg.TypeID = cacheGroupMidType.ID
-	updResp, reqInfo, err := TOSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{})
-	if err == nil {
-		t.Fatalf("expected an error when updating the type of cache group %s because it is assigned to a topology, actual error was nil", *cg.Name)
-	}
-	if reqInfo.StatusCode != http.StatusBadRequest {
-		msg := "expected to receive status code %d but received status code %d - error was: %v - alerts: %+v"
-		t.Fatalf(msg, http.StatusBadRequest, reqInfo.StatusCode, err, updResp.Alerts)
+		assert.NotNil(t, resp.Response.LocalizationMethods, "Localization methods are null")
+		assert.NotNil(t, resp.Response.Fallbacks, "Fallbacks are null")
 	}
 }
 
@@ -765,12 +489,12 @@ func DeleteTestCacheGroups(t *testing.T) {
 			t.Error("Found a Cache Group with null or undefined name")
 			continue
 		}
-		// Retrieve the CacheGroup by name so we can get the id for the Update
+
+		// Retrieve the CacheGroup by name so we can get the id for Deletion
 		opts.QueryParameters.Set("name", *cg.Name)
 		resp, _, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("cannot GET CacheGroup by name '%s': %v - alerts: %+v", *cg.Name, err, resp.Alerts)
-		}
+		assert.NoError(t, err, "Cannot GET CacheGroup by name '%s': %v - alerts: %+v", *cg.Name, err, resp.Alerts)
+
 		if len(resp.Response) < 1 {
 			t.Errorf("Could not find test data Cache Group '%s' in Traffic Ops", *cg.Name)
 			continue
@@ -784,29 +508,19 @@ func DeleteTestCacheGroups(t *testing.T) {
 			continue
 		}
 
-		// TODO: Typo here? cg is already reassigned to resp.Response[0] - is respCG supposed to be different?
-		respCG := resp.Response[0]
-		if respCG.ID == nil {
+		if cg.ID == nil {
 			t.Error("Traffic Ops returned a Cache Group with null or undefined ID")
 			continue
 		}
-		if respCG.Name == nil {
-			t.Error("Traffic Ops returned a Cache Group with null or undefined name")
-			continue
-		}
-		alerts, _, err := TOSession.DeleteCacheGroup(*respCG.ID, client.RequestOptions{})
-		if err != nil {
-			t.Errorf("cannot delete Cache Group: %v - alerts: %+v", err, alerts)
-		}
+
+		alerts, _, err := TOSession.DeleteCacheGroup(*cg.ID, client.RequestOptions{})
+		assert.NoError(t, err, "Cannot delete Cache Group: %v - alerts: %+v", err, alerts)
+
 		// Retrieve the CacheGroup to see if it got deleted
-		opts.QueryParameters.Set("name", *respCG.Name)
+		opts.QueryParameters.Set("name", *cg.Name)
 		cgs, _, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("error deleting Cache Group by name: %v - alerts: %+v", err, cgs.Alerts)
-		}
-		if len(cgs.Response) > 0 {
-			t.Errorf("expected CacheGroup name: %s to be deleted", *cg.Name)
-		}
+		assert.NoError(t, err, "Error deleting Cache Group by name: %v - alerts: %+v", err, cgs.Alerts)
+		assert.Equal(t, 0, len(cgs.Response), "Expected CacheGroup name: %s to be deleted", *cg.Name)
 	}
 
 	opts = client.NewRequestOptions()
@@ -814,11 +528,10 @@ func DeleteTestCacheGroups(t *testing.T) {
 	for _, cg := range parentlessCacheGroups {
 		// nil check for cg.Name occurs prior to insertion into parentlessCacheGroups
 		opts.QueryParameters.Set("name", *cg.Name)
-		// Retrieve the CacheGroup by name so we can get the id for the Update
+		// Retrieve the CacheGroup by name so we can get the id for Deletion
 		resp, _, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("cannot get Cache Group by name '%s': %v - alerts: %+v", *cg.Name, err, resp.Alerts)
-		}
+		assert.NoError(t, err, "Cannot get Cache Group by name '%s': %v - alerts: %+v", *cg.Name, err, resp.Alerts)
+
 		if len(resp.Response) < 1 {
 			t.Errorf("Cache Group '%s' somehow stopped existing since the last time we ask Traffic Ops about it", *cg.Name)
 			continue
@@ -830,202 +543,12 @@ func DeleteTestCacheGroups(t *testing.T) {
 			continue
 		}
 		delResp, _, err := TOSession.DeleteCacheGroup(*respCG.ID, client.RequestOptions{})
-		if err != nil {
-			t.Errorf("cannot delete Cache Group '%s': %v - alerts: %+v", *respCG.Name, err, delResp.Alerts)
-		}
+		assert.NoError(t, err, "Cannot delete Cache Group '%s': %v - alerts: %+v", *respCG.Name, err, delResp.Alerts)
 
 		// Retrieve the CacheGroup to see if it got deleted
 		opts.QueryParameters.Set("name", *cg.Name)
 		cgs, _, err := TOSession.GetCacheGroups(opts)
-		if err != nil {
-			t.Errorf("error attempting to fetch Cache Group '%s' after deletion: %v - alerts: %+v", *cg.Name, err, cgs.Alerts)
-		}
-		if len(cgs.Response) > 0 {
-			t.Errorf("expected Cache Group '%s' to be deleted", *cg.Name)
-		}
-	}
-}
-
-func CheckCacheGroupsAuthentication(t *testing.T) {
-	if len(testData.CacheGroups) < 1 {
-		t.Fatalf("Need at least one Cache Group to test Cache Group API authentication")
-	}
-	cg := testData.CacheGroups[0]
-	if cg.Name == nil {
-		t.Fatal("Cache Group selected from testing data had null or undefined name")
-	}
-
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("name", *cg.Name)
-	resp, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Errorf("cannot get Cache Group by name '%s': %v - alerts: %+v", *cg.Name, err, resp.Alerts)
-	}
-	if len(resp.Response) != 1 {
-		t.Fatalf("Expected exactly one Cache Group with name '%s', but found: %d", *cg.Name, len(resp.Response))
-	}
-	cg = resp.Response[0]
-
-	const errFormat = "expected error from %s when unauthenticated"
-	if _, _, err = NoAuthTOSession.CreateCacheGroup(cg, client.RequestOptions{}); err == nil {
-		t.Error(fmt.Errorf(errFormat, "CreateCacheGroup"))
-	}
-	if _, _, err = NoAuthTOSession.GetCacheGroups(client.RequestOptions{}); err == nil {
-		t.Error(fmt.Errorf(errFormat, "GetCacheGroups"))
-	}
-	if cg.Name == nil {
-		t.Error("Traffic Ops returned a Cache Group with a null or undefined name")
-	} else {
-		opts.QueryParameters.Set("name", *cg.Name)
-		_, _, err = NoAuthTOSession.GetCacheGroups(opts)
-		if err == nil {
-			t.Error(fmt.Errorf(errFormat, "GetCacheGroups filtered by Name"))
-		}
-	}
-	opts.QueryParameters = url.Values{}
-	if cg.ID == nil {
-		t.Error("Traffic Ops returned a Cache Group with a null or undefined name")
-	} else {
-		opts.QueryParameters.Set("id", strconv.Itoa(*cg.ID))
-		_, _, err = NoAuthTOSession.GetCacheGroups(opts)
-		if err == nil {
-			t.Error(fmt.Errorf(errFormat, "GetCacheGroups filtered by ID"))
-		}
-		if _, _, err = NoAuthTOSession.UpdateCacheGroup(*cg.ID, cg, client.RequestOptions{}); err == nil {
-			t.Error(fmt.Errorf(errFormat, "UpdateCacheGroup"))
-		}
-		if _, _, err = NoAuthTOSession.DeleteCacheGroup(*cg.ID, client.RequestOptions{}); err == nil {
-			t.Error(fmt.Errorf(errFormat, "DeleteCacheGroupByID"))
-		}
-	}
-}
-
-func GetTestPaginationSupportCg(t *testing.T) {
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("orderby", "id")
-	resp, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("cannot get Cache Groups: %v - alerts: %+v", err, resp.Alerts)
-	}
-	cachegroup := resp.Response
-	if len(cachegroup) < 3 {
-		t.Fatalf("Need at least 3 Cache Groups in Traffic Ops to test pagination support, found: %d", len(cachegroup))
-	}
-
-	opts.QueryParameters.Set("orderby", "id")
-	opts.QueryParameters.Set("limit", "1")
-	cachegroupWithLimit, _, err := TOSession.GetCacheGroups(opts)
-
-	if !reflect.DeepEqual(cachegroup[:1], cachegroupWithLimit.Response) {
-		t.Error("expected GET Cachegroups with limit = 1 to return first result")
-	}
-
-	opts.QueryParameters.Set("orderby", "id")
-	opts.QueryParameters.Set("limit", "1")
-	opts.QueryParameters.Set("offset", "1")
-	cachegroupsWithOffset, _, err := TOSession.GetCacheGroups(opts)
-	if !reflect.DeepEqual(cachegroup[1:2], cachegroupsWithOffset.Response) {
-		t.Error("expected GET cachegroup with limit = 1, offset = 1 to return second result")
-	}
-
-	opts.QueryParameters.Set("orderby", "id")
-	opts.QueryParameters.Set("limit", "1")
-	opts.QueryParameters.Set("page", "2")
-	cachegroupWithPage, _, err := TOSession.GetCacheGroups(opts)
-	if !reflect.DeepEqual(cachegroup[1:2], cachegroupWithPage.Response) {
-		t.Error("expected GET cachegroup with limit = 1, page = 2 to return second result")
-	}
-
-	opts.QueryParameters = url.Values{}
-	opts.QueryParameters.Set("limit", "-2")
-	resp, _, err = TOSession.GetCacheGroups(opts)
-	if err == nil {
-		t.Error("expected GET cachegroup to return an error when limit is not bigger than -1")
-	} else if !alertsHaveError(resp.Alerts.Alerts, "must be bigger than -1") {
-		t.Errorf("expected GET cachegroup to return an error for limit is not bigger than -1, actual error: %v - alerts: %+v", err, resp.Alerts)
-	}
-
-	opts.QueryParameters.Set("limit", "1")
-	opts.QueryParameters.Set("offset", "0")
-	resp, _, err = TOSession.GetCacheGroups(opts)
-	if err == nil {
-		t.Error("expected GET cachegroup to return an error when offset is not a positive integer")
-	} else if !alertsHaveError(resp.Alerts.Alerts, "must be a positive integer") {
-		t.Errorf("expected GET cachegroup to return an error for offset is not a positive integer, actual error: %v - alerts: %+v", err, resp.Alerts)
-	}
-
-	opts.QueryParameters = url.Values{}
-	opts.QueryParameters.Set("limit", "1")
-	opts.QueryParameters.Set("page", "0")
-	resp, _, err = TOSession.GetCacheGroups(opts)
-	if err == nil {
-		t.Error("expected GET cachegroup to return an error when page is not a positive integer")
-	} else if !alertsHaveError(resp.Alerts.Alerts, "must be a positive integer") {
-		t.Errorf("expected GET cachegroup to return an error for page is not a positive integer, actual error: %v - alerts: %+v", err, resp.Alerts)
-	}
-}
-
-func GetTestCacheGroupsByInvalidId(t *testing.T) {
-	opts := client.NewRequestOptions()
-	// Retrieve the CacheGroup to check CacheGroup name got updated
-	opts.QueryParameters.Set("id", "10000")
-	resp, _, _ := TOSession.GetCacheGroups(opts)
-	if len(resp.Response) > 0 {
-		t.Errorf("Expected 0 response, but got many %v", resp)
-	}
-}
-
-func GetTestCacheGroupsByInvalidType(t *testing.T) {
-	opts := client.NewRequestOptions()
-	// Retrieve the CacheGroup to check CacheGroup name got updated
-	opts.QueryParameters.Set("type", "10000")
-	resp, _, _ := TOSession.GetCacheGroups(opts)
-	if len(resp.Response) > 0 {
-		t.Errorf("Expected 0 response, but got many %v", resp)
-	}
-}
-
-func GetTestCacheGroupsByType(t *testing.T) {
-	if len(testData.CacheGroups) < 1 {
-		t.Fatal("Need at least one Cache Group to test updating Cache Groups")
-	}
-	firstCG := testData.CacheGroups[0]
-
-	if firstCG.Name == nil {
-		t.Fatal("Found Cache Group with null or undefined name in testing data")
-	}
-
-	opts := client.NewRequestOptions()
-	opts.QueryParameters.Set("name", *firstCG.Name)
-
-	resp, _, err := TOSession.GetCacheGroups(opts)
-	if err != nil {
-		t.Fatalf("cannot get Cache Group '%s': %v - alerts: %+v", *firstCG.Name, err, resp.Alerts)
-	}
-	if len(resp.Response) != 1 {
-		t.Fatalf("Expected exactly one Cache Group to exist with name '%s', but got: %d", *firstCG.Name, len(resp.Response))
-	}
-
-	cg := resp.Response[0]
-	if cg.TypeID == nil {
-		t.Fatalf("Traffic Ops returned Cache Group '%s' with null or undefined typeId", *firstCG.Name)
-	}
-
-	opts = client.NewRequestOptions()
-	opts.QueryParameters.Set("type", strconv.Itoa(*cg.TypeID))
-	resp, _, _ = TOSession.GetCacheGroups(opts)
-	if len(resp.Response) < 1 {
-		t.Fatalf("Expected atleast one Cache Group by type ID '%d', but got: %d", *cg.TypeID, len(resp.Response))
-	}
-}
-
-func DeleteTestCacheGroupsByInvalidId(t *testing.T) {
-
-	alerts, reqInf, err := TOSession.DeleteCacheGroup(111111, client.RequestOptions{})
-	if err == nil {
-		t.Errorf("Expected no cachegroup with that id found - but got alerts: %+v", alerts)
-	}
-	if reqInf.StatusCode != http.StatusNotFound {
-		t.Errorf("Expected status code 404, got %v", reqInf.StatusCode)
+		assert.NoError(t, err, "Error attempting to fetch Cache Group '%s' after deletion: %v - alerts: %+v", *cg.Name, err, cgs.Alerts)
+		assert.Equal(t, 0, len(cgs.Response), "Expected Cache Group '%s' to be deleted", *cg.Name)
 	}
 }