shithub: hugo

Download patch

ref: 9e571827055dedb46b78c5db3d17d6913f14870b
parent: 6027ee11082d0b9d72de1d4d1980a702be294ad2
author: Bjørn Erik Pedersen <[email protected]>
date: Sat Aug 10 17:05:17 EDT 2019

tests: Convert from testify to quicktest

--- a/bufferpool/bufpool_test.go
+++ b/bufferpool/bufpool_test.go
@@ -14,14 +14,18 @@
 package bufferpool
 
 import (
-	"github.com/stretchr/testify/assert"
 	"testing"
+
+	qt "github.com/frankban/quicktest"
 )
 
 func TestBufferPool(t *testing.T) {
+	c := qt.New(t)
+
 	buff := GetBuffer()
 	buff.WriteString("do be do be do")
-	assert.Equal(t, "do be do be do", buff.String())
+	c.Assert(buff.String(), qt.Equals, "do be do be do")
 	PutBuffer(buff)
-	assert.Equal(t, 0, buff.Len())
+
+	c.Assert(buff.Len(), qt.Equals, 0)
 }
--- a/cache/filecache/filecache_config_test.go
+++ b/cache/filecache/filecache_config_test.go
@@ -24,14 +24,14 @@
 
 	"github.com/gohugoio/hugo/config"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestDecodeConfig(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	configStr := `
 resourceDir = "myresources"
@@ -55,20 +55,20 @@
 `
 
 	cfg, err := config.FromConfigString(configStr, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	fs := afero.NewMemMapFs()
 	decoded, err := DecodeConfig(fs, cfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal(5, len(decoded))
+	c.Assert(len(decoded), qt.Equals, 5)
 
 	c2 := decoded["getcsv"]
-	assert.Equal("11h0m0s", c2.MaxAge.String())
-	assert.Equal(filepath.FromSlash("/path/to/c2/filecache/getcsv"), c2.Dir)
+	c.Assert(c2.MaxAge.String(), qt.Equals, "11h0m0s")
+	c.Assert(c2.Dir, qt.Equals, filepath.FromSlash("/path/to/c2/filecache/getcsv"))
 
 	c3 := decoded["images"]
-	assert.Equal(time.Duration(-1), c3.MaxAge)
-	assert.Equal(filepath.FromSlash("/path/to/c3/filecache/images"), c3.Dir)
+	c.Assert(c3.MaxAge, qt.Equals, time.Duration(-1))
+	c.Assert(c3.Dir, qt.Equals, filepath.FromSlash("/path/to/c3/filecache/images"))
 
 }
 
@@ -75,7 +75,7 @@
 func TestDecodeConfigIgnoreCache(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	configStr := `
 resourceDir = "myresources"
@@ -100,21 +100,21 @@
 `
 
 	cfg, err := config.FromConfigString(configStr, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	fs := afero.NewMemMapFs()
 	decoded, err := DecodeConfig(fs, cfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal(5, len(decoded))
+	c.Assert(len(decoded), qt.Equals, 5)
 
 	for _, v := range decoded {
-		assert.Equal(time.Duration(0), v.MaxAge)
+		c.Assert(v.MaxAge, qt.Equals, time.Duration(0))
 	}
 
 }
 
 func TestDecodeConfigDefault(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	cfg := newTestConfig()
 
 	if runtime.GOOS == "windows" {
@@ -130,28 +130,28 @@
 
 	decoded, err := DecodeConfig(fs, cfg)
 
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal(5, len(decoded))
+	c.Assert(len(decoded), qt.Equals, 5)
 
 	imgConfig := decoded[cacheKeyImages]
 	jsonConfig := decoded[cacheKeyGetJSON]
 
 	if runtime.GOOS == "windows" {
-		assert.Equal(filepath.FromSlash("_gen/images"), imgConfig.Dir)
+		c.Assert(imgConfig.Dir, qt.Equals, filepath.FromSlash("_gen/images"))
 	} else {
-		assert.Equal("_gen/images", imgConfig.Dir)
-		assert.Equal("/cache/thecache/hugoproject/filecache/getjson", jsonConfig.Dir)
+		c.Assert(imgConfig.Dir, qt.Equals, "_gen/images")
+		c.Assert(jsonConfig.Dir, qt.Equals, "/cache/thecache/hugoproject/filecache/getjson")
 	}
 
-	assert.True(imgConfig.isResourceDir)
-	assert.False(jsonConfig.isResourceDir)
+	c.Assert(imgConfig.isResourceDir, qt.Equals, true)
+	c.Assert(jsonConfig.isResourceDir, qt.Equals, false)
 }
 
 func TestDecodeConfigInvalidDir(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	configStr := `
 resourceDir = "myresources"
@@ -173,11 +173,11 @@
 	}
 
 	cfg, err := config.FromConfigString(configStr, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	fs := afero.NewMemMapFs()
 
 	_, err = DecodeConfig(fs, cfg)
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 }
 
--- a/cache/filecache/filecache_pruner_test.go
+++ b/cache/filecache/filecache_pruner_test.go
@@ -20,13 +20,13 @@
 
 	"github.com/spf13/afero"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestPrune(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	configStr := `
 resourceDir = "myresources"
@@ -53,10 +53,10 @@
 `
 
 	for _, name := range []string{cacheKeyGetCSV, cacheKeyGetJSON, cacheKeyAssets, cacheKeyImages} {
-		msg := fmt.Sprintf("cache: %s", name)
+		msg := qt.Commentf("cache: %s", name)
 		p := newPathsSpec(t, afero.NewMemMapFs(), configStr)
 		caches, err := NewCaches(p)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		cache := caches[name]
 		for i := 0; i < 10; i++ {
 			id := fmt.Sprintf("i%d", i)
@@ -70,21 +70,21 @@
 		}
 
 		count, err := caches.Prune()
-		assert.NoError(err)
-		assert.Equal(5, count, msg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(count, qt.Equals, 5, msg)
 
 		for i := 0; i < 10; i++ {
 			id := fmt.Sprintf("i%d", i)
 			v := cache.getString(id)
 			if i < 5 {
-				assert.Equal("", v, id)
+				c.Assert(v, qt.Equals, "")
 			} else {
-				assert.Equal("abc", v, id)
+				c.Assert(v, qt.Equals, "abc")
 			}
 		}
 
 		caches, err = NewCaches(p)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		cache = caches[name]
 		// Touch one and then prune.
 		cache.GetOrCreateBytes("i5", func() ([]byte, error) {
@@ -92,8 +92,8 @@
 		})
 
 		count, err = caches.Prune()
-		assert.NoError(err)
-		assert.Equal(4, count)
+		c.Assert(err, qt.IsNil)
+		c.Assert(count, qt.Equals, 4)
 
 		// Now only the i5 should be left.
 		for i := 0; i < 10; i++ {
@@ -100,9 +100,9 @@
 			id := fmt.Sprintf("i%d", i)
 			v := cache.getString(id)
 			if i != 5 {
-				assert.Equal("", v, id)
+				c.Assert(v, qt.Equals, "")
 			} else {
-				assert.Equal("abc", v, id)
+				c.Assert(v, qt.Equals, "abc")
 			}
 		}
 
--- a/cache/filecache/filecache_test.go
+++ b/cache/filecache/filecache_test.go
@@ -19,7 +19,6 @@
 	"io/ioutil"
 	"os"
 	"path/filepath"
-	"regexp"
 	"strings"
 	"sync"
 	"testing"
@@ -35,19 +34,19 @@
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/afero"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestFileCache(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tempWorkingDir, err := ioutil.TempDir("", "hugo_filecache_test_work")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer os.Remove(tempWorkingDir)
 
 	tempCacheDir, err := ioutil.TempDir("", "hugo_filecache_test_cache")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer os.Remove(tempCacheDir)
 
 	osfs := afero.NewOsFs()
@@ -89,30 +88,30 @@
 		p := newPathsSpec(t, osfs, configStr)
 
 		caches, err := NewCaches(p)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		cache := caches.Get("GetJSON")
-		assert.NotNil(cache)
-		assert.Equal("10h0m0s", cache.maxAge.String())
+		c.Assert(cache, qt.Not(qt.IsNil))
+		c.Assert(cache.maxAge.String(), qt.Equals, "10h0m0s")
 
 		bfs, ok := cache.Fs.(*afero.BasePathFs)
-		assert.True(ok)
+		c.Assert(ok, qt.Equals, true)
 		filename, err := bfs.RealPath("key")
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		if test.cacheDir != "" {
-			assert.Equal(filepath.Join(test.cacheDir, "c/"+filecacheRootDirname+"/getjson/key"), filename)
+			c.Assert(filename, qt.Equals, filepath.Join(test.cacheDir, "c/"+filecacheRootDirname+"/getjson/key"))
 		} else {
 			// Temp dir.
-			assert.Regexp(regexp.MustCompile(".*hugo_cache.*"+filecacheRootDirname+".*key"), filename)
+			c.Assert(filename, qt.Matches, ".*hugo_cache.*"+filecacheRootDirname+".*key")
 		}
 
 		cache = caches.Get("Images")
-		assert.NotNil(cache)
-		assert.Equal(time.Duration(-1), cache.maxAge)
+		c.Assert(cache, qt.Not(qt.IsNil))
+		c.Assert(cache.maxAge, qt.Equals, time.Duration(-1))
 		bfs, ok = cache.Fs.(*afero.BasePathFs)
-		assert.True(ok)
+		c.Assert(ok, qt.Equals, true)
 		filename, _ = bfs.RealPath("key")
-		assert.Equal(filepath.FromSlash("_gen/images/key"), filename)
+		c.Assert(filename, qt.Equals, filepath.FromSlash("_gen/images/key"))
 
 		rf := func(s string) func() (io.ReadCloser, error) {
 			return func() (io.ReadCloser, error) {
@@ -130,55 +129,55 @@
 			return []byte("bcd"), nil
 		}
 
-		for _, c := range []*Cache{caches.ImageCache(), caches.AssetsCache(), caches.GetJSONCache(), caches.GetCSVCache()} {
+		for _, ca := range []*Cache{caches.ImageCache(), caches.AssetsCache(), caches.GetJSONCache(), caches.GetCSVCache()} {
 			for i := 0; i < 2; i++ {
-				info, r, err := c.GetOrCreate("a", rf("abc"))
-				assert.NoError(err)
-				assert.NotNil(r)
-				assert.Equal("a", info.Name)
+				info, r, err := ca.GetOrCreate("a", rf("abc"))
+				c.Assert(err, qt.IsNil)
+				c.Assert(r, qt.Not(qt.IsNil))
+				c.Assert(info.Name, qt.Equals, "a")
 				b, _ := ioutil.ReadAll(r)
 				r.Close()
-				assert.Equal("abc", string(b))
+				c.Assert(string(b), qt.Equals, "abc")
 
-				info, b, err = c.GetOrCreateBytes("b", bf)
-				assert.NoError(err)
-				assert.NotNil(r)
-				assert.Equal("b", info.Name)
-				assert.Equal("bcd", string(b))
+				info, b, err = ca.GetOrCreateBytes("b", bf)
+				c.Assert(err, qt.IsNil)
+				c.Assert(r, qt.Not(qt.IsNil))
+				c.Assert(info.Name, qt.Equals, "b")
+				c.Assert(string(b), qt.Equals, "bcd")
 
-				_, b, err = c.GetOrCreateBytes("a", bf)
-				assert.NoError(err)
-				assert.Equal("abc", string(b))
+				_, b, err = ca.GetOrCreateBytes("a", bf)
+				c.Assert(err, qt.IsNil)
+				c.Assert(string(b), qt.Equals, "abc")
 
-				_, r, err = c.GetOrCreate("a", rf("bcd"))
-				assert.NoError(err)
+				_, r, err = ca.GetOrCreate("a", rf("bcd"))
+				c.Assert(err, qt.IsNil)
 				b, _ = ioutil.ReadAll(r)
 				r.Close()
-				assert.Equal("abc", string(b))
+				c.Assert(string(b), qt.Equals, "abc")
 			}
 		}
 
-		assert.NotNil(caches.Get("getJSON"))
+		c.Assert(caches.Get("getJSON"), qt.Not(qt.IsNil))
 
 		info, w, err := caches.ImageCache().WriteCloser("mykey")
-		assert.NoError(err)
-		assert.Equal("mykey", info.Name)
+		c.Assert(err, qt.IsNil)
+		c.Assert(info.Name, qt.Equals, "mykey")
 		io.WriteString(w, "Hugo is great!")
 		w.Close()
-		assert.Equal("Hugo is great!", caches.ImageCache().getString("mykey"))
+		c.Assert(caches.ImageCache().getString("mykey"), qt.Equals, "Hugo is great!")
 
 		info, r, err := caches.ImageCache().Get("mykey")
-		assert.NoError(err)
-		assert.NotNil(r)
-		assert.Equal("mykey", info.Name)
+		c.Assert(err, qt.IsNil)
+		c.Assert(r, qt.Not(qt.IsNil))
+		c.Assert(info.Name, qt.Equals, "mykey")
 		b, _ := ioutil.ReadAll(r)
 		r.Close()
-		assert.Equal("Hugo is great!", string(b))
+		c.Assert(string(b), qt.Equals, "Hugo is great!")
 
 		info, b, err = caches.ImageCache().GetBytes("mykey")
-		assert.NoError(err)
-		assert.Equal("mykey", info.Name)
-		assert.Equal("Hugo is great!", string(b))
+		c.Assert(err, qt.IsNil)
+		c.Assert(info.Name, qt.Equals, "mykey")
+		c.Assert(string(b), qt.Equals, "Hugo is great!")
 
 	}
 
@@ -187,7 +186,7 @@
 func TestFileCacheConcurrent(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	configStr := `
 resourceDir = "myresources"
@@ -208,7 +207,7 @@
 	p := newPathsSpec(t, afero.NewMemMapFs(), configStr)
 
 	caches, err := NewCaches(p)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	const cacheName = "getjson"
 
@@ -225,16 +224,16 @@
 		go func(i int) {
 			defer wg.Done()
 			for j := 0; j < 20; j++ {
-				c := caches.Get(cacheName)
-				assert.NotNil(c)
+				ca := caches.Get(cacheName)
+				c.Assert(ca, qt.Not(qt.IsNil))
 				filename, data := filenameData(i)
-				_, r, err := c.GetOrCreate(filename, func() (io.ReadCloser, error) {
+				_, r, err := ca.GetOrCreate(filename, func() (io.ReadCloser, error) {
 					return hugio.ToReadCloser(strings.NewReader(data)), nil
 				})
-				assert.NoError(err)
+				c.Assert(err, qt.IsNil)
 				b, _ := ioutil.ReadAll(r)
 				r.Close()
-				assert.Equal(data, string(b))
+				c.Assert(string(b), qt.Equals, data)
 				// Trigger some expiration.
 				time.Sleep(50 * time.Millisecond)
 			}
@@ -245,9 +244,9 @@
 }
 
 func TestCleanID(t *testing.T) {
-	assert := require.New(t)
-	assert.Equal(filepath.FromSlash("a/b/c.txt"), cleanID(filepath.FromSlash("/a/b//c.txt")))
-	assert.Equal(filepath.FromSlash("a/b/c.txt"), cleanID(filepath.FromSlash("a/b//c.txt")))
+	c := qt.New(t)
+	c.Assert(cleanID(filepath.FromSlash("/a/b//c.txt")), qt.Equals, filepath.FromSlash("a/b/c.txt"))
+	c.Assert(cleanID(filepath.FromSlash("a/b//c.txt")), qt.Equals, filepath.FromSlash("a/b/c.txt"))
 }
 
 func initConfig(fs afero.Fs, cfg config.Provider) error {
@@ -288,12 +287,12 @@
 }
 
 func newPathsSpec(t *testing.T, fs afero.Fs, configStr string) *helpers.PathSpec {
-	assert := require.New(t)
+	c := qt.New(t)
 	cfg, err := config.FromConfigString(configStr, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	initConfig(fs, cfg)
 	p, err := helpers.NewPathSpec(hugofs.NewFrom(fs, cfg), cfg, nil)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	return p
 
 }
--- a/cache/namedmemcache/named_cache_test.go
+++ b/cache/namedmemcache/named_cache_test.go
@@ -18,12 +18,12 @@
 	"sync"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestNamedCache(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	cache := New()
 
@@ -35,24 +35,24 @@
 
 	for i := 0; i < 5; i++ {
 		v1, err := cache.GetOrCreate("a1", create)
-		assert.NoError(err)
-		assert.Equal(1, v1)
+		c.Assert(err, qt.IsNil)
+		c.Assert(v1, qt.Equals, 1)
 		v2, err := cache.GetOrCreate("a2", create)
-		assert.NoError(err)
-		assert.Equal(2, v2)
+		c.Assert(err, qt.IsNil)
+		c.Assert(v2, qt.Equals, 2)
 	}
 
 	cache.Clear()
 
 	v3, err := cache.GetOrCreate("a2", create)
-	assert.NoError(err)
-	assert.Equal(3, v3)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v3, qt.Equals, 3)
 }
 
 func TestNamedCacheConcurrent(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	var wg sync.WaitGroup
 
@@ -71,8 +71,8 @@
 			for j := 0; j < 100; j++ {
 				id := fmt.Sprintf("id%d", j)
 				v, err := cache.GetOrCreate(id, create(j))
-				assert.NoError(err)
-				assert.Equal(j, v)
+				c.Assert(err, qt.IsNil)
+				c.Assert(v, qt.Equals, j)
 			}
 		}()
 	}
--- a/cache/partitioned_lazy_cache_test.go
+++ b/cache/partitioned_lazy_cache_test.go
@@ -18,13 +18,13 @@
 	"sync"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestNewPartitionedLazyCache(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	p1 := Partition{
 		Key: "p1",
@@ -51,28 +51,28 @@
 	cache := NewPartitionedLazyCache(p1, p2)
 
 	v, err := cache.Get("p1", "p1_1")
-	assert.NoError(err)
-	assert.Equal("p1v1", v)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v, qt.Equals, "p1v1")
 
 	v, err = cache.Get("p1", "p2_1")
-	assert.NoError(err)
-	assert.Nil(v)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v, qt.IsNil)
 
 	v, err = cache.Get("p1", "p1_nil")
-	assert.NoError(err)
-	assert.Nil(v)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v, qt.IsNil)
 
 	v, err = cache.Get("p2", "p2_3")
-	assert.NoError(err)
-	assert.Equal("p2v3", v)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v, qt.Equals, "p2v3")
 
 	v, err = cache.Get("doesnotexist", "p1_1")
-	assert.NoError(err)
-	assert.Nil(v)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v, qt.IsNil)
 
 	v, err = cache.Get("p1", "doesnotexist")
-	assert.NoError(err)
-	assert.Nil(v)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v, qt.IsNil)
 
 	errorP := Partition{
 		Key: "p3",
@@ -84,11 +84,11 @@
 	cache = NewPartitionedLazyCache(errorP)
 
 	v, err = cache.Get("p1", "doesnotexist")
-	assert.NoError(err)
-	assert.Nil(v)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v, qt.IsNil)
 
 	_, err = cache.Get("p3", "doesnotexist")
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 }
 
@@ -95,7 +95,7 @@
 func TestConcurrentPartitionedLazyCache(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	var wg sync.WaitGroup
 
@@ -129,8 +129,8 @@
 			defer wg.Done()
 			for j := 0; j < 10; j++ {
 				v, err := cache.Get("p1", "p1_1")
-				assert.NoError(err)
-				assert.Equal("p1v1", v)
+				c.Assert(err, qt.IsNil)
+				c.Assert(v, qt.Equals, "p1v1")
 			}
 		}()
 	}
--- a/codegen/methods_test.go
+++ b/codegen/methods_test.go
@@ -20,8 +20,8 @@
 	"reflect"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/herrors"
-	"github.com/stretchr/testify/require"
 )
 
 func TestMethods(t *testing.T) {
@@ -33,47 +33,47 @@
 	)
 
 	dir, _ := os.Getwd()
-	c := NewInspector(dir)
+	insp := NewInspector(dir)
 
 	t.Run("MethodsFromTypes", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
-		methods := c.MethodsFromTypes([]reflect.Type{zeroI}, nil)
+		methods := insp.MethodsFromTypes([]reflect.Type{zeroI}, nil)
 
 		methodsStr := fmt.Sprint(methods)
 
-		assert.Contains(methodsStr, "Method1(arg0 herrors.ErrorContext)")
-		assert.Contains(methodsStr, "Method7() interface {}")
-		assert.Contains(methodsStr, "Method0() string\n Method4() string")
-		assert.Contains(methodsStr, "MethodEmbed3(arg0 string) string\n MethodEmbed1() string")
+		c.Assert(methodsStr, qt.Contains, "Method1(arg0 herrors.ErrorContext)")
+		c.Assert(methodsStr, qt.Contains, "Method7() interface {}")
+		c.Assert(methodsStr, qt.Contains, "Method0() string\n Method4() string")
+		c.Assert(methodsStr, qt.Contains, "MethodEmbed3(arg0 string) string\n MethodEmbed1() string")
 
-		assert.Contains(methods.Imports(), "github.com/gohugoio/hugo/common/herrors")
+		c.Assert(methods.Imports(), qt.Contains, "github.com/gohugoio/hugo/common/herrors")
 	})
 
 	t.Run("EmbedOnly", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
-		methods := c.MethodsFromTypes([]reflect.Type{zeroIEOnly}, nil)
+		methods := insp.MethodsFromTypes([]reflect.Type{zeroIEOnly}, nil)
 
 		methodsStr := fmt.Sprint(methods)
 
-		assert.Contains(methodsStr, "MethodEmbed3(arg0 string) string")
+		c.Assert(methodsStr, qt.Contains, "MethodEmbed3(arg0 string) string")
 
 	})
 
 	t.Run("ToMarshalJSON", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
-		m, pkg := c.MethodsFromTypes(
+		m, pkg := insp.MethodsFromTypes(
 			[]reflect.Type{zeroI},
 			[]reflect.Type{zeroIE}).ToMarshalJSON("*page", "page")
 
-		assert.Contains(m, "method6 := p.Method6()")
-		assert.Contains(m, "Method0: method0,")
-		assert.Contains(m, "return json.Marshal(&s)")
+		c.Assert(m, qt.Contains, "method6 := p.Method6()")
+		c.Assert(m, qt.Contains, "Method0: method0,")
+		c.Assert(m, qt.Contains, "return json.Marshal(&s)")
 
-		assert.Contains(pkg, "github.com/gohugoio/hugo/common/herrors")
-		assert.Contains(pkg, "encoding/json")
+		c.Assert(pkg, qt.Contains, "github.com/gohugoio/hugo/common/herrors")
+		c.Assert(pkg, qt.Contains, "encoding/json")
 
 		fmt.Println(pkg)
 
--- a/commands/commands_test.go
+++ b/commands/commands_test.go
@@ -25,15 +25,15 @@
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestExecute(t *testing.T) {
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	dir, err := createSimpleTestSite(t, testSiteConfig{})
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	defer func() {
 		os.RemoveAll(dir)
@@ -40,14 +40,14 @@
 	}()
 
 	resp := Execute([]string{"-s=" + dir})
-	assert.NoError(resp.Err)
+	c.Assert(resp.Err, qt.IsNil)
 	result := resp.Result
-	assert.True(len(result.Sites) == 1)
-	assert.True(len(result.Sites[0].RegularPages()) == 1)
+	c.Assert(len(result.Sites) == 1, qt.Equals, true)
+	c.Assert(len(result.Sites[0].RegularPages()) == 1, qt.Equals, true)
 }
 
 func TestCommandsPersistentFlags(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	noOpRunE := func(cmd *cobra.Command, args []string) error {
 		return nil
@@ -83,10 +83,10 @@
 		for _, command := range commands {
 			if b, ok := command.(commandsBuilderGetter); ok {
 				v := b.getCommandsBuilder().hugoBuilderCommon
-				assert.Equal("myconfig.toml", v.cfgFile)
-				assert.Equal("myconfigdir", v.cfgDir)
-				assert.Equal("mysource", v.source)
-				assert.Equal("https://example.com/b/", v.baseURL)
+				c.Assert(v.cfgFile, qt.Equals, "myconfig.toml")
+				c.Assert(v.cfgDir, qt.Equals, "myconfigdir")
+				c.Assert(v.source, qt.Equals, "mysource")
+				c.Assert(v.baseURL, qt.Equals, "https://example.com/b/")
 			}
 
 			if srvCmd, ok := command.(*serverCmd); ok {
@@ -94,32 +94,32 @@
 			}
 		}
 
-		assert.NotNil(sc)
-		assert.True(sc.navigateToChanged)
-		assert.True(sc.disableLiveReload)
-		assert.True(sc.noHTTPCache)
-		assert.True(sc.renderToDisk)
-		assert.Equal(1366, sc.serverPort)
-		assert.Equal("testing", sc.environment)
+		c.Assert(sc, qt.Not(qt.IsNil))
+		c.Assert(sc.navigateToChanged, qt.Equals, true)
+		c.Assert(sc.disableLiveReload, qt.Equals, true)
+		c.Assert(sc.noHTTPCache, qt.Equals, true)
+		c.Assert(sc.renderToDisk, qt.Equals, true)
+		c.Assert(sc.serverPort, qt.Equals, 1366)
+		c.Assert(sc.environment, qt.Equals, "testing")
 
 		cfg := viper.New()
 		sc.flagsToConfig(cfg)
-		assert.Equal("/tmp/mydestination", cfg.GetString("publishDir"))
-		assert.Equal("mycontent", cfg.GetString("contentDir"))
-		assert.Equal("mylayouts", cfg.GetString("layoutDir"))
-		assert.Equal([]string{"mytheme"}, cfg.GetStringSlice("theme"))
-		assert.Equal("mythemes", cfg.GetString("themesDir"))
-		assert.Equal("https://example.com/b/", cfg.GetString("baseURL"))
+		c.Assert(cfg.GetString("publishDir"), qt.Equals, "/tmp/mydestination")
+		c.Assert(cfg.GetString("contentDir"), qt.Equals, "mycontent")
+		c.Assert(cfg.GetString("layoutDir"), qt.Equals, "mylayouts")
+		c.Assert(cfg.GetStringSlice("theme"), qt.DeepEquals, []string{"mytheme"})
+		c.Assert(cfg.GetString("themesDir"), qt.Equals, "mythemes")
+		c.Assert(cfg.GetString("baseURL"), qt.Equals, "https://example.com/b/")
 
-		assert.Equal([]string{"page", "home"}, cfg.Get("disableKinds"))
+		c.Assert(cfg.Get("disableKinds"), qt.DeepEquals, []string{"page", "home"})
 
-		assert.True(cfg.GetBool("gc"))
+		c.Assert(cfg.GetBool("gc"), qt.Equals, true)
 
 		// The flag is named path-warnings
-		assert.True(cfg.GetBool("logPathWarnings"))
+		c.Assert(cfg.GetBool("logPathWarnings"), qt.Equals, true)
 
 		// The flag is named i18n-warnings
-		assert.True(cfg.GetBool("logI18nWarnings"))
+		c.Assert(cfg.GetBool("logI18nWarnings"), qt.Equals, true)
 
 	}}}
 
@@ -136,7 +136,7 @@
 		}
 		rootCmd := root.getCommand()
 		rootCmd.SetArgs(test.args)
-		assert.NoError(rootCmd.Execute())
+		c.Assert(rootCmd.Execute(), qt.IsNil)
 		test.check(b.commands)
 	}
 
@@ -144,13 +144,13 @@
 
 func TestCommandsExecute(t *testing.T) {
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	dir, err := createSimpleTestSite(t, testSiteConfig{})
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	dirOut, err := ioutil.TempDir("", "hugo-cli-out")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	defer func() {
 		os.RemoveAll(dir)
@@ -200,10 +200,10 @@
 
 		_, err := hugoCmd.ExecuteC()
 		if test.expectErrToContain != "" {
-			assert.Error(err, fmt.Sprintf("%v", test.commands))
-			assert.Contains(err.Error(), test.expectErrToContain)
+			c.Assert(err, qt.Not(qt.IsNil))
+			c.Assert(err.Error(), qt.Contains, test.expectErrToContain)
 		} else {
-			assert.NoError(err, fmt.Sprintf("%v", test.commands))
+			c.Assert(err, qt.IsNil)
 		}
 
 		// Assert that we have not left any development debug artifacts in
@@ -210,7 +210,7 @@
 		// the code.
 		if b.c != nil {
 			_, ok := b.c.destinationFs.(types.DevMarker)
-			assert.False(ok)
+			c.Assert(ok, qt.Equals, false)
 		}
 
 	}
--- a/commands/hugo_test.go
+++ b/commands/hugo_test.go
@@ -17,12 +17,12 @@
 	"os"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 // Issue #5662
 func TestHugoWithContentDirOverride(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	hugoCmd := newCommandsBuilder().addAll().build()
 	cmd := hugoCmd.getCommand()
@@ -38,7 +38,7 @@
 
 `
 	dir, err := createSimpleTestSite(t, testSiteConfig{configTOML: cfgStr, contentDir: contentDir})
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	defer func() {
 		os.RemoveAll(dir)
@@ -47,6 +47,6 @@
 	cmd.SetArgs([]string{"-s=" + dir, "-c=" + contentDir})
 
 	_, err = cmd.ExecuteC()
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 }
--- a/commands/import_jekyll_test.go
+++ b/commands/import_jekyll_test.go
@@ -15,12 +15,14 @@
 
 import (
 	"encoding/json"
-	"github.com/stretchr/testify/assert"
 	"testing"
 	"time"
+
+	qt "github.com/frankban/quicktest"
 )
 
 func TestParseJekyllFilename(t *testing.T) {
+	c := qt.New(t)
 	filenameArray := []string{
 		"2015-01-02-test.md",
 		"2012-03-15-中文.markup",
@@ -36,13 +38,14 @@
 
 	for i, filename := range filenameArray {
 		postDate, postName, err := parseJekyllFilename(filename)
-		assert.Equal(t, err, nil)
-		assert.Equal(t, expectResult[i].postDate.Format("2006-01-02"), postDate.Format("2006-01-02"))
-		assert.Equal(t, expectResult[i].postName, postName)
+		c.Assert(err, qt.IsNil)
+		c.Assert(expectResult[i].postDate.Format("2006-01-02"), qt.Equals, postDate.Format("2006-01-02"))
+		c.Assert(expectResult[i].postName, qt.Equals, postName)
 	}
 }
 
 func TestConvertJekyllMetadata(t *testing.T) {
+	c := qt.New(t)
 	testDataList := []struct {
 		metadata interface{}
 		postName string
@@ -73,14 +76,15 @@
 
 	for _, data := range testDataList {
 		result, err := convertJekyllMetaData(data.metadata, data.postName, data.postDate, data.draft)
-		assert.Equal(t, nil, err)
+		c.Assert(err, qt.IsNil)
 		jsonResult, err := json.Marshal(result)
-		assert.Equal(t, nil, err)
-		assert.Equal(t, data.expect, string(jsonResult))
+		c.Assert(err, qt.IsNil)
+		c.Assert(string(jsonResult), qt.Equals, data.expect)
 	}
 }
 
 func TestConvertJekyllContent(t *testing.T) {
+	c := qt.New(t)
 	testDataList := []struct {
 		metadata interface{}
 		content  string
@@ -124,6 +128,6 @@
 
 	for _, data := range testDataList {
 		result := convertJekyllContent(data.metadata, data.content)
-		assert.Equal(t, data.expect, result)
+		c.Assert(data.expect, qt.Equals, result)
 	}
 }
--- a/commands/list_test.go
+++ b/commands/list_test.go
@@ -9,8 +9,8 @@
 	"strings"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/cobra"
-	"github.com/stretchr/testify/require"
 )
 
 func captureStdout(f func() (*cobra.Command, error)) (string, error) {
@@ -33,10 +33,10 @@
 }
 
 func TestListAll(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	dir, err := createSimpleTestSite(t, testSiteConfig{})
 
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	hugoCmd := newCommandsBuilder().addAll().build()
 	cmd := hugoCmd.getCommand()
@@ -48,24 +48,25 @@
 	cmd.SetArgs([]string{"-s=" + dir, "list", "all"})
 
 	out, err := captureStdout(cmd.ExecuteC)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	r := csv.NewReader(strings.NewReader(out))
 
 	header, err := r.Read()
-	assert.NoError(err)
 
-	assert.Equal([]string{
+	c.Assert(err, qt.IsNil)
+	c.Assert(header, qt.DeepEquals, []string{
 		"path", "slug", "title",
 		"date", "expiryDate", "publishDate",
 		"draft", "permalink",
-	}, header)
+	})
 
 	record, err := r.Read()
-	assert.NoError(err)
-	assert.Equal([]string{
+
+	c.Assert(err, qt.IsNil)
+	c.Assert(record, qt.DeepEquals, []string{
 		filepath.Join("content", "p1.md"), "", "P1",
 		"0001-01-01T00:00:00Z", "0001-01-01T00:00:00Z", "0001-01-01T00:00:00Z",
 		"false", "https://example.org/p1/",
-	}, record)
+	})
 }
--- a/commands/new_content_test.go
+++ b/commands/new_content_test.go
@@ -19,19 +19,20 @@
 
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+
+	qt "github.com/frankban/quicktest"
 )
 
 // Issue #1133
 func TestNewContentPathSectionWithForwardSlashes(t *testing.T) {
+	c := qt.New(t)
 	p, s := newContentPathSection(nil, "/post/new.md")
-	assert.Equal(t, filepath.FromSlash("/post/new.md"), p)
-	assert.Equal(t, "post", s)
+	c.Assert(p, qt.Equals, filepath.FromSlash("/post/new.md"))
+	c.Assert(s, qt.Equals, "post")
 }
 
 func checkNewSiteInited(fs *hugofs.Fs, basepath string, t *testing.T) {
-
+	c := qt.New(t)
 	paths := []string{
 		filepath.Join(basepath, "layouts"),
 		filepath.Join(basepath, "content"),
@@ -43,56 +44,60 @@
 
 	for _, path := range paths {
 		_, err := fs.Source.Stat(path)
-		require.NoError(t, err)
+		c.Assert(err, qt.IsNil)
 	}
 }
 
 func TestDoNewSite(t *testing.T) {
+	c := qt.New(t)
 	n := newNewSiteCmd()
 	basepath := filepath.Join("base", "blog")
 	_, fs := newTestCfg()
 
-	require.NoError(t, n.doNewSite(fs, basepath, false))
+	c.Assert(n.doNewSite(fs, basepath, false), qt.IsNil)
 
 	checkNewSiteInited(fs, basepath, t)
 }
 
 func TestDoNewSite_noerror_base_exists_but_empty(t *testing.T) {
+	c := qt.New(t)
 	basepath := filepath.Join("base", "blog")
 	_, fs := newTestCfg()
 	n := newNewSiteCmd()
 
-	require.NoError(t, fs.Source.MkdirAll(basepath, 0777))
+	c.Assert(fs.Source.MkdirAll(basepath, 0777), qt.IsNil)
 
-	require.NoError(t, n.doNewSite(fs, basepath, false))
+	c.Assert(n.doNewSite(fs, basepath, false), qt.IsNil)
 }
 
 func TestDoNewSite_error_base_exists(t *testing.T) {
+	c := qt.New(t)
 	basepath := filepath.Join("base", "blog")
 	_, fs := newTestCfg()
 	n := newNewSiteCmd()
 
-	require.NoError(t, fs.Source.MkdirAll(basepath, 0777))
+	c.Assert(fs.Source.MkdirAll(basepath, 0777), qt.IsNil)
 	_, err := fs.Source.Create(filepath.Join(basepath, "foo"))
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 	// Since the directory already exists and isn't empty, expect an error
-	require.Error(t, n.doNewSite(fs, basepath, false))
+	c.Assert(n.doNewSite(fs, basepath, false), qt.Not(qt.IsNil))
 
 }
 
 func TestDoNewSite_force_empty_dir(t *testing.T) {
+	c := qt.New(t)
 	basepath := filepath.Join("base", "blog")
 	_, fs := newTestCfg()
 	n := newNewSiteCmd()
 
-	require.NoError(t, fs.Source.MkdirAll(basepath, 0777))
+	c.Assert(fs.Source.MkdirAll(basepath, 0777), qt.IsNil)
+	c.Assert(n.doNewSite(fs, basepath, true), qt.IsNil)
 
-	require.NoError(t, n.doNewSite(fs, basepath, true))
-
 	checkNewSiteInited(fs, basepath, t)
 }
 
 func TestDoNewSite_error_force_dir_inside_exists(t *testing.T) {
+	c := qt.New(t)
 	basepath := filepath.Join("base", "blog")
 	_, fs := newTestCfg()
 	n := newNewSiteCmd()
@@ -99,21 +104,22 @@
 
 	contentPath := filepath.Join(basepath, "content")
 
-	require.NoError(t, fs.Source.MkdirAll(contentPath, 0777))
-	require.Error(t, n.doNewSite(fs, basepath, true))
+	c.Assert(fs.Source.MkdirAll(contentPath, 0777), qt.IsNil)
+	c.Assert(n.doNewSite(fs, basepath, true), qt.Not(qt.IsNil))
 }
 
 func TestDoNewSite_error_force_config_inside_exists(t *testing.T) {
+	c := qt.New(t)
 	basepath := filepath.Join("base", "blog")
 	_, fs := newTestCfg()
 	n := newNewSiteCmd()
 
 	configPath := filepath.Join(basepath, "config.toml")
-	require.NoError(t, fs.Source.MkdirAll(basepath, 0777))
+	c.Assert(fs.Source.MkdirAll(basepath, 0777), qt.IsNil)
 	_, err := fs.Source.Create(configPath)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
-	require.Error(t, n.doNewSite(fs, basepath, true))
+	c.Assert(n.doNewSite(fs, basepath, true), qt.Not(qt.IsNil))
 }
 
 func newTestCfg() (*viper.Viper, *hugofs.Fs) {
--- a/commands/server_test.go
+++ b/commands/server_test.go
@@ -24,8 +24,8 @@
 
 	"github.com/gohugoio/hugo/helpers"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestServer(t *testing.T) {
@@ -33,9 +33,9 @@
 		// TODO(bep) not sure why server tests have started to fail on the Windows CI server.
 		t.Skip("Skip server test on appveyor")
 	}
-	assert := require.New(t)
+	c := qt.New(t)
 	dir, err := createSimpleTestSite(t, testSiteConfig{})
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	// Let us hope that this port is available on all systems ...
 	port := 1331
@@ -54,7 +54,7 @@
 
 	go func() {
 		_, err = cmd.ExecuteC()
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 	}()
 
 	// There is no way to know exactly when the server is ready for connections.
@@ -63,12 +63,12 @@
 	time.Sleep(2 * time.Second)
 
 	resp, err := http.Get("http://localhost:1331/")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer resp.Body.Close()
 	homeContent := helpers.ReaderToString(resp.Body)
 
-	assert.Contains(homeContent, "List: Hugo Commands")
-	assert.Contains(homeContent, "Environment: development")
+	c.Assert(homeContent, qt.Contains, "List: Hugo Commands")
+	c.Assert(homeContent, qt.Contains, "Environment: development")
 
 	// Stop the server.
 	stop <- true
@@ -118,7 +118,7 @@
 }
 
 func TestRemoveErrorPrefixFromLog(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	content := `ERROR 2018/10/07 13:11:12 Error while rendering "home": template: _default/baseof.html:4:3: executing "main" at <partial "logo" .>: error calling partial: template: partials/logo.html:5:84: executing "partials/logo.html" at <$resized.AHeight>: can't evaluate field AHeight in type *resource.Image
 ERROR 2018/10/07 13:11:12 Rebuild failed: logged 1 error(s)
 `
@@ -125,7 +125,7 @@
 
 	withoutError := removeErrorPrefixFromLog(content)
 
-	assert.False(strings.Contains(withoutError, "ERROR"), withoutError)
+	c.Assert(strings.Contains(withoutError, "ERROR"), qt.Equals, false)
 
 }
 
--- a/common/collections/append_test.go
+++ b/common/collections/append_test.go
@@ -14,17 +14,16 @@
 package collections
 
 import (
-	"fmt"
-	"reflect"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestAppend(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		start    interface{}
 		addend   []interface{}
 		expected interface{}
@@ -59,20 +58,16 @@
 			false},
 	} {
 
-		errMsg := fmt.Sprintf("[%d]", i)
-
 		result, err := Append(test.start, test.addend...)
 
 		if b, ok := test.expected.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-
-		if !reflect.DeepEqual(test.expected, result) {
-			t.Fatalf("%s got\n%T: %v\nexpected\n%T: %v", errMsg, result, result, test.expected, test.expected)
-		}
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.DeepEquals, test.expected)
 	}
 
 }
--- a/common/collections/slice_test.go
+++ b/common/collections/slice_test.go
@@ -15,10 +15,9 @@
 
 import (
 	"errors"
-	"fmt"
 	"testing"
 
-	"github.com/alecthomas/assert"
+	qt "github.com/frankban/quicktest"
 )
 
 var _ Slicer = (*tstSlicer)(nil)
@@ -34,15 +33,15 @@
 type testSlicerInterfaces []testSlicerInterface
 
 type tstSlicerIn1 struct {
-	name string
+	TheName string
 }
 
 type tstSlicerIn2 struct {
-	name string
+	TheName string
 }
 
 type tstSlicer struct {
-	name string
+	TheName string
 }
 
 func (p *tstSlicerIn1) Slice(in interface{}) (interface{}, error) {
@@ -75,11 +74,11 @@
 }
 
 func (p *tstSlicerIn1) Name() string {
-	return p.name
+	return p.TheName
 }
 
 func (p *tstSlicerIn2) Name() string {
-	return p.name
+	return p.TheName
 }
 
 func (p *tstSlicer) Slice(in interface{}) (interface{}, error) {
@@ -100,6 +99,7 @@
 
 func TestSlice(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	for i, test := range []struct {
 		args     []interface{}
@@ -114,12 +114,11 @@
 		{[]interface{}{&tstSlicerIn1{"a"}, &tstSlicerIn2{"b"}}, testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn2{"b"}}},
 		{[]interface{}{&tstSlicerIn1{"a"}, &tstSlicer{"b"}}, []interface{}{&tstSlicerIn1{"a"}, &tstSlicer{"b"}}},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.args)
+		errMsg := qt.Commentf("[%d] %v", i, test.args)
 
 		result := Slice(test.args...)
 
-		assert.Equal(t, test.expected, result, errMsg)
+		c.Assert(test.expected, qt.DeepEquals, result, errMsg)
 	}
 
-	assert.Len(t, Slice(), 0)
 }
--- a/common/herrors/error_locator_test.go
+++ b/common/herrors/error_locator_test.go
@@ -18,11 +18,11 @@
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestErrorLocator(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	lineMatcher := func(m LineMatcher) bool {
 		return strings.Contains(m.Line, "THEONE")
@@ -39,45 +39,45 @@
 `
 
 	location := locateErrorInString(lines, lineMatcher)
-	assert.Equal([]string{"LINE 3", "LINE 4", "This is THEONE", "LINE 6", "LINE 7"}, location.Lines)
+	c.Assert(location.Lines, qt.DeepEquals, []string{"LINE 3", "LINE 4", "This is THEONE", "LINE 6", "LINE 7"})
 
 	pos := location.Position()
-	assert.Equal(5, pos.LineNumber)
-	assert.Equal(2, location.LinesPos)
+	c.Assert(pos.LineNumber, qt.Equals, 5)
+	c.Assert(location.LinesPos, qt.Equals, 2)
 
-	assert.Equal([]string{"This is THEONE"}, locateErrorInString(`This is THEONE`, lineMatcher).Lines)
+	c.Assert(locateErrorInString(`This is THEONE`, lineMatcher).Lines, qt.DeepEquals, []string{"This is THEONE"})
 
 	location = locateErrorInString(`L1
 This is THEONE
 L2
 `, lineMatcher)
-	assert.Equal(2, location.Position().LineNumber)
-	assert.Equal(1, location.LinesPos)
-	assert.Equal([]string{"L1", "This is THEONE", "L2", ""}, location.Lines)
+	c.Assert(location.Position().LineNumber, qt.Equals, 2)
+	c.Assert(location.LinesPos, qt.Equals, 1)
+	c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "This is THEONE", "L2", ""})
 
 	location = locateErrorInString(`This is THEONE
 L2
 `, lineMatcher)
-	assert.Equal(0, location.LinesPos)
-	assert.Equal([]string{"This is THEONE", "L2", ""}, location.Lines)
+	c.Assert(location.LinesPos, qt.Equals, 0)
+	c.Assert(location.Lines, qt.DeepEquals, []string{"This is THEONE", "L2", ""})
 
 	location = locateErrorInString(`L1
 This THEONE
 `, lineMatcher)
-	assert.Equal([]string{"L1", "This THEONE", ""}, location.Lines)
-	assert.Equal(1, location.LinesPos)
+	c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "This THEONE", ""})
+	c.Assert(location.LinesPos, qt.Equals, 1)
 
 	location = locateErrorInString(`L1
 L2
 This THEONE
 `, lineMatcher)
-	assert.Equal([]string{"L1", "L2", "This THEONE", ""}, location.Lines)
-	assert.Equal(2, location.LinesPos)
+	c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "L2", "This THEONE", ""})
+	c.Assert(location.LinesPos, qt.Equals, 2)
 
 	location = locateErrorInString("NO MATCH", lineMatcher)
-	assert.Equal(-1, location.Position().LineNumber)
-	assert.Equal(-1, location.LinesPos)
-	assert.Equal(0, len(location.Lines))
+	c.Assert(location.Position().LineNumber, qt.Equals, -1)
+	c.Assert(location.LinesPos, qt.Equals, -1)
+	c.Assert(len(location.Lines), qt.Equals, 0)
 
 	lineMatcher = func(m LineMatcher) bool {
 		return m.LineNumber == 6
@@ -94,9 +94,9 @@
 I
 J`, lineMatcher)
 
-	assert.Equal([]string{"D", "E", "F", "G", "H"}, location.Lines)
-	assert.Equal(6, location.Position().LineNumber)
-	assert.Equal(2, location.LinesPos)
+	c.Assert(location.Lines, qt.DeepEquals, []string{"D", "E", "F", "G", "H"})
+	c.Assert(location.Position().LineNumber, qt.Equals, 6)
+	c.Assert(location.LinesPos, qt.Equals, 2)
 
 	// Test match EOF
 	lineMatcher = func(m LineMatcher) bool {
@@ -108,9 +108,9 @@
 C
 `, lineMatcher)
 
-	assert.Equal([]string{"B", "C", ""}, location.Lines)
-	assert.Equal(4, location.Position().LineNumber)
-	assert.Equal(2, location.LinesPos)
+	c.Assert(location.Lines, qt.DeepEquals, []string{"B", "C", ""})
+	c.Assert(location.Position().LineNumber, qt.Equals, 4)
+	c.Assert(location.LinesPos, qt.Equals, 2)
 
 	offsetMatcher := func(m LineMatcher) bool {
 		return m.Offset == 1
@@ -122,8 +122,8 @@
 D
 E`, offsetMatcher)
 
-	assert.Equal([]string{"A", "B", "C", "D"}, location.Lines)
-	assert.Equal(2, location.Position().LineNumber)
-	assert.Equal(1, location.LinesPos)
+	c.Assert(location.Lines, qt.DeepEquals, []string{"A", "B", "C", "D"})
+	c.Assert(location.Position().LineNumber, qt.Equals, 2)
+	c.Assert(location.LinesPos, qt.Equals, 1)
 
 }
--- a/common/herrors/file_error_test.go
+++ b/common/herrors/file_error_test.go
@@ -14,18 +14,17 @@
 package herrors
 
 import (
-	"fmt"
 	"testing"
 
 	"github.com/pkg/errors"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestToLineNumberError(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	for i, test := range []struct {
 		in           error
@@ -43,15 +42,15 @@
 
 		got := ToFileError("template", test.in)
 
-		errMsg := fmt.Sprintf("[%d][%T]", i, got)
+		errMsg := qt.Commentf("[%d][%T]", i, got)
 		le, ok := got.(FileError)
-		assert.True(ok)
+		c.Assert(ok, qt.Equals, true)
 
-		assert.True(ok, errMsg)
+		c.Assert(ok, qt.Equals, true, errMsg)
 		pos := le.Position()
-		assert.Equal(test.lineNumber, pos.LineNumber, errMsg)
-		assert.Equal(test.columnNumber, pos.ColumnNumber, errMsg)
-		assert.Error(errors.Cause(got))
+		c.Assert(pos.LineNumber, qt.Equals, test.lineNumber, errMsg)
+		c.Assert(pos.ColumnNumber, qt.Equals, test.columnNumber, errMsg)
+		c.Assert(errors.Cause(got), qt.Not(qt.IsNil))
 	}
 
 }
--- a/common/hreflect/helpers_test.go
+++ b/common/hreflect/helpers_test.go
@@ -18,16 +18,16 @@
 	"testing"
 	"time"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestIsTruthful(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
-	assert.True(IsTruthful(true))
-	assert.False(IsTruthful(false))
-	assert.True(IsTruthful(time.Now()))
-	assert.False(IsTruthful(time.Time{}))
+	c.Assert(IsTruthful(true), qt.Equals, true)
+	c.Assert(IsTruthful(false), qt.Equals, false)
+	c.Assert(IsTruthful(time.Now()), qt.Equals, true)
+	c.Assert(IsTruthful(time.Time{}), qt.Equals, false)
 }
 
 func BenchmarkIsTruthFul(b *testing.B) {
--- a/common/hugo/hugo_test.go
+++ b/common/hugo/hugo_test.go
@@ -17,19 +17,19 @@
 	"fmt"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestHugoInfo(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	hugoInfo := NewInfo("")
 
-	assert.Equal(CurrentVersion.Version(), hugoInfo.Version())
-	assert.IsType(VersionString(""), hugoInfo.Version())
-	assert.Equal(commitHash, hugoInfo.CommitHash)
-	assert.Equal(buildDate, hugoInfo.BuildDate)
-	assert.Equal("production", hugoInfo.Environment)
-	assert.Contains(hugoInfo.Generator(), fmt.Sprintf("Hugo %s", hugoInfo.Version()))
+	c.Assert(hugoInfo.Version(), qt.Equals, CurrentVersion.Version())
+	c.Assert(fmt.Sprintf("%T", VersionString("")), qt.Equals, fmt.Sprintf("%T", hugoInfo.Version()))
+	c.Assert(hugoInfo.CommitHash, qt.Equals, commitHash)
+	c.Assert(hugoInfo.BuildDate, qt.Equals, buildDate)
+	c.Assert(hugoInfo.Environment, qt.Equals, "production")
+	c.Assert(string(hugoInfo.Generator()), qt.Contains, fmt.Sprintf("Hugo %s", hugoInfo.Version()))
 
 }
--- a/common/hugo/version_test.go
+++ b/common/hugo/version_test.go
@@ -16,70 +16,73 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestHugoVersion(t *testing.T) {
-	assert.Equal(t, "0.15-DEV", version(0.15, 0, "-DEV"))
-	assert.Equal(t, "0.15.2-DEV", version(0.15, 2, "-DEV"))
+	c := qt.New(t)
 
+	c.Assert(version(0.15, 0, "-DEV"), qt.Equals, "0.15-DEV")
+	c.Assert(version(0.15, 2, "-DEV"), qt.Equals, "0.15.2-DEV")
+
 	v := Version{Number: 0.21, PatchLevel: 0, Suffix: "-DEV"}
 
-	require.Equal(t, v.ReleaseVersion().String(), "0.21")
-	require.Equal(t, "0.21-DEV", v.String())
-	require.Equal(t, "0.22", v.Next().String())
+	c.Assert(v.ReleaseVersion().String(), qt.Equals, "0.21")
+	c.Assert(v.String(), qt.Equals, "0.21-DEV")
+	c.Assert(v.Next().String(), qt.Equals, "0.22")
 	nextVersionString := v.Next().Version()
-	require.Equal(t, "0.22", nextVersionString.String())
-	require.True(t, nextVersionString.Eq("0.22"))
-	require.False(t, nextVersionString.Eq("0.21"))
-	require.True(t, nextVersionString.Eq(nextVersionString))
-	require.Equal(t, "0.20.3", v.NextPatchLevel(3).String())
+	c.Assert(nextVersionString.String(), qt.Equals, "0.22")
+	c.Assert(nextVersionString.Eq("0.22"), qt.Equals, true)
+	c.Assert(nextVersionString.Eq("0.21"), qt.Equals, false)
+	c.Assert(nextVersionString.Eq(nextVersionString), qt.Equals, true)
+	c.Assert(v.NextPatchLevel(3).String(), qt.Equals, "0.20.3")
 
 	// We started to use full semver versions even for main
 	// releases in v0.54.0
 	v = Version{Number: 0.53, PatchLevel: 0}
-	require.Equal(t, "0.53", v.String())
-	require.Equal(t, "0.54.0", v.Next().String())
-	require.Equal(t, "0.55.0", v.Next().Next().String())
+	c.Assert(v.String(), qt.Equals, "0.53")
+	c.Assert(v.Next().String(), qt.Equals, "0.54.0")
+	c.Assert(v.Next().Next().String(), qt.Equals, "0.55.0")
 	v = Version{Number: 0.54, PatchLevel: 0, Suffix: "-DEV"}
-	require.Equal(t, "0.54.0-DEV", v.String())
+	c.Assert(v.String(), qt.Equals, "0.54.0-DEV")
 }
 
 func TestCompareVersions(t *testing.T) {
-	require.Equal(t, 0, compareVersions(0.20, 0, 0.20))
-	require.Equal(t, 0, compareVersions(0.20, 0, float32(0.20)))
-	require.Equal(t, 0, compareVersions(0.20, 0, float64(0.20)))
-	require.Equal(t, 1, compareVersions(0.19, 1, 0.20))
-	require.Equal(t, 1, compareVersions(0.19, 3, "0.20.2"))
-	require.Equal(t, -1, compareVersions(0.19, 1, 0.01))
-	require.Equal(t, 1, compareVersions(0, 1, 3))
-	require.Equal(t, 1, compareVersions(0, 1, int32(3)))
-	require.Equal(t, 1, compareVersions(0, 1, int64(3)))
-	require.Equal(t, 0, compareVersions(0.20, 0, "0.20"))
-	require.Equal(t, 0, compareVersions(0.20, 1, "0.20.1"))
-	require.Equal(t, -1, compareVersions(0.20, 1, "0.20"))
-	require.Equal(t, 1, compareVersions(0.20, 0, "0.20.1"))
-	require.Equal(t, 1, compareVersions(0.20, 1, "0.20.2"))
-	require.Equal(t, 1, compareVersions(0.21, 1, "0.22.1"))
-	require.Equal(t, -1, compareVersions(0.22, 0, "0.22-DEV"))
-	require.Equal(t, 1, compareVersions(0.22, 0, "0.22.1-DEV"))
-	require.Equal(t, 1, compareVersionsWithSuffix(0.22, 0, "-DEV", "0.22"))
-	require.Equal(t, -1, compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22"))
-	require.Equal(t, 0, compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22.1-DEV"))
+	c := qt.New(t)
 
+	c.Assert(compareVersions(0.20, 0, 0.20), qt.Equals, 0)
+	c.Assert(compareVersions(0.20, 0, float32(0.20)), qt.Equals, 0)
+	c.Assert(compareVersions(0.20, 0, float64(0.20)), qt.Equals, 0)
+	c.Assert(compareVersions(0.19, 1, 0.20), qt.Equals, 1)
+	c.Assert(compareVersions(0.19, 3, "0.20.2"), qt.Equals, 1)
+	c.Assert(compareVersions(0.19, 1, 0.01), qt.Equals, -1)
+	c.Assert(compareVersions(0, 1, 3), qt.Equals, 1)
+	c.Assert(compareVersions(0, 1, int32(3)), qt.Equals, 1)
+	c.Assert(compareVersions(0, 1, int64(3)), qt.Equals, 1)
+	c.Assert(compareVersions(0.20, 0, "0.20"), qt.Equals, 0)
+	c.Assert(compareVersions(0.20, 1, "0.20.1"), qt.Equals, 0)
+	c.Assert(compareVersions(0.20, 1, "0.20"), qt.Equals, -1)
+	c.Assert(compareVersions(0.20, 0, "0.20.1"), qt.Equals, 1)
+	c.Assert(compareVersions(0.20, 1, "0.20.2"), qt.Equals, 1)
+	c.Assert(compareVersions(0.21, 1, "0.22.1"), qt.Equals, 1)
+	c.Assert(compareVersions(0.22, 0, "0.22-DEV"), qt.Equals, -1)
+	c.Assert(compareVersions(0.22, 0, "0.22.1-DEV"), qt.Equals, 1)
+	c.Assert(compareVersionsWithSuffix(0.22, 0, "-DEV", "0.22"), qt.Equals, 1)
+	c.Assert(compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22"), qt.Equals, -1)
+	c.Assert(compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22.1-DEV"), qt.Equals, 0)
 }
 
 func TestParseHugoVersion(t *testing.T) {
-	require.Equal(t, "0.25", MustParseVersion("0.25").String())
-	require.Equal(t, "0.25.2", MustParseVersion("0.25.2").String())
-	require.Equal(t, "0.25-test", MustParseVersion("0.25-test").String())
-	require.Equal(t, "0.25-DEV", MustParseVersion("0.25-DEV").String())
+	c := qt.New(t)
 
+	c.Assert(MustParseVersion("0.25").String(), qt.Equals, "0.25")
+	c.Assert(MustParseVersion("0.25.2").String(), qt.Equals, "0.25.2")
+	c.Assert(MustParseVersion("0.25-test").String(), qt.Equals, "0.25-test")
+	c.Assert(MustParseVersion("0.25-DEV").String(), qt.Equals, "0.25-DEV")
 }
 
 func TestGoMinorVersion(t *testing.T) {
-	assert := require.New(t)
-	assert.Equal(12, goMinorVersion("go1.12.5"))
-	assert.True(GoMinorVersion() >= 11)
+	c := qt.New(t)
+	c.Assert(goMinorVersion("go1.12.5"), qt.Equals, 12)
+	c.Assert(GoMinorVersion() >= 11, qt.Equals, true)
 }
--- a/common/loggers/loggers_test.go
+++ b/common/loggers/loggers_test.go
@@ -16,11 +16,11 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestLogger(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	l := NewWarningLogger()
 
 	l.ERROR.Println("One error")
@@ -27,6 +27,6 @@
 	l.ERROR.Println("Two error")
 	l.WARN.Println("A warning")
 
-	assert.Equal(uint64(2), l.ErrorCounter.Count())
+	c.Assert(l.ErrorCounter.Count(), qt.Equals, uint64(2))
 
 }
--- a/common/maps/maps_test.go
+++ b/common/maps/maps_test.go
@@ -17,7 +17,7 @@
 	"reflect"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestToLower(t *testing.T) {
@@ -74,7 +74,7 @@
 }
 
 func TestRenameKeys(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	m := map[string]interface{}{
 		"a":    32,
@@ -112,7 +112,7 @@
 		"{ren1,sub/*/ren1}", "new1",
 		"{Ren2,sub/ren2}", "new2",
 	)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	renamer.Rename(m)
 
--- a/common/maps/params_test.go
+++ b/common/maps/params_test.go
@@ -16,7 +16,7 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestGetNestedParam(t *testing.T) {
@@ -33,19 +33,19 @@
 		},
 	}
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	must := func(keyStr, separator string, candidates ...map[string]interface{}) interface{} {
 		v, err := GetNestedParam(keyStr, separator, candidates...)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		return v
 	}
 
-	assert.Equal(1, must("first", "_", m))
-	assert.Equal(1, must("First", "_", m))
-	assert.Equal(2, must("with_underscore", "_", m))
-	assert.Equal("blue", must("nested_color", "_", m))
-	assert.Equal("green", must("nested.nestednested.color", ".", m))
-	assert.Nil(must("string.name", ".", m))
+	c.Assert(must("first", "_", m), qt.Equals, 1)
+	c.Assert(must("First", "_", m), qt.Equals, 1)
+	c.Assert(must("with_underscore", "_", m), qt.Equals, 2)
+	c.Assert(must("nested_color", "_", m), qt.Equals, "blue")
+	c.Assert(must("nested.nestednested.color", ".", m), qt.Equals, "green")
+	c.Assert(must("string.name", ".", m), qt.IsNil)
 
 }
--- a/common/maps/scratch_test.go
+++ b/common/maps/scratch_test.go
@@ -18,12 +18,12 @@
 	"sync"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestScratchAdd(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	scratch := NewScratch()
 	scratch.Add("int1", 10)
@@ -30,19 +30,19 @@
 	scratch.Add("int1", 20)
 	scratch.Add("int2", 20)
 
-	assert.Equal(int64(30), scratch.Get("int1"))
-	assert.Equal(20, scratch.Get("int2"))
+	c.Assert(scratch.Get("int1"), qt.Equals, int64(30))
+	c.Assert(scratch.Get("int2"), qt.Equals, 20)
 
 	scratch.Add("float1", float64(10.5))
 	scratch.Add("float1", float64(20.1))
 
-	assert.Equal(float64(30.6), scratch.Get("float1"))
+	c.Assert(scratch.Get("float1"), qt.Equals, float64(30.6))
 
 	scratch.Add("string1", "Hello ")
 	scratch.Add("string1", "big ")
 	scratch.Add("string1", "World!")
 
-	assert.Equal("Hello big World!", scratch.Get("string1"))
+	c.Assert(scratch.Get("string1"), qt.Equals, "Hello big World!")
 
 	scratch.Add("scratch", scratch)
 	_, err := scratch.Add("scratch", scratch)
@@ -55,14 +55,14 @@
 
 func TestScratchAddSlice(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	scratch := NewScratch()
 
 	_, err := scratch.Add("intSlice", []int{1, 2})
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	_, err = scratch.Add("intSlice", 3)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	sl := scratch.Get("intSlice")
 	expected := []int{1, 2, 3}
@@ -72,7 +72,7 @@
 	}
 	_, err = scratch.Add("intSlice", []int{4, 5})
 
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	sl = scratch.Get("intSlice")
 	expected = []int{1, 2, 3, 4, 5}
@@ -85,14 +85,14 @@
 // https://github.com/gohugoio/hugo/issues/5275
 func TestScratchAddTypedSliceToInterfaceSlice(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	scratch := NewScratch()
 	scratch.Set("slice", []interface{}{})
 
 	_, err := scratch.Add("slice", []int{1, 2})
-	assert.NoError(err)
-	assert.Equal([]int{1, 2}, scratch.Get("slice"))
+	c.Assert(err, qt.IsNil)
+	c.Assert(scratch.Get("slice"), qt.DeepEquals, []int{1, 2})
 
 }
 
@@ -99,35 +99,35 @@
 // https://github.com/gohugoio/hugo/issues/5361
 func TestScratchAddDifferentTypedSliceToInterfaceSlice(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	scratch := NewScratch()
 	scratch.Set("slice", []string{"foo"})
 
 	_, err := scratch.Add("slice", []int{1, 2})
-	assert.NoError(err)
-	assert.Equal([]interface{}{"foo", 1, 2}, scratch.Get("slice"))
+	c.Assert(err, qt.IsNil)
+	c.Assert(scratch.Get("slice"), qt.DeepEquals, []interface{}{"foo", 1, 2})
 
 }
 
 func TestScratchSet(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	scratch := NewScratch()
 	scratch.Set("key", "val")
-	assert.Equal("val", scratch.Get("key"))
+	c.Assert(scratch.Get("key"), qt.Equals, "val")
 }
 
 func TestScratchDelete(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	scratch := NewScratch()
 	scratch.Set("key", "val")
 	scratch.Delete("key")
 	scratch.Add("key", "Lucy Parsons")
-	assert.Equal("Lucy Parsons", scratch.Get("key"))
+	c.Assert(scratch.Get("key"), qt.Equals, "Lucy Parsons")
 }
 
 // Issue #2005
@@ -177,7 +177,7 @@
 
 func TestScratchSetInMap(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	scratch := NewScratch()
 	scratch.SetInMap("key", "lux", "Lux")
@@ -185,7 +185,7 @@
 	scratch.SetInMap("key", "zyx", "Zyx")
 	scratch.SetInMap("key", "abc", "Abc (updated)")
 	scratch.SetInMap("key", "def", "Def")
-	assert.Equal([]interface{}{0: "Abc (updated)", 1: "Def", 2: "Lux", 3: "Zyx"}, scratch.GetSortedMapValues("key"))
+	c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []interface{}{0: "Abc (updated)", 1: "Def", 2: "Lux", 3: "Zyx"})
 }
 
 func TestScratchGetSortedMapValues(t *testing.T) {
--- a/common/math/math_test.go
+++ b/common/math/math_test.go
@@ -14,17 +14,16 @@
 package math
 
 import (
-	"fmt"
 	"testing"
 
-	"github.com/alecthomas/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestDoArithmetic(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		b      interface{}
 		op     rune
@@ -94,16 +93,14 @@
 		{"foo", "bar", '-', false},
 		{3, 2, '%', false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
-
 		result, err := DoArithmetic(test.a, test.b, test.op)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(test.expect, qt.Equals, result)
 	}
 }
--- a/common/text/position_test.go
+++ b/common/text/position_test.go
@@ -16,18 +16,18 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestPositionStringFormatter(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	pos := Position{Filename: "/my/file.txt", LineNumber: 12, ColumnNumber: 13, Offset: 14}
 
-	assert.Equal("/my/file.txt|13|12", createPositionStringFormatter(":file|:col|:line")(pos))
-	assert.Equal("13|/my/file.txt|12", createPositionStringFormatter(":col|:file|:line")(pos))
-	assert.Equal("好:13", createPositionStringFormatter("好::col")(pos))
-	assert.Equal("\"/my/file.txt:12:13\"", createPositionStringFormatter("")(pos))
-	assert.Equal("\"/my/file.txt:12:13\"", pos.String())
+	c.Assert(createPositionStringFormatter(":file|:col|:line")(pos), qt.Equals, "/my/file.txt|13|12")
+	c.Assert(createPositionStringFormatter(":col|:file|:line")(pos), qt.Equals, "13|/my/file.txt|12")
+	c.Assert(createPositionStringFormatter("好::col")(pos), qt.Equals, "好:13")
+	c.Assert(createPositionStringFormatter("")(pos), qt.Equals, "\"/my/file.txt:12:13\"")
+	c.Assert(pos.String(), qt.Equals, "\"/my/file.txt:12:13\"")
 
 }
--- a/common/types/evictingqueue_test.go
+++ b/common/types/evictingqueue_test.go
@@ -17,36 +17,36 @@
 	"sync"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestEvictingStringQueue(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	queue := NewEvictingStringQueue(3)
 
-	assert.Equal("", queue.Peek())
+	c.Assert(queue.Peek(), qt.Equals, "")
 	queue.Add("a")
 	queue.Add("b")
 	queue.Add("a")
-	assert.Equal("b", queue.Peek())
+	c.Assert(queue.Peek(), qt.Equals, "b")
 	queue.Add("b")
-	assert.Equal("b", queue.Peek())
+	c.Assert(queue.Peek(), qt.Equals, "b")
 
 	queue.Add("a")
 	queue.Add("b")
 
-	assert.True(queue.Contains("a"))
-	assert.False(queue.Contains("foo"))
+	c.Assert(queue.Contains("a"), qt.Equals, true)
+	c.Assert(queue.Contains("foo"), qt.Equals, false)
 
-	assert.Equal([]string{"b", "a"}, queue.PeekAll())
-	assert.Equal("b", queue.Peek())
+	c.Assert(queue.PeekAll(), qt.DeepEquals, []string{"b", "a"})
+	c.Assert(queue.Peek(), qt.Equals, "b")
 	queue.Add("c")
 	queue.Add("d")
 	// Overflowed, a should now be removed.
-	assert.Equal([]string{"d", "c", "b"}, queue.PeekAll())
-	assert.Len(queue.PeekAllSet(), 3)
-	assert.True(queue.PeekAllSet()["c"])
+	c.Assert(queue.PeekAll(), qt.DeepEquals, []string{"d", "c", "b"})
+	c.Assert(len(queue.PeekAllSet()), qt.Equals, 3)
+	c.Assert(queue.PeekAllSet()["c"], qt.Equals, true)
 }
 
 func TestEvictingStringQueueConcurrent(t *testing.T) {
--- a/common/types/types_test.go
+++ b/common/types/types_test.go
@@ -16,14 +16,14 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestKeyValues(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	kv := NewKeyValuesStrings("key", "a1", "a2")
 
-	assert.Equal("key", kv.KeyString())
-	assert.Equal([]interface{}{"a1", "a2"}, kv.Values)
+	c.Assert(kv.KeyString(), qt.Equals, "key")
+	c.Assert(kv.Values, qt.DeepEquals, []interface{}{"a1", "a2"})
 }
--- a/compare/compare_strings_test.go
+++ b/compare/compare_strings_test.go
@@ -14,17 +14,16 @@
 package compare
 
 import (
-	"fmt"
 	"sort"
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestCompare(t *testing.T) {
-	assert := require.New(t)
-	for i, test := range []struct {
+	c := qt.New(t)
+	for _, test := range []struct {
 		a string
 		b string
 	}{
@@ -47,13 +46,13 @@
 		expect := strings.Compare(strings.ToLower(test.a), strings.ToLower(test.b))
 		got := compareFold(test.a, test.b)
 
-		assert.Equal(expect, got, fmt.Sprintf("test %d: %d", i, expect))
+		c.Assert(got, qt.Equals, expect)
 
 	}
 }
 
 func TestLexicographicSort(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	s := []string{"b", "Bz", "ba", "A", "Ba", "ba"}
 
@@ -61,6 +60,6 @@
 		return LessStrings(s[i], s[j])
 	})
 
-	assert.Equal([]string{"A", "b", "Ba", "ba", "ba", "Bz"}, s)
+	c.Assert(s, qt.DeepEquals, []string{"A", "b", "Ba", "ba", "ba", "Bz"})
 
 }
--- a/config/configLoader_test.go
+++ b/config/configLoader_test.go
@@ -17,18 +17,18 @@
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestIsValidConfigFileName(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	for _, ext := range ValidConfigFileExtensions {
 		filename := "config." + ext
-		assert.True(IsValidConfigFilename(filename), ext)
-		assert.True(IsValidConfigFilename(strings.ToUpper(filename)))
+		c.Assert(IsValidConfigFilename(filename), qt.Equals, true)
+		c.Assert(IsValidConfigFilename(strings.ToUpper(filename)), qt.Equals, true)
 	}
 
-	assert.False(IsValidConfigFilename(""))
-	assert.False(IsValidConfigFilename("config.toml.swp"))
+	c.Assert(IsValidConfigFilename(""), qt.Equals, false)
+	c.Assert(IsValidConfigFilename("config.toml.swp"), qt.Equals, false)
 }
--- a/config/configProvider_test.go
+++ b/config/configProvider_test.go
@@ -16,12 +16,12 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestGetStringSlicePreserveString(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	cfg := viper.New()
 
 	s := "This is a string"
@@ -30,7 +30,7 @@
 	cfg.Set("s1", s)
 	cfg.Set("s2", sSlice)
 
-	assert.Equal([]string{s}, GetStringSlicePreserveString(cfg, "s1"))
-	assert.Equal(sSlice, GetStringSlicePreserveString(cfg, "s2"))
-	assert.Nil(GetStringSlicePreserveString(cfg, "s3"))
+	c.Assert(GetStringSlicePreserveString(cfg, "s1"), qt.DeepEquals, []string{s})
+	c.Assert(GetStringSlicePreserveString(cfg, "s2"), qt.DeepEquals, sSlice)
+	c.Assert(GetStringSlicePreserveString(cfg, "s3"), qt.IsNil)
 }
--- a/config/env_test.go
+++ b/config/env_test.go
@@ -16,17 +16,17 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestSetEnvVars(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 	vars := []string{"FOO=bar", "HUGO=cool", "BAR=foo"}
 	SetEnvVars(&vars, "HUGO", "rocking!", "NEW", "bar")
-	assert.Equal([]string{"FOO=bar", "HUGO=rocking!", "BAR=foo", "NEW=bar"}, vars)
+	c.Assert(vars, qt.DeepEquals, []string{"FOO=bar", "HUGO=rocking!", "BAR=foo", "NEW=bar"})
 
 	key, val := SplitEnvVar("HUGO=rocks")
-	assert.Equal("HUGO", key)
-	assert.Equal("rocks", val)
+	c.Assert(key, qt.Equals, "HUGO")
+	c.Assert(val, qt.Equals, "rocks")
 }
--- a/config/privacy/privacyConfig_test.go
+++ b/config/privacy/privacyConfig_test.go
@@ -16,13 +16,13 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/config"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestDecodeConfigFromTOML(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tomlConfig := `
 
@@ -52,30 +52,27 @@
 simple = true
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	pc, err := DecodeConfig(cfg)
-	assert.NoError(err)
-	assert.NotNil(pc)
+	c.Assert(err, qt.IsNil)
+	c.Assert(pc, qt.Not(qt.IsNil))
 
-	assert.True(pc.Disqus.Disable)
-	assert.True(pc.GoogleAnalytics.Disable)
-	assert.True(pc.GoogleAnalytics.RespectDoNotTrack)
-	assert.True(pc.GoogleAnalytics.AnonymizeIP)
-	assert.True(pc.GoogleAnalytics.UseSessionStorage)
-	assert.True(pc.Instagram.Disable)
-	assert.True(pc.Instagram.Simple)
-	assert.True(pc.Twitter.Disable)
-	assert.True(pc.Twitter.EnableDNT)
-	assert.True(pc.Twitter.Simple)
-	assert.True(pc.Vimeo.Disable)
-	assert.True(pc.Vimeo.Simple)
-	assert.True(pc.YouTube.PrivacyEnhanced)
-	assert.True(pc.YouTube.Disable)
+	got := []bool{
+		pc.Disqus.Disable, pc.GoogleAnalytics.Disable,
+		pc.GoogleAnalytics.RespectDoNotTrack, pc.GoogleAnalytics.AnonymizeIP,
+		pc.GoogleAnalytics.UseSessionStorage, pc.Instagram.Disable,
+		pc.Instagram.Simple, pc.Twitter.Disable, pc.Twitter.EnableDNT,
+		pc.Twitter.Simple, pc.Vimeo.Disable, pc.Vimeo.Simple,
+		pc.YouTube.PrivacyEnhanced, pc.YouTube.Disable,
+	}
+
+	c.Assert(got, qt.All(qt.Equals), true)
+
 }
 
 func TestDecodeConfigFromTOMLCaseInsensitive(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tomlConfig := `
 
@@ -86,19 +83,19 @@
 PrivacyENhanced = true
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	pc, err := DecodeConfig(cfg)
-	assert.NoError(err)
-	assert.NotNil(pc)
-	assert.True(pc.YouTube.PrivacyEnhanced)
+	c.Assert(err, qt.IsNil)
+	c.Assert(pc, qt.Not(qt.IsNil))
+	c.Assert(pc.YouTube.PrivacyEnhanced, qt.Equals, true)
 }
 
 func TestDecodeConfigDefault(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	pc, err := DecodeConfig(viper.New())
-	assert.NoError(err)
-	assert.NotNil(pc)
-	assert.False(pc.YouTube.PrivacyEnhanced)
+	c.Assert(err, qt.IsNil)
+	c.Assert(pc, qt.Not(qt.IsNil))
+	c.Assert(pc.YouTube.PrivacyEnhanced, qt.Equals, false)
 }
--- a/config/services/servicesConfig_test.go
+++ b/config/services/servicesConfig_test.go
@@ -16,13 +16,13 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/config"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestDecodeConfigFromTOML(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tomlConfig := `
 
@@ -39,21 +39,21 @@
 disableInlineCSS = true
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	config, err := DecodeConfig(cfg)
-	assert.NoError(err)
-	assert.NotNil(config)
+	c.Assert(err, qt.IsNil)
+	c.Assert(config, qt.Not(qt.IsNil))
 
-	assert.Equal("DS", config.Disqus.Shortname)
-	assert.Equal("ga_id", config.GoogleAnalytics.ID)
+	c.Assert(config.Disqus.Shortname, qt.Equals, "DS")
+	c.Assert(config.GoogleAnalytics.ID, qt.Equals, "ga_id")
 
-	assert.True(config.Instagram.DisableInlineCSS)
+	c.Assert(config.Instagram.DisableInlineCSS, qt.Equals, true)
 }
 
 // Support old root-level GA settings etc.
 func TestUseSettingsFromRootIfSet(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	cfg := viper.New()
 	cfg.Set("disqusShortname", "root_short")
@@ -60,10 +60,10 @@
 	cfg.Set("googleAnalytics", "ga_root")
 
 	config, err := DecodeConfig(cfg)
-	assert.NoError(err)
-	assert.NotNil(config)
+	c.Assert(err, qt.IsNil)
+	c.Assert(config, qt.Not(qt.IsNil))
 
-	assert.Equal("root_short", config.Disqus.Shortname)
-	assert.Equal("ga_root", config.GoogleAnalytics.ID)
+	c.Assert(config.Disqus.Shortname, qt.Equals, "root_short")
+	c.Assert(config.GoogleAnalytics.ID, qt.Equals, "ga_root")
 
 }
--- a/create/content_test.go
+++ b/create/content_test.go
@@ -27,11 +27,11 @@
 
 	"github.com/gohugoio/hugo/hugofs"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/create"
 	"github.com/gohugoio/hugo/helpers"
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestNewContent(t *testing.T) {
@@ -62,25 +62,25 @@
 			"{{</* comment */>}}\n{{%/* comment */%}}"}}, // shortcodes
 	}
 
-	for i, c := range cases {
-		c := c
-		t.Run(fmt.Sprintf("%s-%d", c.kind, i), func(t *testing.T) {
+	for i, cas := range cases {
+		cas := cas
+		t.Run(fmt.Sprintf("%s-%d", cas.kind, i), func(t *testing.T) {
 			t.Parallel()
-			assert := require.New(t)
+			c := qt.New(t)
 			mm := afero.NewMemMapFs()
-			assert.NoError(initFs(mm))
-			cfg, fs := newTestCfg(assert, mm)
+			c.Assert(initFs(mm), qt.IsNil)
+			cfg, fs := newTestCfg(c, mm)
 			h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs})
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 
-			assert.NoError(create.NewContent(h, c.kind, c.path))
+			c.Assert(create.NewContent(h, cas.kind, cas.path), qt.IsNil)
 
-			fname := filepath.FromSlash(c.path)
+			fname := filepath.FromSlash(cas.path)
 			if !strings.HasPrefix(fname, "content") {
 				fname = filepath.Join("content", fname)
 			}
 			content := readFileFromFs(t, fs.Source, fname)
-			for _, v := range c.expected {
+			for _, v := range cas.expected {
 				found := strings.Contains(content, v)
 				if !found {
 					t.Fatalf("[%d] %q missing from output:\n%q", i, v, content)
@@ -93,13 +93,13 @@
 
 func TestNewContentFromDir(t *testing.T) {
 	mm := afero.NewMemMapFs()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	archetypeDir := filepath.Join("archetypes", "my-bundle")
-	assert.NoError(mm.MkdirAll(archetypeDir, 0755))
+	c.Assert(mm.MkdirAll(archetypeDir, 0755), qt.IsNil)
 
 	archetypeThemeDir := filepath.Join("themes", "mytheme", "archetypes", "my-theme-bundle")
-	assert.NoError(mm.MkdirAll(archetypeThemeDir, 0755))
+	c.Assert(mm.MkdirAll(archetypeThemeDir, 0755), qt.IsNil)
 
 	contentFile := `
 File: %s
@@ -108,38 +108,38 @@
 i18n: {{ T "hugo" }}
 `
 
-	assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755))
-	assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.nn.md"), []byte(fmt.Sprintf(contentFile, "index.nn.md")), 0755))
+	c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.nn.md"), []byte(fmt.Sprintf(contentFile, "index.nn.md")), 0755), qt.IsNil)
 
-	assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeDir, "pages", "bio.md"), []byte(fmt.Sprintf(contentFile, "bio.md")), 0755))
-	assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755))
-	assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo2.xml"), []byte(`hugo2: {{ printf "no template handling in here" }}`), 0755))
+	c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "pages", "bio.md"), []byte(fmt.Sprintf(contentFile, "bio.md")), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo2.xml"), []byte(`hugo2: {{ printf "no template handling in here" }}`), 0755), qt.IsNil)
 
-	assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755))
-	assert.NoError(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755))
+	c.Assert(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755), qt.IsNil)
 
-	assert.NoError(initFs(mm))
-	cfg, fs := newTestCfg(assert, mm)
+	c.Assert(initFs(mm), qt.IsNil)
+	cfg, fs := newTestCfg(c, mm)
 
 	h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs})
-	assert.NoError(err)
-	assert.Equal(2, len(h.Sites))
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(h.Sites), qt.Equals, 2)
 
-	assert.NoError(create.NewContent(h, "my-bundle", "post/my-post"))
+	c.Assert(create.NewContent(h, "my-bundle", "post/my-post"), qt.IsNil)
 
-	assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`)
-	assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/resources/hugo2.xml")), `hugo2: {{ printf "no template handling in here" }}`)
+	cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`)
+	cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/resources/hugo2.xml")), `hugo2: {{ printf "no template handling in here" }}`)
 
 	// Content files should get the correct site context.
 	// TODO(bep) archetype check i18n
-	assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Post`, `i18n: Hugo Rocks!`)
-	assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/index.nn.md")), `File: index.nn.md`, `Site Lang: nn`, `Name: My Post`, `i18n: Hugo Rokkar!`)
+	cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Post`, `i18n: Hugo Rocks!`)
+	cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/index.nn.md")), `File: index.nn.md`, `Site Lang: nn`, `Name: My Post`, `i18n: Hugo Rokkar!`)
 
-	assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/pages/bio.md")), `File: bio.md`, `Site Lang: en`, `Name: My Post`)
+	cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/pages/bio.md")), `File: bio.md`, `Site Lang: en`, `Name: My Post`)
 
-	assert.NoError(create.NewContent(h, "my-theme-bundle", "post/my-theme-post"))
-	assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Theme Post`, `i18n: Hugo Rocks!`)
-	assertContains(assert, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`)
+	c.Assert(create.NewContent(h, "my-theme-bundle", "post/my-theme-post"), qt.IsNil)
+	cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Theme Post`, `i18n: Hugo Rocks!`)
+	cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`)
 
 }
 
@@ -221,9 +221,9 @@
 	return nil
 }
 
-func assertContains(assert *require.Assertions, v interface{}, matches ...string) {
+func cContains(c *qt.C, v interface{}, matches ...string) {
 	for _, m := range matches {
-		assert.Contains(v, m)
+		c.Assert(v, qt.Contains, m)
 	}
 }
 
@@ -247,7 +247,7 @@
 	return string(b)
 }
 
-func newTestCfg(assert *require.Assertions, mm afero.Fs) (*viper.Viper, *hugofs.Fs) {
+func newTestCfg(c *qt.C, mm afero.Fs) (*viper.Viper, *hugofs.Fs) {
 
 	cfg := `
 
@@ -270,15 +270,15 @@
 
 	mm.MkdirAll(filepath.FromSlash("themes/mytheme"), 0777)
 
-	assert.NoError(afero.WriteFile(mm, filepath.Join("i18n", "en.toml"), []byte(`[hugo]
-other = "Hugo Rocks!"`), 0755))
-	assert.NoError(afero.WriteFile(mm, filepath.Join("i18n", "nn.toml"), []byte(`[hugo]
-other = "Hugo Rokkar!"`), 0755))
+	c.Assert(afero.WriteFile(mm, filepath.Join("i18n", "en.toml"), []byte(`[hugo]
+other = "Hugo Rocks!"`), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(mm, filepath.Join("i18n", "nn.toml"), []byte(`[hugo]
+other = "Hugo Rokkar!"`), 0755), qt.IsNil)
 
-	assert.NoError(afero.WriteFile(mm, "config.toml", []byte(cfg), 0755))
+	c.Assert(afero.WriteFile(mm, "config.toml", []byte(cfg), 0755), qt.IsNil)
 
 	v, _, err := hugolib.LoadConfig(hugolib.ConfigSourceDescriptor{Fs: mm, Filename: "config.toml"})
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	return v, hugofs.NewFrom(mm, v)
 
--- a/deploy/deployConfig_test.go
+++ b/deploy/deployConfig_test.go
@@ -17,13 +17,13 @@
 	"fmt"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/config"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestDecodeConfigFromTOML(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tomlConfig := `
 
@@ -77,42 +77,42 @@
 force = true
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	dcfg, err := decodeConfig(cfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	// Order.
-	assert.Equal(2, len(dcfg.Order))
-	assert.Equal("o1", dcfg.Order[0])
-	assert.Equal("o2", dcfg.Order[1])
-	assert.Equal(2, len(dcfg.ordering))
+	c.Assert(len(dcfg.Order), qt.Equals, 2)
+	c.Assert(dcfg.Order[0], qt.Equals, "o1")
+	c.Assert(dcfg.Order[1], qt.Equals, "o2")
+	c.Assert(len(dcfg.ordering), qt.Equals, 2)
 
 	// Targets.
-	assert.Equal(3, len(dcfg.Targets))
+	c.Assert(len(dcfg.Targets), qt.Equals, 3)
 	for i := 0; i < 3; i++ {
 		tgt := dcfg.Targets[i]
-		assert.Equal(fmt.Sprintf("name%d", i), tgt.Name)
-		assert.Equal(fmt.Sprintf("url%d", i), tgt.URL)
-		assert.Equal(fmt.Sprintf("cdn%d", i), tgt.CloudFrontDistributionID)
+		c.Assert(tgt.Name, qt.Equals, fmt.Sprintf("name%d", i))
+		c.Assert(tgt.URL, qt.Equals, fmt.Sprintf("url%d", i))
+		c.Assert(tgt.CloudFrontDistributionID, qt.Equals, fmt.Sprintf("cdn%d", i))
 	}
 
 	// Matchers.
-	assert.Equal(3, len(dcfg.Matchers))
+	c.Assert(len(dcfg.Matchers), qt.Equals, 3)
 	for i := 0; i < 3; i++ {
 		m := dcfg.Matchers[i]
-		assert.Equal(fmt.Sprintf("^pattern%d$", i), m.Pattern)
-		assert.NotNil(m.re)
-		assert.Equal(fmt.Sprintf("cachecontrol%d", i), m.CacheControl)
-		assert.Equal(fmt.Sprintf("contentencoding%d", i), m.ContentEncoding)
-		assert.Equal(fmt.Sprintf("contenttype%d", i), m.ContentType)
-		assert.Equal(i != 0, m.Gzip)
-		assert.Equal(i != 0, m.Force)
+		c.Assert(m.Pattern, qt.Equals, fmt.Sprintf("^pattern%d$", i))
+		c.Assert(m.re, qt.Not(qt.IsNil))
+		c.Assert(m.CacheControl, qt.Equals, fmt.Sprintf("cachecontrol%d", i))
+		c.Assert(m.ContentEncoding, qt.Equals, fmt.Sprintf("contentencoding%d", i))
+		c.Assert(m.ContentType, qt.Equals, fmt.Sprintf("contenttype%d", i))
+		c.Assert(m.Gzip, qt.Equals, i != 0)
+		c.Assert(m.Force, qt.Equals, i != 0)
 	}
 }
 
 func TestInvalidOrderingPattern(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tomlConfig := `
 
@@ -122,14 +122,14 @@
 order = ["["]  # invalid regular expression
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	_, err = decodeConfig(cfg)
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 }
 
 func TestInvalidMatcherPattern(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tomlConfig := `
 
@@ -140,17 +140,17 @@
 Pattern = "["  # invalid regular expression
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	_, err = decodeConfig(cfg)
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 }
 
 func TestDecodeConfigDefault(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	dcfg, err := decodeConfig(viper.New())
-	assert.NoError(err)
-	assert.Equal(0, len(dcfg.Targets))
-	assert.Equal(0, len(dcfg.Matchers))
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(dcfg.Targets), qt.Equals, 0)
+	c.Assert(len(dcfg.Matchers), qt.Equals, 0)
 }
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,6 @@
 	github.com/BurntSushi/toml v0.3.1
 	github.com/PuerkitoBio/purell v1.1.0
 	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
-	github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38
 	github.com/alecthomas/chroma v0.6.4
 	github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 // indirect
 	github.com/armon/go-radix v1.0.0
@@ -17,6 +16,7 @@
 	github.com/dustin/go-humanize v1.0.0
 	github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385
 	github.com/fortytw2/leaktest v1.3.0
+	github.com/frankban/quicktest v1.4.1
 	github.com/fsnotify/fsnotify v1.4.7
 	github.com/gobwas/glob v0.2.3
 	github.com/gohugoio/testmodBuilder/mods v0.0.0-20190520184928-c56af20f2e95
@@ -49,7 +49,6 @@
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/spf13/pflag v1.0.3
 	github.com/spf13/viper v1.4.0
-	github.com/stretchr/testify v1.3.0
 	github.com/tdewolff/minify/v2 v2.3.7
 	github.com/yosssi/ace v0.0.5
 	go.opencensus.io v0.22.0 // indirect
@@ -68,4 +67,4 @@
 
 replace github.com/markbates/inflect => github.com/markbates/inflect v0.0.0-20171215194931-a12c3aec81a6
 
-go 1.13
+go 1.12
--- a/go.sum
+++ b/go.sum
@@ -103,6 +103,8 @@
 github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
 github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
+github.com/frankban/quicktest v1.4.1 h1:Wv2VwvNn73pAdFIVUQRXYDFp31lXKbqblIXo/Q5GPSg=
+github.com/frankban/quicktest v1.4.1/go.mod h1:36zfPVQyHxymz4cH7wlDmVwDrJuljRB60qkgn7rorfQ=
 github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
--- a/helpers/content_renderer_test.go
+++ b/helpers/content_renderer_test.go
@@ -18,8 +18,8 @@
 	"regexp"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 // Renders a codeblock using Blackfriday
@@ -43,7 +43,7 @@
 }
 
 func TestCodeFence(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	type test struct {
 		enabled         bool
@@ -64,10 +64,10 @@
 			v.Set("pygmentsCodeFences", d.enabled)
 			v.Set("pygmentsUseClassic", useClassic)
 
-			c, err := NewContentSpec(v)
-			assert.NoError(err)
+			cs, err := NewContentSpec(v)
+			c.Assert(err, qt.IsNil)
 
-			result := c.render(d.input)
+			result := cs.render(d.input)
 
 			expectedRe, err := regexp.Compile(d.expected)
 
@@ -80,7 +80,7 @@
 				t.Errorf("Test %d failed. BlackFriday enabled:%t, Expected:\n%q got:\n%q", i, d.enabled, d.expected, result)
 			}
 
-			result = c.renderWithMmark(d.input)
+			result = cs.renderWithMmark(d.input)
 			matched = expectedRe.MatchString(result)
 			if !matched {
 				t.Errorf("Test %d failed. Mmark enabled:%t, Expected:\n%q got:\n%q", i, d.enabled, d.expected, result)
--- a/helpers/content_test.go
+++ b/helpers/content_test.go
@@ -21,10 +21,9 @@
 
 	"github.com/spf13/viper"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/miekg/mmark"
 	"github.com/russross/blackfriday"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 const tstHTMLContent = "<!DOCTYPE html><html><head><script src=\"http://two/foobar.js\"></script></head><body><nav><ul><li hugo-nav=\"section_0\"></li><li hugo-nav=\"section_1\"></li></ul></nav><article>content <a href=\"http://two/foobar\">foobar</a>. Follow up</article><p>This is some text.<br>And some more.</p></body></html>"
@@ -90,17 +89,19 @@
 }
 
 func TestStripEmptyNav(t *testing.T) {
+	c := qt.New(t)
 	cleaned := stripEmptyNav([]byte("do<nav>\n</nav>\n\nbedobedo"))
-	assert.Equal(t, []byte("dobedobedo"), cleaned)
+	c.Assert(cleaned, qt.DeepEquals, []byte("dobedobedo"))
 }
 
 func TestBytesToHTML(t *testing.T) {
-	assert.Equal(t, template.HTML("dobedobedo"), BytesToHTML([]byte("dobedobedo")))
+	c := qt.New(t)
+	c.Assert(BytesToHTML([]byte("dobedobedo")), qt.Equals, template.HTML("dobedobedo"))
 }
 
 func TestNewContentSpec(t *testing.T) {
 	cfg := viper.New()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	cfg.Set("summaryLength", 32)
 	cfg.Set("buildFuture", true)
@@ -109,11 +110,11 @@
 
 	spec, err := NewContentSpec(cfg)
 
-	assert.NoError(err)
-	assert.Equal(32, spec.summaryLength)
-	assert.True(spec.BuildFuture)
-	assert.True(spec.BuildExpired)
-	assert.True(spec.BuildDrafts)
+	c.Assert(err, qt.IsNil)
+	c.Assert(spec.summaryLength, qt.Equals, 32)
+	c.Assert(spec.BuildFuture, qt.Equals, true)
+	c.Assert(spec.BuildExpired, qt.Equals, true)
+	c.Assert(spec.BuildDrafts, qt.Equals, true)
 
 }
 
--- a/helpers/general_test.go
+++ b/helpers/general_test.go
@@ -19,9 +19,8 @@
 	"strings"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/afero"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 func TestGuessType(t *testing.T) {
@@ -188,6 +187,7 @@
 }
 
 func TestReaderContains(t *testing.T) {
+	c := qt.New(t)
 	for i, this := range append(containsBenchTestData, containsAdditionalTestData...) {
 		result := ReaderContains(strings.NewReader(this.v1), this.v2)
 		if result != this.expect {
@@ -195,21 +195,21 @@
 		}
 	}
 
-	assert.False(t, ReaderContains(nil, []byte("a")))
-	assert.False(t, ReaderContains(nil, nil))
+	c.Assert(ReaderContains(nil, []byte("a")), qt.Equals, false)
+	c.Assert(ReaderContains(nil, nil), qt.Equals, false)
 }
 
 func TestGetTitleFunc(t *testing.T) {
 	title := "somewhere over the rainbow"
-	assert := require.New(t)
+	c := qt.New(t)
 
-	assert.Equal("Somewhere Over The Rainbow", GetTitleFunc("go")(title))
-	assert.Equal("Somewhere over the Rainbow", GetTitleFunc("chicago")(title), "Chicago style")
-	assert.Equal("Somewhere over the Rainbow", GetTitleFunc("Chicago")(title), "Chicago style")
-	assert.Equal("Somewhere Over the Rainbow", GetTitleFunc("ap")(title), "AP style")
-	assert.Equal("Somewhere Over the Rainbow", GetTitleFunc("ap")(title), "AP style")
-	assert.Equal("Somewhere Over the Rainbow", GetTitleFunc("")(title), "AP style")
-	assert.Equal("Somewhere Over the Rainbow", GetTitleFunc("unknown")(title), "AP style")
+	c.Assert(GetTitleFunc("go")(title), qt.Equals, "Somewhere Over The Rainbow")
+	c.Assert(GetTitleFunc("chicago")(title), qt.Equals, "Somewhere over the Rainbow")
+	c.Assert(GetTitleFunc("Chicago")(title), qt.Equals, "Somewhere over the Rainbow")
+	c.Assert(GetTitleFunc("ap")(title), qt.Equals, "Somewhere Over the Rainbow")
+	c.Assert(GetTitleFunc("ap")(title), qt.Equals, "Somewhere Over the Rainbow")
+	c.Assert(GetTitleFunc("")(title), qt.Equals, "Somewhere Over the Rainbow")
+	c.Assert(GetTitleFunc("unknown")(title), qt.Equals, "Somewhere Over the Rainbow")
 
 }
 
@@ -244,19 +244,20 @@
 }
 
 func TestUniqueStringsSorted(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	in := []string{"a", "a", "b", "c", "b", "", "a", "", "d"}
 	output := UniqueStringsSorted(in)
 	expected := []string{"", "a", "b", "c", "d"}
-	assert.Equal(expected, output)
-	assert.Nil(UniqueStringsSorted(nil))
+	c.Assert(output, qt.DeepEquals, expected)
+	c.Assert(UniqueStringsSorted(nil), qt.IsNil)
 }
 
 func TestFindAvailablePort(t *testing.T) {
+	c := qt.New(t)
 	addr, err := FindAvailablePort()
-	assert.Nil(t, err)
-	assert.NotNil(t, addr)
-	assert.True(t, addr.Port > 0)
+	c.Assert(err, qt.IsNil)
+	c.Assert(addr, qt.Not(qt.IsNil))
+	c.Assert(addr.Port > 0, qt.Equals, true)
 }
 
 func TestFastMD5FromFile(t *testing.T) {
@@ -278,17 +279,17 @@
 		t.Fatal(err)
 	}
 
-	req := require.New(t)
+	c := qt.New(t)
 
 	sf1, err := fs.Open("small.txt")
-	req.NoError(err)
+	c.Assert(err, qt.IsNil)
 	sf2, err := fs.Open("small2.txt")
-	req.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	bf1, err := fs.Open("bigger.txt")
-	req.NoError(err)
+	c.Assert(err, qt.IsNil)
 	bf2, err := fs.Open("bigger2.txt")
-	req.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	defer sf1.Close()
 	defer sf2.Close()
@@ -296,24 +297,24 @@
 	defer bf2.Close()
 
 	m1, err := MD5FromFileFast(sf1)
-	req.NoError(err)
-	req.Equal("e9c8989b64b71a88b4efb66ad05eea96", m1)
+	c.Assert(err, qt.IsNil)
+	c.Assert(m1, qt.Equals, "e9c8989b64b71a88b4efb66ad05eea96")
 
 	m2, err := MD5FromFileFast(sf2)
-	req.NoError(err)
-	req.NotEqual(m1, m2)
+	c.Assert(err, qt.IsNil)
+	c.Assert(m2, qt.Not(qt.Equals), m1)
 
 	m3, err := MD5FromFileFast(bf1)
-	req.NoError(err)
-	req.NotEqual(m2, m3)
+	c.Assert(err, qt.IsNil)
+	c.Assert(m3, qt.Not(qt.Equals), m2)
 
 	m4, err := MD5FromFileFast(bf2)
-	req.NoError(err)
-	req.NotEqual(m3, m4)
+	c.Assert(err, qt.IsNil)
+	c.Assert(m4, qt.Not(qt.Equals), m3)
 
 	m5, err := MD5FromReader(bf2)
-	req.NoError(err)
-	req.NotEqual(m4, m5)
+	c.Assert(err, qt.IsNil)
+	c.Assert(m5, qt.Not(qt.Equals), m4)
 }
 
 func BenchmarkMD5FromFileFast(b *testing.B) {
--- a/helpers/path_test.go
+++ b/helpers/path_test.go
@@ -27,7 +27,7 @@
 
 	"github.com/gohugoio/hugo/langs"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/afero"
@@ -35,6 +35,7 @@
 )
 
 func TestMakePath(t *testing.T) {
+	c := qt.New(t)
 	tests := []struct {
 		input         string
 		expected      string
@@ -61,7 +62,7 @@
 
 		l := langs.NewDefaultLanguage(v)
 		p, err := NewPathSpec(hugofs.NewMem(v), l, nil)
-		require.NoError(t, err)
+		c.Assert(err, qt.IsNil)
 
 		output := p.MakePath(test.input)
 		if output != test.expected {
@@ -547,8 +548,8 @@
 }
 
 func TestExtNoDelimiter(t *testing.T) {
-	assert := require.New(t)
-	assert.Equal("json", ExtNoDelimiter(filepath.FromSlash("/my/data.json")))
+	c := qt.New(t)
+	c.Assert(ExtNoDelimiter(filepath.FromSlash("/my/data.json")), qt.Equals, "json")
 }
 
 func TestFilename(t *testing.T) {
@@ -636,11 +637,11 @@
 
 	result := ExtractAndGroupRootPaths(in)
 
-	assert := require.New(t)
-	assert.Equal(filepath.FromSlash("[/a/b/{c,e} /c/d/e]"), fmt.Sprint(result))
+	c := qt.New(t)
+	c.Assert(fmt.Sprint(result), qt.Equals, filepath.FromSlash("[/a/b/{c,e} /c/d/e]"))
 
 	// Make sure the original is preserved
-	assert.Equal(inCopy, in)
+	c.Assert(in, qt.DeepEquals, inCopy)
 
 }
 
--- a/helpers/pathspec_test.go
+++ b/helpers/pathspec_test.go
@@ -17,13 +17,14 @@
 	"path/filepath"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/hugofs"
 
 	"github.com/gohugoio/hugo/langs"
-	"github.com/stretchr/testify/require"
 )
 
 func TestNewPathSpecFromConfig(t *testing.T) {
+	c := qt.New(t)
 	v := newTestCfg()
 	l := langs.NewLanguage("no", v)
 	v.Set("disablePathToLower", true)
@@ -44,16 +45,16 @@
 
 	p, err := NewPathSpec(fs, l, nil)
 
-	require.NoError(t, err)
-	require.True(t, p.CanonifyURLs)
-	require.True(t, p.DisablePathToLower)
-	require.True(t, p.RemovePathAccents)
-	require.True(t, p.UglyURLs)
-	require.Equal(t, "no", p.Language.Lang)
-	require.Equal(t, "side", p.PaginatePath)
+	c.Assert(err, qt.IsNil)
+	c.Assert(p.CanonifyURLs, qt.Equals, true)
+	c.Assert(p.DisablePathToLower, qt.Equals, true)
+	c.Assert(p.RemovePathAccents, qt.Equals, true)
+	c.Assert(p.UglyURLs, qt.Equals, true)
+	c.Assert(p.Language.Lang, qt.Equals, "no")
+	c.Assert(p.PaginatePath, qt.Equals, "side")
 
-	require.Equal(t, "http://base.com", p.BaseURL.String())
-	require.Equal(t, "thethemes", p.ThemesDir)
-	require.Equal(t, "thework", p.WorkingDir)
+	c.Assert(p.BaseURL.String(), qt.Equals, "http://base.com")
+	c.Assert(p.ThemesDir, qt.Equals, "thethemes")
+	c.Assert(p.WorkingDir, qt.Equals, "thework")
 
 }
--- a/helpers/pygments_test.go
+++ b/helpers/pygments_test.go
@@ -20,12 +20,12 @@
 
 	"github.com/alecthomas/chroma/formatters/html"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestParsePygmentsArgs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	for i, this := range []struct {
 		in                 string
@@ -46,7 +46,7 @@
 		v.Set("pygmentsStyle", this.pygmentsStyle)
 		v.Set("pygmentsUseClasses", this.pygmentsUseClasses)
 		spec, err := NewContentSpec(v)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		result1, err := spec.createPygmentsOptionsString(this.in)
 		if b, ok := this.expect1.(bool); ok && !b {
@@ -67,7 +67,7 @@
 }
 
 func TestParseDefaultPygmentsArgs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	expect := "encoding=utf8,noclasses=false,style=foo"
 
@@ -95,7 +95,7 @@
 		}
 
 		spec, err := NewContentSpec(v)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		result, err := spec.createPygmentsOptionsString(this.in)
 		if err != nil {
@@ -134,22 +134,22 @@
 }
 
 func TestChromaHTMLHighlight(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	v := viper.New()
 	v.Set("pygmentsUseClasses", true)
 	spec, err := NewContentSpec(v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	result, err := spec.Highlight(`echo "Hello"`, "bash", "")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Contains(result, `<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="s2">&#34;Hello&#34;</span></code></pre></div>`)
+	c.Assert(result, qt.Contains, `<div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash"><span class="nb">echo</span> <span class="s2">&#34;Hello&#34;</span></code></pre></div>`)
 
 }
 
 func TestChromaHTMLFormatterFromOptions(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	for i, this := range []struct {
 		in                 string
@@ -158,40 +158,40 @@
 		pygmentsOptions    string
 		assert             func(c chromaInfo)
 	}{
-		{"", "monokai", true, "style=manni,noclasses=true", func(c chromaInfo) {
-			assert.True(c.classes)
-			assert.False(c.lineNumbers)
-			assert.Equal(0, c.highlightRangesLen)
+		{"", "monokai", true, "style=manni,noclasses=true", func(ci chromaInfo) {
+			c.Assert(ci.classes, qt.Equals, true)
+			c.Assert(ci.lineNumbers, qt.Equals, false)
+			c.Assert(ci.highlightRangesLen, qt.Equals, 0)
 
 		}},
-		{"", nil, nil, "style=monokai,noclasses=false", func(c chromaInfo) {
-			assert.True(c.classes)
+		{"", nil, nil, "style=monokai,noclasses=false", func(ci chromaInfo) {
+			c.Assert(ci.classes, qt.Equals, true)
 		}},
-		{"linenos=sure,hl_lines=1 2 3", nil, nil, "style=monokai,noclasses=false", func(c chromaInfo) {
-			assert.True(c.classes)
-			assert.True(c.lineNumbers)
-			assert.Equal(3, c.highlightRangesLen)
-			assert.Equal("[[1 1] [2 2] [3 3]]", c.highlightRangesStr)
-			assert.Equal(1, c.baseLineNumber)
+		{"linenos=sure,hl_lines=1 2 3", nil, nil, "style=monokai,noclasses=false", func(ci chromaInfo) {
+			c.Assert(ci.classes, qt.Equals, true)
+			c.Assert(ci.lineNumbers, qt.Equals, true)
+			c.Assert(ci.highlightRangesLen, qt.Equals, 3)
+			c.Assert(ci.highlightRangesStr, qt.Equals, "[[1 1] [2 2] [3 3]]")
+			c.Assert(ci.baseLineNumber, qt.Equals, 1)
 		}},
-		{"linenos=inline,hl_lines=1,linenostart=4", nil, nil, "style=monokai,noclasses=false", func(c chromaInfo) {
-			assert.True(c.classes)
-			assert.True(c.lineNumbers)
-			assert.False(c.lineNumbersInTable)
-			assert.Equal(1, c.highlightRangesLen)
+		{"linenos=inline,hl_lines=1,linenostart=4", nil, nil, "style=monokai,noclasses=false", func(ci chromaInfo) {
+			c.Assert(ci.classes, qt.Equals, true)
+			c.Assert(ci.lineNumbers, qt.Equals, true)
+			c.Assert(ci.lineNumbersInTable, qt.Equals, false)
+			c.Assert(ci.highlightRangesLen, qt.Equals, 1)
 			// This compansates for https://github.com/alecthomas/chroma/issues/30
-			assert.Equal("[[4 4]]", c.highlightRangesStr)
-			assert.Equal(4, c.baseLineNumber)
+			c.Assert(ci.highlightRangesStr, qt.Equals, "[[4 4]]")
+			c.Assert(ci.baseLineNumber, qt.Equals, 4)
 		}},
-		{"linenos=table", nil, nil, "style=monokai", func(c chromaInfo) {
-			assert.True(c.lineNumbers)
-			assert.True(c.lineNumbersInTable)
+		{"linenos=table", nil, nil, "style=monokai", func(ci chromaInfo) {
+			c.Assert(ci.lineNumbers, qt.Equals, true)
+			c.Assert(ci.lineNumbersInTable, qt.Equals, true)
 		}},
-		{"style=monokai,noclasses=false", nil, nil, "style=manni,noclasses=true", func(c chromaInfo) {
-			assert.True(c.classes)
+		{"style=monokai,noclasses=false", nil, nil, "style=manni,noclasses=true", func(ci chromaInfo) {
+			c.Assert(ci.classes, qt.Equals, true)
 		}},
-		{"style=monokai,noclasses=true", "friendly", false, "style=manni,noclasses=false", func(c chromaInfo) {
-			assert.False(c.classes)
+		{"style=monokai,noclasses=true", "friendly", false, "style=manni,noclasses=false", func(ci chromaInfo) {
+			c.Assert(ci.classes, qt.Equals, false)
 		}},
 	} {
 		v := viper.New()
@@ -207,7 +207,7 @@
 		}
 
 		spec, err := NewContentSpec(v)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		opts, err := spec.parsePygmentsOpts(this.in)
 		if err != nil {
@@ -257,7 +257,7 @@
 }
 
 func BenchmarkChromaHighlight(b *testing.B) {
-	assert := require.New(b)
+	c := qt.New(b)
 	v := viper.New()
 
 	v.Set("pygmentsstyle", "trac")
@@ -289,7 +289,7 @@
 `
 
 	spec, err := NewContentSpec(v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	for i := 0; i < b.N; i++ {
 		_, err := spec.Highlight(code, "go", "linenos=inline,hl_lines=8 15-17")
--- a/helpers/url_test.go
+++ b/helpers/url_test.go
@@ -14,14 +14,12 @@
 package helpers
 
 import (
-	"fmt"
 	"strings"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/gohugoio/hugo/langs"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 func TestURLize(t *testing.T) {
@@ -111,7 +109,9 @@
 }
 
 func TestIsAbsURL(t *testing.T) {
-	for i, this := range []struct {
+	c := qt.New(t)
+
+	for _, this := range []struct {
 		a string
 		b bool
 	}{
@@ -122,7 +122,7 @@
 		{"/content", false},
 		{"content", false},
 	} {
-		require.True(t, IsAbsURL(this.a) == this.b, fmt.Sprintf("Test %d", i))
+		c.Assert(IsAbsURL(this.a) == this.b, qt.Equals, true)
 	}
 }
 
@@ -292,31 +292,33 @@
 }
 
 func TestPretty(t *testing.T) {
-	assert.Equal(t, PrettifyURLPath("/section/name.html"), "/section/name/index.html")
-	assert.Equal(t, PrettifyURLPath("/section/sub/name.html"), "/section/sub/name/index.html")
-	assert.Equal(t, PrettifyURLPath("/section/name/"), "/section/name/index.html")
-	assert.Equal(t, PrettifyURLPath("/section/name/index.html"), "/section/name/index.html")
-	assert.Equal(t, PrettifyURLPath("/index.html"), "/index.html")
-	assert.Equal(t, PrettifyURLPath("/name.xml"), "/name/index.xml")
-	assert.Equal(t, PrettifyURLPath("/"), "/")
-	assert.Equal(t, PrettifyURLPath(""), "/")
-	assert.Equal(t, PrettifyURL("/section/name.html"), "/section/name")
-	assert.Equal(t, PrettifyURL("/section/sub/name.html"), "/section/sub/name")
-	assert.Equal(t, PrettifyURL("/section/name/"), "/section/name")
-	assert.Equal(t, PrettifyURL("/section/name/index.html"), "/section/name")
-	assert.Equal(t, PrettifyURL("/index.html"), "/")
-	assert.Equal(t, PrettifyURL("/name.xml"), "/name/index.xml")
-	assert.Equal(t, PrettifyURL("/"), "/")
-	assert.Equal(t, PrettifyURL(""), "/")
+	c := qt.New(t)
+	c.Assert("/section/name/index.html", qt.Equals, PrettifyURLPath("/section/name.html"))
+	c.Assert("/section/sub/name/index.html", qt.Equals, PrettifyURLPath("/section/sub/name.html"))
+	c.Assert("/section/name/index.html", qt.Equals, PrettifyURLPath("/section/name/"))
+	c.Assert("/section/name/index.html", qt.Equals, PrettifyURLPath("/section/name/index.html"))
+	c.Assert("/index.html", qt.Equals, PrettifyURLPath("/index.html"))
+	c.Assert("/name/index.xml", qt.Equals, PrettifyURLPath("/name.xml"))
+	c.Assert("/", qt.Equals, PrettifyURLPath("/"))
+	c.Assert("/", qt.Equals, PrettifyURLPath(""))
+	c.Assert("/section/name", qt.Equals, PrettifyURL("/section/name.html"))
+	c.Assert("/section/sub/name", qt.Equals, PrettifyURL("/section/sub/name.html"))
+	c.Assert("/section/name", qt.Equals, PrettifyURL("/section/name/"))
+	c.Assert("/section/name", qt.Equals, PrettifyURL("/section/name/index.html"))
+	c.Assert("/", qt.Equals, PrettifyURL("/index.html"))
+	c.Assert("/name/index.xml", qt.Equals, PrettifyURL("/name.xml"))
+	c.Assert("/", qt.Equals, PrettifyURL("/"))
+	c.Assert("/", qt.Equals, PrettifyURL(""))
 }
 
 func TestUgly(t *testing.T) {
-	assert.Equal(t, Uglify("/section/name.html"), "/section/name.html")
-	assert.Equal(t, Uglify("/section/sub/name.html"), "/section/sub/name.html")
-	assert.Equal(t, Uglify("/section/name/"), "/section/name.html")
-	assert.Equal(t, Uglify("/section/name/index.html"), "/section/name.html")
-	assert.Equal(t, Uglify("/index.html"), "/index.html")
-	assert.Equal(t, Uglify("/name.xml"), "/name.xml")
-	assert.Equal(t, Uglify("/"), "/")
-	assert.Equal(t, Uglify(""), "/")
+	c := qt.New(t)
+	c.Assert("/section/name.html", qt.Equals, Uglify("/section/name.html"))
+	c.Assert("/section/sub/name.html", qt.Equals, Uglify("/section/sub/name.html"))
+	c.Assert("/section/name.html", qt.Equals, Uglify("/section/name/"))
+	c.Assert("/section/name.html", qt.Equals, Uglify("/section/name/index.html"))
+	c.Assert("/index.html", qt.Equals, Uglify("/index.html"))
+	c.Assert("/name.xml", qt.Equals, Uglify("/name.xml"))
+	c.Assert("/", qt.Equals, Uglify("/"))
+	c.Assert("/", qt.Equals, Uglify(""))
 }
--- /dev/null
+++ b/htesting/hqt/checkers.go
@@ -1,0 +1,92 @@
+// Copyright 2019 The Hugo Authors. All rights reserved.
+//
+// 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.
+
+package hqt
+
+import (
+	"errors"
+	"reflect"
+
+	qt "github.com/frankban/quicktest"
+	"github.com/google/go-cmp/cmp"
+)
+
+// IsSameType asserts that got is the same type as want.
+var IsSameType qt.Checker = &typeChecker{
+	argNames: []string{"got", "want"},
+}
+
+type argNames []string
+
+func (a argNames) ArgNames() []string {
+	return a
+}
+
+type typeChecker struct {
+	argNames
+}
+
+// Check implements Checker.Check by checking that got and args[0] is of the same type.
+func (c *typeChecker) Check(got interface{}, args []interface{}, note func(key string, value interface{})) (err error) {
+	if want := args[0]; reflect.TypeOf(got) != reflect.TypeOf(want) {
+		if _, ok := got.(error); ok && want == nil {
+			return errors.New("got non-nil error")
+		}
+		return errors.New("values are not of same type")
+	}
+	return nil
+}
+
+// DeepAllowUnexported creates an option to allow compare of unexported types
+// in the given list of types.
+// see https://github.com/google/go-cmp/issues/40#issuecomment-328615283
+func DeepAllowUnexported(vs ...interface{}) cmp.Option {
+	m := make(map[reflect.Type]struct{})
+	for _, v := range vs {
+		structTypes(reflect.ValueOf(v), m)
+	}
+	var typs []interface{}
+	for t := range m {
+		typs = append(typs, reflect.New(t).Elem().Interface())
+	}
+	return cmp.AllowUnexported(typs...)
+}
+
+func structTypes(v reflect.Value, m map[reflect.Type]struct{}) {
+	if !v.IsValid() {
+		return
+	}
+	switch v.Kind() {
+	case reflect.Ptr:
+		if !v.IsNil() {
+			structTypes(v.Elem(), m)
+		}
+	case reflect.Interface:
+		if !v.IsNil() {
+			structTypes(v.Elem(), m)
+		}
+	case reflect.Slice, reflect.Array:
+		for i := 0; i < v.Len(); i++ {
+			structTypes(v.Index(i), m)
+		}
+	case reflect.Map:
+		for _, k := range v.MapKeys() {
+			structTypes(v.MapIndex(k), m)
+		}
+	case reflect.Struct:
+		m[v.Type()] = struct{}{}
+		for i := 0; i < v.NumField(); i++ {
+			structTypes(v.Field(i), m)
+		}
+	}
+}
--- a/hugofs/files/classifier_test.go
+++ b/hugofs/files/classifier_test.go
@@ -17,33 +17,33 @@
 	"path/filepath"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestIsContentFile(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
-	assert.True(IsContentFile(filepath.FromSlash("my/file.md")))
-	assert.True(IsContentFile(filepath.FromSlash("my/file.ad")))
-	assert.False(IsContentFile(filepath.FromSlash("textfile.txt")))
-	assert.True(IsContentExt("md"))
-	assert.False(IsContentExt("json"))
+	c.Assert(IsContentFile(filepath.FromSlash("my/file.md")), qt.Equals, true)
+	c.Assert(IsContentFile(filepath.FromSlash("my/file.ad")), qt.Equals, true)
+	c.Assert(IsContentFile(filepath.FromSlash("textfile.txt")), qt.Equals, false)
+	c.Assert(IsContentExt("md"), qt.Equals, true)
+	c.Assert(IsContentExt("json"), qt.Equals, false)
 }
 
 func TestComponentFolders(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	// It's important that these are absolutely right and not changed.
-	assert.Equal(len(ComponentFolders), len(componentFoldersSet))
-	assert.True(IsComponentFolder("archetypes"))
-	assert.True(IsComponentFolder("layouts"))
-	assert.True(IsComponentFolder("data"))
-	assert.True(IsComponentFolder("i18n"))
-	assert.True(IsComponentFolder("assets"))
-	assert.False(IsComponentFolder("resources"))
-	assert.True(IsComponentFolder("static"))
-	assert.True(IsComponentFolder("content"))
-	assert.False(IsComponentFolder("foo"))
-	assert.False(IsComponentFolder(""))
+	c.Assert(len(componentFoldersSet), qt.Equals, len(ComponentFolders))
+	c.Assert(IsComponentFolder("archetypes"), qt.Equals, true)
+	c.Assert(IsComponentFolder("layouts"), qt.Equals, true)
+	c.Assert(IsComponentFolder("data"), qt.Equals, true)
+	c.Assert(IsComponentFolder("i18n"), qt.Equals, true)
+	c.Assert(IsComponentFolder("assets"), qt.Equals, true)
+	c.Assert(IsComponentFolder("resources"), qt.Equals, false)
+	c.Assert(IsComponentFolder("static"), qt.Equals, true)
+	c.Assert(IsComponentFolder("content"), qt.Equals, true)
+	c.Assert(IsComponentFolder("foo"), qt.Equals, false)
+	c.Assert(IsComponentFolder(""), qt.Equals, false)
 
 }
--- a/hugofs/filter_fs_test.go
+++ b/hugofs/filter_fs_test.go
@@ -17,7 +17,7 @@
 	"path/filepath"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestLangInfoFrom(t *testing.T) {
@@ -27,7 +27,7 @@
 		"en": 20,
 	}
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tests := []struct {
 		input    string
@@ -42,7 +42,7 @@
 
 	for _, test := range tests {
 		v1, v2, v3 := langInfoFrom(langs, test.input)
-		assert.Equal(test.expected, []string{v1, v2, v3})
+		c.Assert([]string{v1, v2, v3}, qt.DeepEquals, test.expected)
 	}
 
 }
--- a/hugofs/fs_test.go
+++ b/hugofs/fs_test.go
@@ -16,39 +16,39 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
 )
 
 func TestNewDefault(t *testing.T) {
+	c := qt.New(t)
 	v := viper.New()
 	f := NewDefault(v)
 
-	assert.NotNil(t, f.Source)
-	assert.IsType(t, new(afero.OsFs), f.Source)
-	assert.NotNil(t, f.Destination)
-	assert.IsType(t, new(afero.OsFs), f.Destination)
-	assert.NotNil(t, f.Os)
-	assert.IsType(t, new(afero.OsFs), f.Os)
-	assert.Nil(t, f.WorkingDir)
+	c.Assert(f.Source, qt.Not(qt.IsNil))
+	c.Assert(f.Source, hqt.IsSameType, new(afero.OsFs))
+	c.Assert(f.Os, qt.Not(qt.IsNil))
+	c.Assert(f.WorkingDir, qt.IsNil)
 
-	assert.IsType(t, new(afero.OsFs), Os)
 }
 
 func TestNewMem(t *testing.T) {
+	c := qt.New(t)
 	v := viper.New()
 	f := NewMem(v)
 
-	assert.NotNil(t, f.Source)
-	assert.IsType(t, new(afero.MemMapFs), f.Source)
-	assert.NotNil(t, f.Destination)
-	assert.IsType(t, new(afero.MemMapFs), f.Destination)
-	assert.IsType(t, new(afero.OsFs), f.Os)
-	assert.Nil(t, f.WorkingDir)
+	c.Assert(f.Source, qt.Not(qt.IsNil))
+	c.Assert(f.Source, hqt.IsSameType, new(afero.MemMapFs))
+	c.Assert(f.Destination, qt.Not(qt.IsNil))
+	c.Assert(f.Destination, hqt.IsSameType, new(afero.MemMapFs))
+	c.Assert(f.Os, hqt.IsSameType, new(afero.OsFs))
+	c.Assert(f.WorkingDir, qt.IsNil)
 }
 
 func TestWorkingDir(t *testing.T) {
+	c := qt.New(t)
 	v := viper.New()
 
 	v.Set("workingDir", "/a/b/")
@@ -55,6 +55,7 @@
 
 	f := NewMem(v)
 
-	assert.NotNil(t, f.WorkingDir)
-	assert.IsType(t, new(afero.BasePathFs), f.WorkingDir)
+	c.Assert(f.WorkingDir, qt.Not(qt.IsNil))
+	c.Assert(f.WorkingDir, hqt.IsSameType, new(afero.BasePathFs))
+
 }
--- a/hugofs/hashing_fs_test.go
+++ b/hugofs/hashing_fs_test.go
@@ -16,8 +16,8 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/afero"
-	"github.com/stretchr/testify/require"
 )
 
 type testHashReceiver struct {
@@ -31,7 +31,7 @@
 }
 
 func TestHashingFs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	fs := afero.NewMemMapFs()
 	observer := &testHashReceiver{}
@@ -38,16 +38,16 @@
 	ofs := NewHashingFs(fs, observer)
 
 	f, err := ofs.Create("hashme")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	_, err = f.Write([]byte("content"))
-	assert.NoError(err)
-	assert.NoError(f.Close())
-	assert.Equal("9a0364b9e99bb480dd25e1f0284c8555", observer.sum)
-	assert.Equal("hashme", observer.name)
+	c.Assert(err, qt.IsNil)
+	c.Assert(f.Close(), qt.IsNil)
+	c.Assert(observer.sum, qt.Equals, "9a0364b9e99bb480dd25e1f0284c8555")
+	c.Assert(observer.name, qt.Equals, "hashme")
 
 	f, err = ofs.Create("nowrites")
-	assert.NoError(err)
-	assert.NoError(f.Close())
-	assert.Equal("d41d8cd98f00b204e9800998ecf8427e", observer.sum)
+	c.Assert(err, qt.IsNil)
+	c.Assert(f.Close(), qt.IsNil)
+	c.Assert(observer.sum, qt.Equals, "d41d8cd98f00b204e9800998ecf8427e")
 
 }
--- a/hugofs/nosymlink_test.go
+++ b/hugofs/nosymlink_test.go
@@ -24,28 +24,28 @@
 
 	"github.com/spf13/afero"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func prepareSymlinks(t *testing.T) (string, func()) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	workDir, clean, err := htesting.CreateTempDir(Os, "hugo-symlink-test")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	wd, _ := os.Getwd()
 
 	blogDir := filepath.Join(workDir, "blog")
 	blogSubDir := filepath.Join(blogDir, "sub")
-	assert.NoError(os.MkdirAll(blogSubDir, 0777))
+	c.Assert(os.MkdirAll(blogSubDir, 0777), qt.IsNil)
 	blogFile1 := filepath.Join(blogDir, "a.txt")
 	blogFile2 := filepath.Join(blogSubDir, "b.txt")
 	afero.WriteFile(Os, filepath.Join(blogFile1), []byte("content1"), 0777)
 	afero.WriteFile(Os, filepath.Join(blogFile2), []byte("content2"), 0777)
 	os.Chdir(workDir)
-	assert.NoError(os.Symlink("blog", "symlinkdedir"))
+	c.Assert(os.Symlink("blog", "symlinkdedir"), qt.IsNil)
 	os.Chdir(blogDir)
-	assert.NoError(os.Symlink("sub", "symsub"))
-	assert.NoError(os.Symlink("a.txt", "symlinkdedfile.txt"))
+	c.Assert(os.Symlink("sub", "symsub"), qt.IsNil)
+	c.Assert(os.Symlink("a.txt", "symlinkdedfile.txt"), qt.IsNil)
 
 	return workDir, func() {
 		clean()
@@ -57,7 +57,7 @@
 	if skipSymlink() {
 		t.Skip("Skip; os.Symlink needs administrator rights on Windows")
 	}
-	assert := require.New(t)
+	c := qt.New(t)
 	workDir, clean := prepareSymlinks(t)
 	defer clean()
 
@@ -77,9 +77,9 @@
 
 			assertFileErr := func(err error) {
 				if allowFiles {
-					assert.NoError(err)
+					c.Assert(err, qt.IsNil)
 				} else {
-					assert.Equal(ErrPermissionSymlink, err)
+					c.Assert(err, qt.Equals, ErrPermissionSymlink)
 				}
 			}
 
@@ -87,8 +87,8 @@
 				t.Helper()
 				assertFileErr(err)
 				if err == nil {
-					assert.NotNil(fi)
-					assert.Equal(name, fi.Name())
+					c.Assert(fi, qt.Not(qt.IsNil))
+					c.Assert(fi.Name(), qt.Equals, name)
 				}
 			}
 
@@ -103,42 +103,42 @@
 				},
 			} {
 				_, err := stat(symlinkedDir)
-				assert.Equal(ErrPermissionSymlink, err)
+				c.Assert(err, qt.Equals, ErrPermissionSymlink)
 				fi, err := stat(symlinkedFile)
 				assertFileStat(symlinkedFilename, fi, err)
 
 				fi, err = stat(filepath.Join(workDir, "blog"))
-				assert.NoError(err)
-				assert.NotNil(fi)
+				c.Assert(err, qt.IsNil)
+				c.Assert(fi, qt.Not(qt.IsNil))
 
 				fi, err = stat(blogFile1)
-				assert.NoError(err)
-				assert.NotNil(fi)
+				c.Assert(err, qt.IsNil)
+				c.Assert(fi, qt.Not(qt.IsNil))
 			}
 
 			// Check Open
 			_, err := fs.Open(symlinkedDir)
-			assert.Equal(ErrPermissionSymlink, err)
+			c.Assert(err, qt.Equals, ErrPermissionSymlink)
 			_, err = fs.OpenFile(symlinkedDir, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
-			assert.Equal(ErrPermissionSymlink, err)
+			c.Assert(err, qt.Equals, ErrPermissionSymlink)
 			_, err = fs.OpenFile(symlinkedFile, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
 			assertFileErr(err)
 			_, err = fs.Open(symlinkedFile)
 			assertFileErr(err)
 			f, err := fs.Open(blogDir)
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 			f.Close()
 			f, err = fs.Open(blogFile1)
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 			f.Close()
 
 			// Check readdir
 			f, err = fs.Open(workDir)
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 			// There is at least one unsported symlink inside workDir
 			_, err = f.Readdir(-1)
 			f.Close()
-			assert.Equal(uint64(1), logger.WarnCounter.Count())
+			c.Assert(logger.WarnCounter.Count(), qt.Equals, uint64(1))
 
 		}
 	}
--- a/hugofs/rootmapping_fs_test.go
+++ b/hugofs/rootmapping_fs_test.go
@@ -21,24 +21,24 @@
 
 	"github.com/spf13/viper"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/htesting"
 	"github.com/spf13/afero"
-	"github.com/stretchr/testify/require"
 )
 
 func TestLanguageRootMapping(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	v := viper.New()
 	v.Set("contentDir", "content")
 
 	fs := NewBaseFileDecorator(afero.NewMemMapFs())
 
-	assert.NoError(afero.WriteFile(fs, filepath.Join("content/sv/svdir", "main.txt"), []byte("main sv"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/a/mysvblogcontent", "sv-f.txt"), []byte("some sv blog content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/a/myenblogcontent", "en-f.txt"), []byte("some en blog content in a"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/a/myotherenblogcontent", "en-f2.txt"), []byte("some en content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/a/mysvdocs", "sv-docs.txt"), []byte("some sv docs content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/b/myenblogcontent", "en-b-f.txt"), []byte("some en content"), 0755))
+	c.Assert(afero.WriteFile(fs, filepath.Join("content/sv/svdir", "main.txt"), []byte("main sv"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/a/mysvblogcontent", "sv-f.txt"), []byte("some sv blog content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/a/myenblogcontent", "en-f.txt"), []byte("some en blog content in a"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/a/myotherenblogcontent", "en-f2.txt"), []byte("some en content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/a/mysvdocs", "sv-docs.txt"), []byte("some sv docs content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/b/myenblogcontent", "en-b-f.txt"), []byte("some en content"), 0755), qt.IsNil)
 
 	rfs, err := NewRootMappingFs(fs,
 		RootMapping{
@@ -68,38 +68,38 @@
 		},
 	)
 
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	collected, err := collectFilenames(rfs, "content", "content")
-	assert.NoError(err)
-	assert.Equal([]string{"blog/en-f.txt", "blog/en-f2.txt", "blog/sv-f.txt", "blog/svdir/main.txt", "docs/sv-docs.txt"}, collected)
+	c.Assert(err, qt.IsNil)
+	c.Assert(collected, qt.DeepEquals, []string{"blog/en-f.txt", "blog/en-f2.txt", "blog/sv-f.txt", "blog/svdir/main.txt", "docs/sv-docs.txt"})
 
 	bfs := afero.NewBasePathFs(rfs, "content")
 	collected, err = collectFilenames(bfs, "", "")
-	assert.NoError(err)
-	assert.Equal([]string{"blog/en-f.txt", "blog/en-f2.txt", "blog/sv-f.txt", "blog/svdir/main.txt", "docs/sv-docs.txt"}, collected)
+	c.Assert(err, qt.IsNil)
+	c.Assert(collected, qt.DeepEquals, []string{"blog/en-f.txt", "blog/en-f2.txt", "blog/sv-f.txt", "blog/svdir/main.txt", "docs/sv-docs.txt"})
 
 	dirs, err := rfs.Dirs(filepath.FromSlash("content/blog"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal(4, len(dirs))
+	c.Assert(len(dirs), qt.Equals, 4)
 
 	getDirnames := func(name string, rfs *RootMappingFs) []string {
 		filename := filepath.FromSlash(name)
 		f, err := rfs.Open(filename)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		names, err := f.Readdirnames(-1)
 
 		f.Close()
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		info, err := rfs.Stat(filename)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		f2, err := info.(FileMetaInfo).Meta().Open()
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		names2, err := f2.Readdirnames(-1)
-		assert.NoError(err)
-		assert.Equal(names, names2)
+		c.Assert(err, qt.IsNil)
+		c.Assert(names2, qt.DeepEquals, names)
 		f2.Close()
 
 		return names
@@ -109,83 +109,83 @@
 		return rm.Meta.Lang() == "en"
 	})
 
-	assert.Equal([]string{"en-f.txt", "en-f2.txt"}, getDirnames("content/blog", rfsEn))
+	c.Assert(getDirnames("content/blog", rfsEn), qt.DeepEquals, []string{"en-f.txt", "en-f2.txt"})
 
 	rfsSv := rfs.Filter(func(rm RootMapping) bool {
 		return rm.Meta.Lang() == "sv"
 	})
 
-	assert.Equal([]string{"sv-f.txt", "svdir"}, getDirnames("content/blog", rfsSv))
+	c.Assert(getDirnames("content/blog", rfsSv), qt.DeepEquals, []string{"sv-f.txt", "svdir"})
 
 	// Make sure we have not messed with the original
-	assert.Equal([]string{"sv-f.txt", "en-f.txt", "svdir", "en-f2.txt"}, getDirnames("content/blog", rfs))
+	c.Assert(getDirnames("content/blog", rfs), qt.DeepEquals, []string{"sv-f.txt", "en-f.txt", "svdir", "en-f2.txt"})
 
-	assert.Equal([]string{"blog", "docs"}, getDirnames("content", rfsSv))
-	assert.Equal([]string{"blog", "docs"}, getDirnames("content", rfs))
+	c.Assert(getDirnames("content", rfsSv), qt.DeepEquals, []string{"blog", "docs"})
+	c.Assert(getDirnames("content", rfs), qt.DeepEquals, []string{"blog", "docs"})
 
 }
 
 func TestRootMappingFsDirnames(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	fs := NewBaseFileDecorator(afero.NewMemMapFs())
 
 	testfile := "myfile.txt"
-	assert.NoError(fs.Mkdir("f1t", 0755))
-	assert.NoError(fs.Mkdir("f2t", 0755))
-	assert.NoError(fs.Mkdir("f3t", 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("f2t", testfile), []byte("some content"), 0755))
+	c.Assert(fs.Mkdir("f1t", 0755), qt.IsNil)
+	c.Assert(fs.Mkdir("f2t", 0755), qt.IsNil)
+	c.Assert(fs.Mkdir("f3t", 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("f2t", testfile), []byte("some content"), 0755), qt.IsNil)
 
 	rfs, err := NewRootMappingFsFromFromTo(fs, "static/bf1", "f1t", "static/cf2", "f2t", "static/af3", "f3t")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	fif, err := rfs.Stat(filepath.Join("static/cf2", testfile))
-	assert.NoError(err)
-	assert.Equal("myfile.txt", fif.Name())
+	c.Assert(err, qt.IsNil)
+	c.Assert(fif.Name(), qt.Equals, "myfile.txt")
 	fifm := fif.(FileMetaInfo).Meta()
-	assert.Equal(filepath.FromSlash("f2t/myfile.txt"), fifm.Filename())
+	c.Assert(fifm.Filename(), qt.Equals, filepath.FromSlash("f2t/myfile.txt"))
 
 	root, err := rfs.Open(filepathSeparator)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	dirnames, err := root.Readdirnames(-1)
-	assert.NoError(err)
-	assert.Equal([]string{"bf1", "cf2", "af3"}, dirnames)
+	c.Assert(err, qt.IsNil)
+	c.Assert(dirnames, qt.DeepEquals, []string{"bf1", "cf2", "af3"})
 
 }
 
 func TestRootMappingFsFilename(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	workDir, clean, err := htesting.CreateTempDir(Os, "hugo-root-filename")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer clean()
 	fs := NewBaseFileDecorator(Os)
 
 	testfilename := filepath.Join(workDir, "f1t/foo/file.txt")
 
-	assert.NoError(fs.MkdirAll(filepath.Join(workDir, "f1t/foo"), 0777))
-	assert.NoError(afero.WriteFile(fs, testfilename, []byte("content"), 0666))
+	c.Assert(fs.MkdirAll(filepath.Join(workDir, "f1t/foo"), 0777), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, testfilename, []byte("content"), 0666), qt.IsNil)
 
 	rfs, err := NewRootMappingFsFromFromTo(fs, "static/f1", filepath.Join(workDir, "f1t"), "static/f2", filepath.Join(workDir, "f2t"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	fi, err := rfs.Stat(filepath.FromSlash("static/f1/foo/file.txt"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	fim := fi.(FileMetaInfo)
-	assert.Equal(testfilename, fim.Meta().Filename())
+	c.Assert(fim.Meta().Filename(), qt.Equals, testfilename)
 	_, err = rfs.Stat(filepath.FromSlash("static/f1"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 }
 
 func TestRootMappingFsMount(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	fs := NewBaseFileDecorator(afero.NewMemMapFs())
 
 	testfile := "test.txt"
 
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/a/mynoblogcontent", testfile), []byte("some no content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/a/myenblogcontent", testfile), []byte("some en content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/a/mysvblogcontent", testfile), []byte("some sv content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("themes/a/mysvblogcontent", "other.txt"), []byte("some sv content"), 0755))
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/a/mynoblogcontent", testfile), []byte("some no content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/a/myenblogcontent", testfile), []byte("some en content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/a/mysvblogcontent", testfile), []byte("some sv content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("themes/a/mysvblogcontent", "other.txt"), []byte("some sv content"), 0755), qt.IsNil)
 
 	bfs := afero.NewBasePathFs(fs, "themes/a").(*afero.BasePathFs)
 	rm := []RootMapping{
@@ -204,48 +204,48 @@
 	}
 
 	rfs, err := NewRootMappingFs(bfs, rm...)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	blog, err := rfs.Stat(filepath.FromSlash("content/blog"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	blogm := blog.(FileMetaInfo).Meta()
-	assert.Equal("sv", blogm.Lang()) // Last match
+	c.Assert(blogm.Lang(), qt.Equals, "sv") // Last match
 
 	f, err := blogm.Open()
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer f.Close()
 	dirs1, err := f.Readdirnames(-1)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	// Union with duplicate dir names filtered.
-	assert.Equal([]string{"test.txt", "test.txt", "other.txt", "test.txt"}, dirs1)
+	c.Assert(dirs1, qt.DeepEquals, []string{"test.txt", "test.txt", "other.txt", "test.txt"})
 
 	files, err := afero.ReadDir(rfs, filepath.FromSlash("content/blog"))
-	assert.NoError(err)
-	assert.Equal(4, len(files))
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(files), qt.Equals, 4)
 
 	testfilefi := files[1]
-	assert.Equal(testfile, testfilefi.Name())
+	c.Assert(testfilefi.Name(), qt.Equals, testfile)
 
 	testfilem := testfilefi.(FileMetaInfo).Meta()
-	assert.Equal(filepath.FromSlash("themes/a/mynoblogcontent/test.txt"), testfilem.Filename())
+	c.Assert(testfilem.Filename(), qt.Equals, filepath.FromSlash("themes/a/mynoblogcontent/test.txt"))
 
 	tf, err := testfilem.Open()
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer tf.Close()
-	c, err := ioutil.ReadAll(tf)
-	assert.NoError(err)
-	assert.Equal("some no content", string(c))
+	b, err := ioutil.ReadAll(tf)
+	c.Assert(err, qt.IsNil)
+	c.Assert(string(b), qt.Equals, "some no content")
 
 }
 
 func TestRootMappingFsMountOverlap(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	fs := NewBaseFileDecorator(afero.NewMemMapFs())
 
-	assert.NoError(afero.WriteFile(fs, filepath.FromSlash("da/a.txt"), []byte("some no content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.FromSlash("db/b.txt"), []byte("some no content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.FromSlash("dc/c.txt"), []byte("some no content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.FromSlash("de/e.txt"), []byte("some no content"), 0755))
+	c.Assert(afero.WriteFile(fs, filepath.FromSlash("da/a.txt"), []byte("some no content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.FromSlash("db/b.txt"), []byte("some no content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.FromSlash("dc/c.txt"), []byte("some no content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.FromSlash("de/e.txt"), []byte("some no content"), 0755), qt.IsNil)
 
 	rm := []RootMapping{
 		RootMapping{
@@ -267,56 +267,56 @@
 	}
 
 	rfs, err := NewRootMappingFs(fs, rm...)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	getDirnames := func(name string) []string {
 		name = filepath.FromSlash(name)
 		f, err := rfs.Open(name)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		defer f.Close()
 		names, err := f.Readdirnames(-1)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		return names
 	}
 
-	assert.Equal([]string{"a.txt", "b", "e"}, getDirnames("static"))
-	assert.Equal([]string{"b.txt", "c"}, getDirnames("static/b"))
-	assert.Equal([]string{"c.txt"}, getDirnames("static/b/c"))
+	c.Assert(getDirnames("static"), qt.DeepEquals, []string{"a.txt", "b", "e"})
+	c.Assert(getDirnames("static/b"), qt.DeepEquals, []string{"b.txt", "c"})
+	c.Assert(getDirnames("static/b/c"), qt.DeepEquals, []string{"c.txt"})
 
 	fi, err := rfs.Stat(filepath.FromSlash("static/b/b.txt"))
-	assert.NoError(err)
-	assert.Equal("b.txt", fi.Name())
+	c.Assert(err, qt.IsNil)
+	c.Assert(fi.Name(), qt.Equals, "b.txt")
 
 }
 
 func TestRootMappingFsOs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	fs := afero.NewOsFs()
 
 	d, err := ioutil.TempDir("", "hugo-root-mapping")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer func() {
 		os.RemoveAll(d)
 	}()
 
 	testfile := "myfile.txt"
-	assert.NoError(fs.Mkdir(filepath.Join(d, "f1t"), 0755))
-	assert.NoError(fs.Mkdir(filepath.Join(d, "f2t"), 0755))
-	assert.NoError(fs.Mkdir(filepath.Join(d, "f3t"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join(d, "f2t", testfile), []byte("some content"), 0755))
+	c.Assert(fs.Mkdir(filepath.Join(d, "f1t"), 0755), qt.IsNil)
+	c.Assert(fs.Mkdir(filepath.Join(d, "f2t"), 0755), qt.IsNil)
+	c.Assert(fs.Mkdir(filepath.Join(d, "f3t"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join(d, "f2t", testfile), []byte("some content"), 0755), qt.IsNil)
 
 	rfs, err := NewRootMappingFsFromFromTo(fs, "static/bf1", filepath.Join(d, "f1t"), "static/cf2", filepath.Join(d, "f2t"), "static/af3", filepath.Join(d, "f3t"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	fif, err := rfs.Stat(filepath.Join("static/cf2", testfile))
-	assert.NoError(err)
-	assert.Equal("myfile.txt", fif.Name())
+	c.Assert(err, qt.IsNil)
+	c.Assert(fif.Name(), qt.Equals, "myfile.txt")
 
 	root, err := rfs.Open(filepathSeparator)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	dirnames, err := root.Readdirnames(-1)
-	assert.NoError(err)
-	assert.Equal([]string{"bf1", "cf2", "af3"}, dirnames)
+	c.Assert(err, qt.IsNil)
+	c.Assert(dirnames, qt.DeepEquals, []string{"bf1", "cf2", "af3"})
 
 }
--- a/hugofs/walk_test.go
+++ b/hugofs/walk_test.go
@@ -29,11 +29,11 @@
 
 	"github.com/spf13/afero"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestWalk(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	fs := NewBaseFileDecorator(afero.NewMemMapFs())
 
@@ -43,19 +43,19 @@
 
 	names, err := collectFilenames(fs, "", "")
 
-	assert.NoError(err)
-	assert.Equal([]string{"a.txt", "b.txt", "c.txt"}, names)
+	c.Assert(err, qt.IsNil)
+	c.Assert(names, qt.DeepEquals, []string{"a.txt", "b.txt", "c.txt"})
 }
 
 func TestWalkRootMappingFs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	fs := NewBaseFileDecorator(afero.NewMemMapFs())
 
 	testfile := "test.txt"
 
-	assert.NoError(afero.WriteFile(fs, filepath.Join("a/b", testfile), []byte("some content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("c/d", testfile), []byte("some content"), 0755))
-	assert.NoError(afero.WriteFile(fs, filepath.Join("e/f", testfile), []byte("some content"), 0755))
+	c.Assert(afero.WriteFile(fs, filepath.Join("a/b", testfile), []byte("some content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("c/d", testfile), []byte("some content"), 0755), qt.IsNil)
+	c.Assert(afero.WriteFile(fs, filepath.Join("e/f", testfile), []byte("some content"), 0755), qt.IsNil)
 
 	rm := []RootMapping{
 		RootMapping{
@@ -74,13 +74,13 @@
 	}
 
 	rfs, err := NewRootMappingFs(fs, rm...)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	bfs := afero.NewBasePathFs(rfs, "static")
 
 	names, err := collectFilenames(bfs, "", "")
 
-	assert.NoError(err)
-	assert.Equal([]string{"a/test.txt", "b/test.txt", "c/test.txt"}, names)
+	c.Assert(err, qt.IsNil)
+	c.Assert(names, qt.DeepEquals, []string{"a/test.txt", "b/test.txt", "c/test.txt"})
 
 }
 
@@ -92,9 +92,9 @@
 	if skipSymlink() {
 		t.Skip("Skip; os.Symlink needs administrator rights on Windows")
 	}
-	assert := require.New(t)
+	c := qt.New(t)
 	workDir, clean, err := htesting.CreateTempDir(Os, "hugo-walk-sym")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer clean()
 	wd, _ := os.Getwd()
 	defer func() {
@@ -107,25 +107,25 @@
 	docsDir := filepath.Join(workDir, "docs")
 	blogReal := filepath.Join(blogDir, "real")
 	blogRealSub := filepath.Join(blogReal, "sub")
-	assert.NoError(os.MkdirAll(blogRealSub, 0777))
-	assert.NoError(os.MkdirAll(docsDir, 0777))
+	c.Assert(os.MkdirAll(blogRealSub, 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(docsDir, 0777), qt.IsNil)
 	afero.WriteFile(fs, filepath.Join(blogRealSub, "a.txt"), []byte("content"), 0777)
 	afero.WriteFile(fs, filepath.Join(docsDir, "b.txt"), []byte("content"), 0777)
 
 	os.Chdir(blogDir)
-	assert.NoError(os.Symlink("real", "symlinked"))
+	c.Assert(os.Symlink("real", "symlinked"), qt.IsNil)
 	os.Chdir(blogReal)
-	assert.NoError(os.Symlink("../real", "cyclic"))
+	c.Assert(os.Symlink("../real", "cyclic"), qt.IsNil)
 	os.Chdir(docsDir)
-	assert.NoError(os.Symlink("../blog/real/cyclic", "docsreal"))
+	c.Assert(os.Symlink("../blog/real/cyclic", "docsreal"), qt.IsNil)
 
 	t.Run("OS Fs", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
 		names, err := collectFilenames(fs, workDir, workDir)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
-		assert.Equal([]string{"blog/real/sub/a.txt", "docs/b.txt"}, names)
+		c.Assert(names, qt.DeepEquals, []string{"blog/real/sub/a.txt", "docs/b.txt"})
 	})
 
 	t.Run("BasePath Fs", func(t *testing.T) {
@@ -135,15 +135,15 @@
 			t.Skip("skip this for Go <= 1.11 due to a bug in Go's stdlib")
 
 		}
-		assert := require.New(t)
+		c := qt.New(t)
 
 		docsFs := afero.NewBasePathFs(fs, docsDir)
 
 		names, err := collectFilenames(docsFs, "", "")
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		// Note: the docsreal folder is considered cyclic when walking from the root, but this works.
-		assert.Equal([]string{"b.txt", "docsreal/sub/a.txt"}, names)
+		c.Assert(names, qt.DeepEquals, []string{"b.txt", "docsreal/sub/a.txt"})
 	})
 
 }
@@ -177,13 +177,13 @@
 }
 
 func BenchmarkWalk(b *testing.B) {
-	assert := require.New(b)
+	c := qt.New(b)
 	fs := NewBaseFileDecorator(afero.NewMemMapFs())
 
 	writeFiles := func(dir string, numfiles int) {
 		for i := 0; i < numfiles; i++ {
 			filename := filepath.Join(dir, fmt.Sprintf("file%d.txt", i))
-			assert.NoError(afero.WriteFile(fs, filename, []byte("content"), 0777))
+			c.Assert(afero.WriteFile(fs, filename, []byte("content"), 0777), qt.IsNil)
 		}
 	}
 
--- a/hugolib/alias_test.go
+++ b/hugolib/alias_test.go
@@ -20,7 +20,7 @@
 
 	"github.com/gohugoio/hugo/common/loggers"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 const pageWithAlias = `---
@@ -43,14 +43,14 @@
 
 func TestAlias(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	b := newTestSitesBuilder(t)
 	b.WithSimpleConfigFile().WithContent("blog/page.md", pageWithAlias)
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
-	require.Len(t, b.H.Sites[0].RegularPages(), 1)
+	c.Assert(len(b.H.Sites), qt.Equals, 1)
+	c.Assert(len(b.H.Sites[0].RegularPages()), qt.Equals, 1)
 
 	// the real page
 	b.AssertFileContent("public/blog/page/index.html", "For some moments the old man")
@@ -62,7 +62,7 @@
 func TestAliasMultipleOutputFormats(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	b := newTestSitesBuilder(t)
 	b.WithSimpleConfigFile().WithContent("blog/page.md", pageWithAliasMultipleOutputs)
@@ -82,7 +82,7 @@
 	// the alias redirectors
 	b.AssertFileContent("public/foo/bar/index.html", "<meta http-equiv=\"refresh\" content=\"0; ")
 	b.AssertFileContent("public/amp/foo/bar/index.html", "<meta http-equiv=\"refresh\" content=\"0; ")
-	assert.False(b.CheckExists("public/foo/bar/index.json"))
+	c.Assert(b.CheckExists("public/foo/bar/index.json"), qt.Equals, false)
 }
 
 func TestAliasTemplate(t *testing.T) {
--- a/hugolib/cascade_test.go
+++ b/hugolib/cascade_test.go
@@ -19,10 +19,9 @@
 	"path"
 	"testing"
 
-	"github.com/alecthomas/assert"
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/parser"
 	"github.com/gohugoio/hugo/parser/metadecoders"
-	"github.com/stretchr/testify/require"
 )
 
 func BenchmarkCascade(b *testing.B) {
@@ -31,7 +30,7 @@
 	for i := 1; i <= len(allLangs); i += 2 {
 		langs := allLangs[0:i]
 		b.Run(fmt.Sprintf("langs-%d", len(langs)), func(b *testing.B) {
-			assert := require.New(b)
+			c := qt.New(b)
 			b.StopTimer()
 			builders := make([]*sitesBuilder, b.N)
 			for i := 0; i < b.N; i++ {
@@ -42,9 +41,9 @@
 			for i := 0; i < b.N; i++ {
 				builder := builders[i]
 				err := builder.BuildE(BuildCfg{})
-				assert.NoError(err)
+				c.Assert(err, qt.IsNil)
 				first := builder.H.Sites[0]
-				assert.NotNil(first)
+				c.Assert(first, qt.Not(qt.IsNil))
 			}
 		})
 	}
@@ -51,7 +50,6 @@
 }
 
 func TestCascade(t *testing.T) {
-	assert := assert.New(t)
 
 	allLangs := []string{"en", "nn", "nb", "sv"}
 
@@ -93,7 +91,7 @@
 		// Check output formats set in cascade
 		b.AssertFileContent("public/sect4/index.xml", `<link>https://example.org/sect4/index.xml</link>`)
 		b.AssertFileContent("public/sect4/p1/index.xml", `<link>https://example.org/sect4/p1/index.xml</link>`)
-		assert.False(b.CheckExists("public/sect2/index.xml"))
+		b.C.Assert(b.CheckExists("public/sect2/index.xml"), qt.Equals, false)
 
 		// Check cascade into bundled page
 		b.AssertFileContent("public/bundle1/index.html", `Resources: bp1.md|home.png|`)
--- a/hugolib/case_insensitive_test.go
+++ b/hugolib/case_insensitive_test.go
@@ -21,9 +21,9 @@
 
 	"github.com/gohugoio/hugo/hugofs"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/spf13/afero"
-	"github.com/stretchr/testify/require"
 )
 
 var (
@@ -135,6 +135,8 @@
 func TestCaseInsensitiveConfigurationVariations(t *testing.T) {
 	t.Parallel()
 
+	c := qt.New(t)
+
 	// See issues 2615, 1129, 2590 and maybe some others
 	// Also see 2598
 	//
@@ -152,11 +154,11 @@
 	caseMixingTestsWriteCommonSources(t, mm)
 
 	cfg, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Filename: "config.toml"})
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	fs := hugofs.NewFrom(mm, cfg)
 
-	th := testHelper{cfg, fs, t}
+	th := newTestHelper(cfg, fs, t)
 
 	writeSource(t, fs, filepath.Join("layouts", "_default", "baseof.html"), `
 Block Page Colors: {{ .Params.COLOR }}|{{ .Params.Colors.Blue }}	
@@ -258,17 +260,17 @@
 }
 
 func doTestCaseInsensitiveConfigurationForTemplateEngine(t *testing.T, suffix string, templateFixer func(s string) string) {
-
+	c := qt.New(t)
 	mm := afero.NewMemMapFs()
 
 	caseMixingTestsWriteCommonSources(t, mm)
 
 	cfg, err := LoadConfigDefault(mm)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	fs := hugofs.NewFrom(mm, cfg)
 
-	th := testHelper{cfg, fs, t}
+	th := newTestHelper(cfg, fs, t)
 
 	t.Log("Testing", suffix)
 
--- a/hugolib/collections_test.go
+++ b/hugolib/collections_test.go
@@ -17,11 +17,11 @@
 	"fmt"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestGroupFunc(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	pageContent := `
 ---
@@ -39,14 +39,14 @@
 `)
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
-	require.Len(t, b.H.Sites[0].RegularPages(), 2)
+	c.Assert(len(b.H.Sites), qt.Equals, 1)
+	c.Assert(len(b.H.Sites[0].RegularPages()), qt.Equals, 2)
 
 	b.AssertFileContent("public/index.html", "cool: 2")
 }
 
 func TestSliceFunc(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	pageContent := `
 ---
@@ -78,8 +78,8 @@
 `)
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
-	require.Len(t, b.H.Sites[0].RegularPages(), 2)
+	c.Assert(len(b.H.Sites), qt.Equals, 1)
+	c.Assert(len(b.H.Sites[0].RegularPages()), qt.Equals, 2)
 
 	b.AssertFileContent("public/index.html",
 		"pages:2:page.Pages:Page(/page1.md)/Page(/page2.md)",
@@ -88,7 +88,7 @@
 }
 
 func TestUnionFunc(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	pageContent := `
 ---
@@ -110,8 +110,8 @@
 `)
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
-	require.Len(t, b.H.Sites[0].RegularPages(), 3)
+	c.Assert(len(b.H.Sites), qt.Equals, 1)
+	c.Assert(len(b.H.Sites[0].RegularPages()), qt.Equals, 3)
 
 	b.AssertFileContent("public/index.html",
 		"unionPages: page.Pages 3",
@@ -119,7 +119,7 @@
 }
 
 func TestCollectionsFuncs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	pageContent := `
 ---
@@ -151,8 +151,8 @@
 `)
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
-	require.Len(t, b.H.Sites[0].RegularPages(), 3)
+	c.Assert(len(b.H.Sites), qt.Equals, 1)
+	c.Assert(len(b.H.Sites[0].RegularPages()), qt.Equals, 3)
 
 	b.AssertFileContent("public/index.html",
 		"uniqPages: page.Pages 3",
@@ -164,7 +164,7 @@
 }
 
 func TestAppendFunc(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	pageContent := `
 ---
@@ -203,8 +203,8 @@
 `)
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
-	assert.Len(b.H.Sites[0].RegularPages(), 2)
+	c.Assert(len(b.H.Sites), qt.Equals, 1)
+	c.Assert(len(b.H.Sites[0].RegularPages()), qt.Equals, 2)
 
 	b.AssertFileContent("public/index.html",
 		"pages:2:page.Pages:Page(/page2.md)/Page(/page1.md)",
--- a/hugolib/config_test.go
+++ b/hugolib/config_test.go
@@ -19,15 +19,15 @@
 	"path/filepath"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestLoadConfig(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	// Add a random config variable for testing.
 	// side = page in Norwegian.
@@ -40,9 +40,9 @@
 	writeToFs(t, mm, "hugo.toml", configContent)
 
 	cfg, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Filename: "hugo.toml"})
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal("side", cfg.GetString("paginatePath"))
+	c.Assert(cfg.GetString("paginatePath"), qt.Equals, "side")
 
 }
 
@@ -49,7 +49,7 @@
 func TestLoadMultiConfig(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	// Add a random config variable for testing.
 	// side = page in Norwegian.
@@ -67,16 +67,16 @@
 	writeToFs(t, mm, "override.toml", configContentSub)
 
 	cfg, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Filename: "base.toml,override.toml"})
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal("top", cfg.GetString("paginatePath"))
-	assert.Equal("same", cfg.GetString("DontChange"))
+	c.Assert(cfg.GetString("paginatePath"), qt.Equals, "top")
+	c.Assert(cfg.GetString("DontChange"), qt.Equals, "same")
 }
 
 func TestLoadConfigFromTheme(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	mainConfigBasic := `
 theme = "test-theme"
@@ -291,7 +291,7 @@
 }
 `, got["menus"])
 
-	assert.Equal("https://example.com/", got["baseurl"])
+	c.Assert(got["baseurl"], qt.Equals, "https://example.com/")
 
 	if true {
 		return
@@ -314,7 +314,7 @@
   },
 }`, got["params"])
 
-	assert.Nil(got["languages"])
+	c.Assert(got["languages"], qt.IsNil)
 	b.AssertObject(`
 map[string]interface {}{
   "text/m1": map[string]interface {}{
@@ -365,7 +365,7 @@
 func TestPrivacyConfig(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tomlConfig := `
 
@@ -380,7 +380,7 @@
 	b.WithConfigFile("toml", tomlConfig)
 	b.Build(BuildCfg{SkipRender: true})
 
-	assert.True(b.H.Sites[0].Info.Config().Privacy.YouTube.PrivacyEnhanced)
+	c.Assert(b.H.Sites[0].Info.Config().Privacy.YouTube.PrivacyEnhanced, qt.Equals, true)
 
 }
 
@@ -387,7 +387,7 @@
 func TestLoadConfigModules(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	// https://github.com/gohugoio/hugoThemes#themetoml
 
@@ -469,18 +469,20 @@
 	var graphb bytes.Buffer
 	modulesClient.Graph(&graphb)
 
-	assert.Equal(`project n1
+	expected := `project n1
 n1 o1
 o1 n2
 n1 n3
 project n4
-`, graphb.String())
+`
 
+	c.Assert(graphb.String(), qt.Equals, expected)
+
 }
 
 func TestLoadConfigWithOsEnvOverrides(t *testing.T) {
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	baseConfig := `
 
@@ -512,13 +514,13 @@
 
 	cfg := b.H.Cfg
 
-	assert.Equal("test", cfg.Get("environment"))
-	assert.Equal(false, cfg.GetBool("enablegitinfo"))
-	assert.Equal("new", cfg.Get("new"))
-	assert.Equal("top", cfg.Get("imaging.anchor"))
-	assert.Equal(int64(75), cfg.Get("imaging.quality"))
-	assert.Equal([]interface{}{"c", "d"}, cfg.Get("stringSlice"))
-	assert.Equal([]interface{}{5.32}, cfg.Get("floatSlice"))
-	assert.Equal([]interface{}{5, 8, 9}, cfg.Get("intSlice"))
+	c.Assert(cfg.Get("environment"), qt.Equals, "test")
+	c.Assert(cfg.GetBool("enablegitinfo"), qt.Equals, false)
+	c.Assert(cfg.Get("new"), qt.Equals, "new")
+	c.Assert(cfg.Get("imaging.anchor"), qt.Equals, "top")
+	c.Assert(cfg.Get("imaging.quality"), qt.Equals, int64(75))
+	c.Assert(cfg.Get("stringSlice"), qt.DeepEquals, []interface{}{"c", "d"})
+	c.Assert(cfg.Get("floatSlice"), qt.DeepEquals, []interface{}{5.32})
+	c.Assert(cfg.Get("intSlice"), qt.DeepEquals, []interface{}{5, 8, 9})
 
 }
--- a/hugolib/configdir_test.go
+++ b/hugolib/configdir_test.go
@@ -19,15 +19,15 @@
 
 	"github.com/gohugoio/hugo/common/herrors"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/htesting"
 	"github.com/spf13/afero"
-	"github.com/stretchr/testify/require"
 )
 
 func TestLoadConfigDir(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	configContent := `
 baseURL = "https://example.org"
@@ -107,22 +107,22 @@
 	fb.Build()
 
 	cfg, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Environment: "development", Filename: "hugo.toml", AbsConfigDir: "config"})
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal("pag_development", cfg.GetString("paginatePath")) // /config/development/config.toml
+	c.Assert(cfg.GetString("paginatePath"), qt.Equals, "pag_development") // /config/development/config.toml
 
-	assert.Equal(10, cfg.GetInt("languages.no.weight"))                          //  /config.toml
-	assert.Equal("Norsk_no_default", cfg.GetString("languages.no.languageName")) // /config/_default/languages.no.toml
+	c.Assert(cfg.GetInt("languages.no.weight"), qt.Equals, 10)                          //  /config.toml
+	c.Assert(cfg.GetString("languages.no.languageName"), qt.Equals, "Norsk_no_default") // /config/_default/languages.no.toml
 
-	assert.Equal("p1_base", cfg.GetString("params.p1"))
-	assert.Equal("p2params_default", cfg.GetString("params.p2")) // Is in both _default and production
-	assert.Equal("p3params_development", cfg.GetString("params.p3"))
-	assert.Equal("p3params_no_development", cfg.GetString("languages.no.params.p3"))
+	c.Assert(cfg.GetString("params.p1"), qt.Equals, "p1_base")
+	c.Assert(cfg.GetString("params.p2"), qt.Equals, "p2params_default") // Is in both _default and production
+	c.Assert(cfg.GetString("params.p3"), qt.Equals, "p3params_development")
+	c.Assert(cfg.GetString("languages.no.params.p3"), qt.Equals, "p3params_no_development")
 
-	assert.Equal(2, len(cfg.Get("menus.docs").(([]map[string]interface{}))))
+	c.Assert(len(cfg.Get("menus.docs").(([]map[string]interface{}))), qt.Equals, 2)
 	noMenus := cfg.Get("languages.no.menus.docs")
-	assert.NotNil(noMenus)
-	assert.Equal(1, len(noMenus.(([]map[string]interface{}))))
+	c.Assert(noMenus, qt.Not(qt.IsNil))
+	c.Assert(len(noMenus.(([]map[string]interface{}))), qt.Equals, 1)
 
 }
 
@@ -129,7 +129,7 @@
 func TestLoadConfigDirError(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	configContent := `
 baseURL = "https://example.org"
@@ -145,10 +145,10 @@
 	fb.Add("config.toml", `invalid & syntax`).Build()
 
 	_, _, err := LoadConfig(ConfigSourceDescriptor{Fs: mm, Environment: "development", Filename: "hugo.toml", AbsConfigDir: "config"})
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	fe := herrors.UnwrapErrorWithFileContext(err)
-	assert.NotNil(fe)
-	assert.Equal(filepath.FromSlash("config/development/config.toml"), fe.Position().Filename)
+	c.Assert(fe, qt.Not(qt.IsNil))
+	c.Assert(fe.Position().Filename, qt.Equals, filepath.FromSlash("config/development/config.toml"))
 
 }
--- a/hugolib/datafiles_test.go
+++ b/hugolib/datafiles_test.go
@@ -16,7 +16,6 @@
 import (
 	"path/filepath"
 	"reflect"
-	"strings"
 	"testing"
 
 	"github.com/gohugoio/hugo/common/loggers"
@@ -26,7 +25,7 @@
 	"fmt"
 	"runtime"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestDataDir(t *testing.T) {
@@ -377,6 +376,7 @@
 
 	var (
 		cfg, fs = newTestCfg()
+		c       = qt.New(t)
 	)
 
 	writeSource(t, fs, "data/hugo.toml", "slogan = \"Hugo Rocks!\"")
@@ -392,7 +392,7 @@
 	buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
 
 	content := readSource(t, fs, "public/c/index.html")
-	require.True(t, strings.Contains(content, "Slogan from template: Hugo Rocks!"), content)
-	require.True(t, strings.Contains(content, "Slogan from shortcode: Hugo Rocks!"), content)
 
+	c.Assert(content, qt.Contains, "Slogan from template: Hugo Rocks!")
+	c.Assert(content, qt.Contains, "Slogan from shortcode: Hugo Rocks!")
 }
--- a/hugolib/disableKinds_test.go
+++ b/hugolib/disableKinds_test.go
@@ -18,10 +18,10 @@
 
 	"fmt"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/resources/page"
 
 	"github.com/gohugoio/hugo/helpers"
-	"github.com/stretchr/testify/require"
 )
 
 func TestDisableKindsNoneDisabled(t *testing.T) {
@@ -104,8 +104,6 @@
 	b.Build(BuildCfg{})
 	h := b.H
 
-	require.Len(t, h.Sites, 1)
-
 	assertDisabledKinds(b, h.Sites[0], disabled...)
 
 }
@@ -181,7 +179,7 @@
 
 func assertDisabledKind(b *sitesBuilder, kindAssert func(bool) bool, disabled []string, kind, path, matcher string) {
 	isDisabled := stringSliceContains(kind, disabled...)
-	require.True(b.T, kindAssert(isDisabled), fmt.Sprintf("%s: %t", kind, isDisabled))
+	b.Assert(kindAssert(isDisabled), qt.Equals, true)
 
 	if kind == kindRSS && !isDisabled {
 		// If the home page is also disabled, there is not RSS to look for.
@@ -193,8 +191,8 @@
 	if isDisabled {
 		// Path should not exist
 		fileExists, err := helpers.Exists(path, b.Fs.Destination)
-		require.False(b.T, fileExists)
-		require.NoError(b.T, err)
+		b.Assert(err, qt.IsNil)
+		b.Assert(fileExists, qt.Equals, false)
 
 	} else {
 		b.AssertFileContent(path, matcher)
--- a/hugolib/embedded_shortcodes_test.go
+++ b/hugolib/embedded_shortcodes_test.go
@@ -26,8 +26,8 @@
 
 	"github.com/gohugoio/hugo/deps"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/tpl"
-	"github.com/stretchr/testify/require"
 )
 
 const (
@@ -45,6 +45,7 @@
 func doTestShortcodeCrossrefs(t *testing.T, relative bool) {
 	var (
 		cfg, fs = newTestCfg()
+		c       = qt.New(t)
 	)
 
 	cfg.Set("baseURL", testBaseURL)
@@ -69,10 +70,10 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
 
-	require.Len(t, s.RegularPages(), 1)
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	content, err := s.RegularPages()[0].Content()
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 	output := cast.ToString(content)
 
 	if !strings.Contains(output, expected) {
@@ -100,7 +101,7 @@
 
 		var (
 			cfg, fs = newTestCfg()
-			th      = testHelper{cfg, fs, t}
+			th      = newTestHelper(cfg, fs, t)
 		)
 
 		cfg.Set("pygmentsStyle", "bw")
@@ -148,7 +149,7 @@
 
 		var (
 			cfg, fs = newTestCfg()
-			th      = testHelper{cfg, fs, t}
+			th      = newTestHelper(cfg, fs, t)
 		)
 
 		writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`---
@@ -187,7 +188,7 @@
 	} {
 		var (
 			cfg, fs = newTestCfg()
-			th      = testHelper{cfg, fs, t}
+			th      = newTestHelper(cfg, fs, t)
 		)
 
 		writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`---
@@ -226,7 +227,7 @@
 	} {
 		var (
 			cfg, fs = newTestCfg()
-			th      = testHelper{cfg, fs, t}
+			th      = newTestHelper(cfg, fs, t)
 		)
 
 		writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`---
@@ -259,7 +260,7 @@
 	} {
 		var (
 			cfg, fs = newTestCfg()
-			th      = testHelper{cfg, fs, t}
+			th      = newTestHelper(cfg, fs, t)
 		)
 
 		writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`---
@@ -302,7 +303,7 @@
 
 		var (
 			cfg, fs = newTestCfg()
-			th      = testHelper{cfg, fs, t}
+			th      = newTestHelper(cfg, fs, t)
 		)
 
 		withTemplate := func(templ tpl.TemplateHandler) error {
@@ -357,7 +358,7 @@
 14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\"\u003e\u003ca href=\"https://www.instagram.com/p/BMokmydjG-M/\" style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;\" target=\"_blank\"\u003eA photo posted by Instagram (@instagram)\u003c/a\u003e on \u003ctime style=\" font-family:Arial,sans-serif; font-size:14px; line-height:17px;\" datetime=\"2016-11-10T15:02:28+00:00\"\u003eNov 10, 2016 at 7:02am PST\u003c/time\u003e\u003c/p\u003e\u003c/div\u003e\u003c/blockquote\u003e\n\u003cscript async defer src=\"//platform.instagram.com/en_US/embeds.js\"\u003e\u003c/script\u003e", "width": 658, "version": "1.0", "author_url": "https://www.instagram.com/instagram", "author_id": 25025320, "type": "rich"}`,
 			`(?s)<blockquote class="instagram-media" data-instgrm-version="7" style=" background:#FFF; border:0; .*<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>`,
 		},
-om:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\"\u003e\u003ca href=\"https://www.instagram.com/p/BMokmydjG-M/\" style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;\" target=\"_blank\"\u003eA photo posted by Instagram (@instagram)\u003c/a\u003e on \u003ctime style=\" font-family:Arial,sans-serif; font-size:14px; line-height:17px;\" datetime=\"2016-11-10T15:02:28+00:00\"\u003eNov 10, 2016 at 7:02am PST\u003c/time\u003e\u003c/p\u003e\u003c/div\u003e\u003c/blockquote\u003e\n\u003cscript async defer src=\"//platform.instagram.com/en_US/embeds.js\"\u003e\u003c/script\u003e", "width": 658, "version": "1.0", "author_url": "https://www.instagram.com/instagram", "author_id": 25025320, "type": "rich"}`,
+om:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\"\u003e\u003ca href=\"https://www.instagram.com/p/BMokmydjG-M/\" style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;\" target=\"_blank\"\u003eA photo posted by Instagram (@instagram)\u003c/a\u003e on \u003ctime style=\" font-family:Arial,sans-serif; font-size:14px; line-height:17px;\" datetime=\"2016-11-10T15:02:28+00:00\"\u003eNov 10, 2016 at 7:02am PST\u003c/time\u003e\u003c/p\u003e\u003c/div\u003e\u003c/blockquote\u003e\n\u003cscript async defer src=\"//platform.instagram.com/en_US/embeds.js\"\u003e\u003c/script\u003e", "width": 658, "version": "1.0", "author_url": "https://www.instagram.com/instagram", "author_id": 25025320, "type": "rich"}`,
 n; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\"\u003e\u003ca href=\"https://www.instagram.com/p/BMokmydjG-M/\" style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;\" target=\"_blank\"\u003eA photo posted by Instagram (@instagram)\u003c/a\u003e on \u003ctime style=\" font-family:Arial,sans-serif; font-size:14px; line-height:17px;\" datetime=\"2016-11-10T15:02:28+00:00\"\u003eNov 10, 2016 at 7:02am PST\u003c/time\u003e\u003c/p\u003e\u003c/div\u003e\u003c/blockquote\u003e\n\u003cscript async defer src=\"//platform.instagram.com/en_US/embeds.js\"\u003e\u003c/script\u003e", "width": 658, "version": "1.0", "author_url": "https://www.instagram.com/instagram", "author_id": 25025320, "type": "rich"}`,
 			`(?s)<blockquote class="instagram-media" data-instgrm-version="7" style=" background:#FFF; border:0; .*<script async defer src="//platform.instagram.com/en_US/embeds.js"></script>`,
 		},
--- a/hugolib/embedded_templates_test.go
+++ b/hugolib/embedded_templates_test.go
@@ -16,7 +16,7 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 // Just some simple test of the embedded templates to avoid
@@ -25,8 +25,8 @@
 func _TestEmbeddedTemplates(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
-	assert.True(true)
+	c := qt.New(t)
+	c.Assert(true, qt.Equals, true)
 
 	home := []string{"index.html", `
 GA:
--- a/hugolib/fileInfo_test.go
+++ b/hugolib/fileInfo_test.go
@@ -16,16 +16,16 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/cast"
-	"github.com/stretchr/testify/require"
 )
 
 func TestFileInfo(t *testing.T) {
 	t.Run("String", func(t *testing.T) {
 		t.Parallel()
-		assert := require.New(t)
+		c := qt.New(t)
 		fi := &fileInfo{}
 		_, err := cast.ToStringE(fi)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 	})
 }
--- a/hugolib/filesystems/basefs_test.go
+++ b/hugolib/filesystems/basefs_test.go
@@ -27,11 +27,11 @@
 
 	"github.com/spf13/afero"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/gohugoio/hugo/hugolib/paths"
 	"github.com/gohugoio/hugo/modules"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func initConfig(fs afero.Fs, cfg config.Provider) error {
@@ -72,7 +72,7 @@
 }
 
 func TestNewBaseFs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	v := viper.New()
 
 	fs := hugofs.NewMem(v)
@@ -119,54 +119,52 @@
 	setConfigAndWriteSomeFilesTo(fs.Source, v, "resourceDir", "myrsesource", 10)
 
 	v.Set("publishDir", "public")
-	assert.NoError(initConfig(fs.Source, v))
+	c.Assert(initConfig(fs.Source, v), qt.IsNil)
 
 	p, err := paths.New(fs, v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	bfs, err := NewBase(p, nil)
-	assert.NoError(err)
-	assert.NotNil(bfs)
+	c.Assert(err, qt.IsNil)
+	c.Assert(bfs, qt.Not(qt.IsNil))
 
 	root, err := bfs.I18n.Fs.Open("")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	dirnames, err := root.Readdirnames(-1)
-	assert.NoError(err)
-	assert.Equal([]string{"f1.txt", "f2.txt", "f3.txt", "f4.txt", "f3.txt", "theme-file-btheme.txt", "f3.txt", "theme-file-atheme.txt"}, dirnames)
+	c.Assert(err, qt.IsNil)
+	c.Assert(dirnames, qt.DeepEquals, []string{"f1.txt", "f2.txt", "f3.txt", "f4.txt", "f3.txt", "theme-file-btheme.txt", "f3.txt", "theme-file-atheme.txt"})
 
 	root, err = bfs.Data.Fs.Open("")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	dirnames, err = root.Readdirnames(-1)
-	assert.NoError(err)
-	assert.Equal([]string{"f1.txt", "f2.txt", "f3.txt", "f4.txt", "f5.txt", "f6.txt", "f7.txt", "f3.txt", "theme-file-btheme.txt", "f3.txt", "theme-file-atheme.txt"}, dirnames)
+	c.Assert(err, qt.IsNil)
+	c.Assert(dirnames, qt.DeepEquals, []string{"f1.txt", "f2.txt", "f3.txt", "f4.txt", "f5.txt", "f6.txt", "f7.txt", "f3.txt", "theme-file-btheme.txt", "f3.txt", "theme-file-atheme.txt"})
 
-	//printFs(bfs.Work, "", os.Stdout)
+	checkFileCount(bfs.Layouts.Fs, "", c, 7)
 
-	checkFileCount(bfs.Layouts.Fs, "", assert, 7)
+	checkFileCount(bfs.Content.Fs, "", c, 3)
+	checkFileCount(bfs.I18n.Fs, "", c, 8) // 4 + 4 themes
 
-	checkFileCount(bfs.Content.Fs, "", assert, 3)
-	checkFileCount(bfs.I18n.Fs, "", assert, 8) // 4 + 4 themes
+	checkFileCount(bfs.Static[""].Fs, "", c, 6)
+	checkFileCount(bfs.Data.Fs, "", c, 11)       // 7 + 4 themes
+	checkFileCount(bfs.Archetypes.Fs, "", c, 10) // 8 + 2 themes
+	checkFileCount(bfs.Assets.Fs, "", c, 9)
+	checkFileCount(bfs.Work, "", c, 82)
 
-	checkFileCount(bfs.Static[""].Fs, "", assert, 6)
-	checkFileCount(bfs.Data.Fs, "", assert, 11)       // 7 + 4 themes
-	checkFileCount(bfs.Archetypes.Fs, "", assert, 10) // 8 + 2 themes
-	checkFileCount(bfs.Assets.Fs, "", assert, 9)
-	checkFileCount(bfs.Work, "", assert, 82)
+	c.Assert(bfs.IsData(filepath.Join(workingDir, "mydata", "file1.txt")), qt.Equals, true)
+	c.Assert(bfs.IsI18n(filepath.Join(workingDir, "myi18n", "file1.txt")), qt.Equals, true)
+	c.Assert(bfs.IsLayout(filepath.Join(workingDir, "mylayouts", "file1.txt")), qt.Equals, true)
+	c.Assert(bfs.IsStatic(filepath.Join(workingDir, "mystatic", "file1.txt")), qt.Equals, true)
+	c.Assert(bfs.IsAsset(filepath.Join(workingDir, "myassets", "file1.txt")), qt.Equals, true)
 
-	assert.True(bfs.IsData(filepath.Join(workingDir, "mydata", "file1.txt")))
-	assert.True(bfs.IsI18n(filepath.Join(workingDir, "myi18n", "file1.txt")))
-	assert.True(bfs.IsLayout(filepath.Join(workingDir, "mylayouts", "file1.txt")))
-	assert.True(bfs.IsStatic(filepath.Join(workingDir, "mystatic", "file1.txt")))
-	assert.True(bfs.IsAsset(filepath.Join(workingDir, "myassets", "file1.txt")))
-
 	contentFilename := filepath.Join(workingDir, "mycontent", "file1.txt")
-	assert.True(bfs.IsContent(contentFilename))
+	c.Assert(bfs.IsContent(contentFilename), qt.Equals, true)
 	rel := bfs.RelContentDir(contentFilename)
-	assert.Equal("file1.txt", rel)
+	c.Assert(rel, qt.Equals, "file1.txt")
 
 	// Check Work fs vs theme
-	checkFileContent(bfs.Work, "file-root.txt", assert, "content-project")
-	checkFileContent(bfs.Work, "theme-root-atheme.txt", assert, "content:atheme")
+	checkFileContent(bfs.Work, "file-root.txt", c, "content-project")
+	checkFileContent(bfs.Work, "theme-root-atheme.txt", c, "content:atheme")
 
 	// https://github.com/gohugoio/hugo/issues/5318
 	// Check both project and theme.
@@ -174,10 +172,10 @@
 		for _, filename := range []string{"/f1.txt", "/theme-file-atheme.txt"} {
 			filename = filepath.FromSlash(filename)
 			f, err := fs.Open(filename)
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 			name := f.Name()
 			f.Close()
-			assert.Equal(filename, name)
+			c.Assert(name, qt.Equals, filename)
 		}
 	}
 }
@@ -199,35 +197,35 @@
 }
 
 func TestNewBaseFsEmpty(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	v := createConfig()
 	fs := hugofs.NewMem(v)
-	assert.NoError(initConfig(fs.Source, v))
+	c.Assert(initConfig(fs.Source, v), qt.IsNil)
 
 	p, err := paths.New(fs, v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	bfs, err := NewBase(p, nil)
-	assert.NoError(err)
-	assert.NotNil(bfs)
-	assert.NotNil(bfs.Archetypes.Fs)
-	assert.NotNil(bfs.Layouts.Fs)
-	assert.NotNil(bfs.Data.Fs)
-	assert.NotNil(bfs.I18n.Fs)
-	assert.NotNil(bfs.Work)
-	assert.NotNil(bfs.Content.Fs)
-	assert.NotNil(bfs.Static)
+	c.Assert(err, qt.IsNil)
+	c.Assert(bfs, qt.Not(qt.IsNil))
+	c.Assert(bfs.Archetypes.Fs, qt.Not(qt.IsNil))
+	c.Assert(bfs.Layouts.Fs, qt.Not(qt.IsNil))
+	c.Assert(bfs.Data.Fs, qt.Not(qt.IsNil))
+	c.Assert(bfs.I18n.Fs, qt.Not(qt.IsNil))
+	c.Assert(bfs.Work, qt.Not(qt.IsNil))
+	c.Assert(bfs.Content.Fs, qt.Not(qt.IsNil))
+	c.Assert(bfs.Static, qt.Not(qt.IsNil))
 }
 
 func TestRealDirs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	v := createConfig()
 	fs := hugofs.NewDefault(v)
 	sfs := fs.Source
 
 	root, err := afero.TempDir(sfs, "", "realdir")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	themesDir, err := afero.TempDir(sfs, "", "themesDir")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer func() {
 		os.RemoveAll(root)
 		os.RemoveAll(themesDir)
@@ -237,14 +235,14 @@
 	v.Set("themesDir", themesDir)
 	v.Set("theme", "mytheme")
 
-	assert.NoError(sfs.MkdirAll(filepath.Join(root, "myassets", "scss", "sf1"), 0755))
-	assert.NoError(sfs.MkdirAll(filepath.Join(root, "myassets", "scss", "sf2"), 0755))
-	assert.NoError(sfs.MkdirAll(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf2"), 0755))
-	assert.NoError(sfs.MkdirAll(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf3"), 0755))
-	assert.NoError(sfs.MkdirAll(filepath.Join(root, "resources"), 0755))
-	assert.NoError(sfs.MkdirAll(filepath.Join(themesDir, "mytheme", "resources"), 0755))
+	c.Assert(sfs.MkdirAll(filepath.Join(root, "myassets", "scss", "sf1"), 0755), qt.IsNil)
+	c.Assert(sfs.MkdirAll(filepath.Join(root, "myassets", "scss", "sf2"), 0755), qt.IsNil)
+	c.Assert(sfs.MkdirAll(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf2"), 0755), qt.IsNil)
+	c.Assert(sfs.MkdirAll(filepath.Join(themesDir, "mytheme", "assets", "scss", "sf3"), 0755), qt.IsNil)
+	c.Assert(sfs.MkdirAll(filepath.Join(root, "resources"), 0755), qt.IsNil)
+	c.Assert(sfs.MkdirAll(filepath.Join(themesDir, "mytheme", "resources"), 0755), qt.IsNil)
 
-	assert.NoError(sfs.MkdirAll(filepath.Join(root, "myassets", "js", "f2"), 0755))
+	c.Assert(sfs.MkdirAll(filepath.Join(root, "myassets", "js", "f2"), 0755), qt.IsNil)
 
 	afero.WriteFile(sfs, filepath.Join(filepath.Join(root, "myassets", "scss", "sf1", "a1.scss")), []byte("content"), 0755)
 	afero.WriteFile(sfs, filepath.Join(filepath.Join(root, "myassets", "scss", "sf2", "a3.scss")), []byte("content"), 0755)
@@ -259,27 +257,27 @@
 	afero.WriteFile(sfs, filepath.Join(filepath.Join(root, "myassets", "js", "f2", "a1.js")), []byte("content"), 0755)
 	afero.WriteFile(sfs, filepath.Join(filepath.Join(root, "myassets", "js", "a2.js")), []byte("content"), 0755)
 
-	assert.NoError(initConfig(fs.Source, v))
+	c.Assert(initConfig(fs.Source, v), qt.IsNil)
 
 	p, err := paths.New(fs, v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	bfs, err := NewBase(p, nil)
-	assert.NoError(err)
-	assert.NotNil(bfs)
+	c.Assert(err, qt.IsNil)
+	c.Assert(bfs, qt.Not(qt.IsNil))
 
-	checkFileCount(bfs.Assets.Fs, "", assert, 6)
+	checkFileCount(bfs.Assets.Fs, "", c, 6)
 
 	realDirs := bfs.Assets.RealDirs("scss")
-	assert.Equal(2, len(realDirs))
-	assert.Equal(filepath.Join(root, "myassets/scss"), realDirs[0])
-	assert.Equal(filepath.Join(themesDir, "mytheme/assets/scss"), realDirs[len(realDirs)-1])
+	c.Assert(len(realDirs), qt.Equals, 2)
+	c.Assert(realDirs[0], qt.Equals, filepath.Join(root, "myassets/scss"))
+	c.Assert(realDirs[len(realDirs)-1], qt.Equals, filepath.Join(themesDir, "mytheme/assets/scss"))
 
-	assert.NotNil(bfs.theBigFs)
+	c.Assert(bfs.theBigFs, qt.Not(qt.IsNil))
 
 }
 
 func TestStaticFs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	v := createConfig()
 	workDir := "mywork"
 	v.Set("workingDir", workDir)
@@ -296,21 +294,21 @@
 	afero.WriteFile(fs.Source, filepath.Join(themeStaticDir, "f2.txt"), []byte("Hugo Themes Still Rocks!"), 0755)
 	afero.WriteFile(fs.Source, filepath.Join(themeStaticDir2, "f2.txt"), []byte("Hugo Themes Rocks in t2!"), 0755)
 
-	assert.NoError(initConfig(fs.Source, v))
+	c.Assert(initConfig(fs.Source, v), qt.IsNil)
 
 	p, err := paths.New(fs, v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	bfs, err := NewBase(p, nil)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	sfs := bfs.StaticFs("en")
-	checkFileContent(sfs, "f1.txt", assert, "Hugo Rocks!")
-	checkFileContent(sfs, "f2.txt", assert, "Hugo Themes Still Rocks!")
+	checkFileContent(sfs, "f1.txt", c, "Hugo Rocks!")
+	checkFileContent(sfs, "f2.txt", c, "Hugo Themes Still Rocks!")
 
 }
 
 func TestStaticFsMultiHost(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	v := createConfig()
 	workDir := "mywork"
 	v.Set("workingDir", workDir)
@@ -340,30 +338,30 @@
 	afero.WriteFile(fs.Source, filepath.Join(themeStaticDir, "f1.txt"), []byte("Hugo Themes Rocks!"), 0755)
 	afero.WriteFile(fs.Source, filepath.Join(themeStaticDir, "f2.txt"), []byte("Hugo Themes Still Rocks!"), 0755)
 
-	assert.NoError(initConfig(fs.Source, v))
+	c.Assert(initConfig(fs.Source, v), qt.IsNil)
 
 	p, err := paths.New(fs, v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	bfs, err := NewBase(p, nil)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	enFs := bfs.StaticFs("en")
-	checkFileContent(enFs, "f1.txt", assert, "Hugo Rocks!")
-	checkFileContent(enFs, "f2.txt", assert, "Hugo Themes Still Rocks!")
+	checkFileContent(enFs, "f1.txt", c, "Hugo Rocks!")
+	checkFileContent(enFs, "f2.txt", c, "Hugo Themes Still Rocks!")
 
 	noFs := bfs.StaticFs("no")
-	checkFileContent(noFs, "f1.txt", assert, "Hugo Rocks in Norway!")
-	checkFileContent(noFs, "f2.txt", assert, "Hugo Themes Still Rocks!")
+	checkFileContent(noFs, "f1.txt", c, "Hugo Rocks in Norway!")
+	checkFileContent(noFs, "f2.txt", c, "Hugo Themes Still Rocks!")
 }
 
 func TestMakePathRelative(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	v := createConfig()
 	fs := hugofs.NewMem(v)
 	workDir := "mywork"
 	v.Set("workingDir", workDir)
 
-	assert.NoError(fs.Source.MkdirAll(filepath.Join(workDir, "dist"), 0777))
-	assert.NoError(fs.Source.MkdirAll(filepath.Join(workDir, "static"), 0777))
+	c.Assert(fs.Source.MkdirAll(filepath.Join(workDir, "dist"), 0777), qt.IsNil)
+	c.Assert(fs.Source.MkdirAll(filepath.Join(workDir, "static"), 0777), qt.IsNil)
 
 	moduleCfg := map[string]interface{}{
 		"mounts": []interface{}{
@@ -380,35 +378,35 @@
 
 	v.Set("module", moduleCfg)
 
-	assert.NoError(initConfig(fs.Source, v))
+	c.Assert(initConfig(fs.Source, v), qt.IsNil)
 
 	p, err := paths.New(fs, v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	bfs, err := NewBase(p, nil)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	sfs := bfs.Static[""]
-	assert.NotNil(sfs)
+	c.Assert(sfs, qt.Not(qt.IsNil))
 
-	assert.Equal(filepath.FromSlash("/foo.txt"), sfs.MakePathRelative(filepath.Join(workDir, "static", "foo.txt")))
-	assert.Equal(filepath.FromSlash("/dist/foo.txt"), sfs.MakePathRelative(filepath.Join(workDir, "dist", "foo.txt")))
+	c.Assert(sfs.MakePathRelative(filepath.Join(workDir, "static", "foo.txt")), qt.Equals, filepath.FromSlash("/foo.txt"))
+	c.Assert(sfs.MakePathRelative(filepath.Join(workDir, "dist", "foo.txt")), qt.Equals, filepath.FromSlash("/dist/foo.txt"))
 }
 
-func checkFileCount(fs afero.Fs, dirname string, assert *require.Assertions, expected int) {
-	count, fnames, err := countFileaAndGetFilenames(fs, dirname)
-	assert.NoError(err, fnames)
-	assert.Equal(expected, count, fnames)
+func checkFileCount(fs afero.Fs, dirname string, c *qt.C, expected int) {
+	count, _, err := countFileaAndGetFilenames(fs, dirname)
+	c.Assert(err, qt.IsNil)
+	c.Assert(count, qt.Equals, expected)
 }
 
-func checkFileContent(fs afero.Fs, filename string, assert *require.Assertions, expected ...string) {
+func checkFileContent(fs afero.Fs, filename string, c *qt.C, expected ...string) {
 
 	b, err := afero.ReadFile(fs, filename)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	content := string(b)
 
 	for _, e := range expected {
-		assert.Contains(content, e)
+		c.Assert(content, qt.Contains, e)
 	}
 }
 
--- a/hugolib/hugo_modules_test.go
+++ b/hugolib/hugo_modules_test.go
@@ -33,9 +33,9 @@
 	"github.com/gohugoio/hugo/htesting"
 	"github.com/gohugoio/hugo/hugofs"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/testmodBuilder/mods"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 // TODO(bep) this fails when testmodBuilder is also building ...
@@ -60,12 +60,12 @@
 	rnd.Shuffle(len(testmods), func(i, j int) { testmods[i], testmods[j] = testmods[j], testmods[i] })
 
 	for _, m := range testmods[:2] {
-		assert := require.New(t)
+		c := qt.New(t)
 
 		v := viper.New()
 
 		workingDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-modules-test")
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		defer clean()
 
 		configTemplate := `
@@ -375,9 +375,9 @@
 
 	b.Build(BuildCfg{})
 
-	assert := require.New(t)
+	c := qt.New(t)
 
-	assert.Equal(uint64(2), logger.WarnCounter.Count())
+	c.Assert(logger.WarnCounter.Count(), qt.Equals, uint64(2))
 
 }
 
@@ -389,13 +389,13 @@
 		os.Chdir(wd)
 	}()
 
-	assert := require.New(t)
+	c := qt.New(t)
 	// We need to use the OS fs for this.
 	cfg := viper.New()
 	fs := hugofs.NewFrom(hugofs.Os, cfg)
 
 	workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-mod-sym")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	defer clean()
 
@@ -406,11 +406,11 @@
 	createDirsAndFiles := func(baseDir string) {
 		for _, dir := range files.ComponentFolders {
 			realDir := filepath.Join(baseDir, dir, "real")
-			assert.NoError(os.MkdirAll(realDir, 0777))
-			assert.NoError(afero.WriteFile(fs.Source, filepath.Join(realDir, "data.toml"), []byte("[hello]\nother = \"hello\""), 0777))
+			c.Assert(os.MkdirAll(realDir, 0777), qt.IsNil)
+			c.Assert(afero.WriteFile(fs.Source, filepath.Join(realDir, "data.toml"), []byte("[hello]\nother = \"hello\""), 0777), qt.IsNil)
 		}
 
-		assert.NoError(afero.WriteFile(fs.Source, filepath.Join(baseDir, "layouts", "index.html"), []byte(homeTemplate), 0777))
+		c.Assert(afero.WriteFile(fs.Source, filepath.Join(baseDir, "layouts", "index.html"), []byte(homeTemplate), 0777), qt.IsNil)
 	}
 
 	// Create project dirs and files.
@@ -421,10 +421,10 @@
 
 	createSymlinks := func(baseDir, id string) {
 		for _, dir := range files.ComponentFolders {
-			assert.NoError(os.Chdir(filepath.Join(baseDir, dir)))
-			assert.NoError(os.Symlink("real", fmt.Sprintf("realsym%s", id)))
-			assert.NoError(os.Chdir(filepath.Join(baseDir, dir, "real")))
-			assert.NoError(os.Symlink("data.toml", fmt.Sprintf(filepath.FromSlash("datasym%s.toml"), id)))
+			c.Assert(os.Chdir(filepath.Join(baseDir, dir)), qt.IsNil)
+			c.Assert(os.Symlink("real", fmt.Sprintf("realsym%s", id)), qt.IsNil)
+			c.Assert(os.Chdir(filepath.Join(baseDir, dir, "real")), qt.IsNil)
+			c.Assert(os.Symlink("data.toml", fmt.Sprintf(filepath.FromSlash("datasym%s.toml"), id)), qt.IsNil)
 		}
 	}
 
@@ -451,7 +451,7 @@
 	b.Fs = fs
 
 	b.WithConfigFile("toml", config)
-	assert.NoError(os.Chdir(workDir))
+	c.Assert(os.Chdir(workDir), qt.IsNil)
 
 	b.Build(BuildCfg{})
 
@@ -493,10 +493,10 @@
 				}
 
 				if shouldFail {
-					assert.Error(err)
-					assert.Equal(hugofs.ErrPermissionSymlink, err, filename)
+					c.Assert(err, qt.Not(qt.IsNil))
+					c.Assert(err, qt.Equals, hugofs.ErrPermissionSymlink)
 				} else {
-					assert.NoError(err, filename)
+					c.Assert(err, qt.IsNil)
 				}
 			}
 
--- a/hugolib/hugo_sites_build_errors_test.go
+++ b/hugolib/hugo_sites_build_errors_test.go
@@ -11,31 +11,31 @@
 
 	"github.com/fortytw2/leaktest"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/herrors"
-	"github.com/stretchr/testify/require"
 )
 
 type testSiteBuildErrorAsserter struct {
-	name   string
-	assert *require.Assertions
+	name string
+	c    *qt.C
 }
 
 func (t testSiteBuildErrorAsserter) getFileError(err error) *herrors.ErrorWithFileContext {
-	t.assert.NotNil(err, t.name)
+	t.c.Assert(err, qt.Not(qt.IsNil), qt.Commentf(t.name))
 	ferr := herrors.UnwrapErrorWithFileContext(err)
-	t.assert.NotNil(ferr, fmt.Sprintf("[%s] got %T: %+v\n%s", t.name, err, err, stackTrace()))
+	t.c.Assert(ferr, qt.Not(qt.IsNil))
 	return ferr
 }
 
 func (t testSiteBuildErrorAsserter) assertLineNumber(lineNumber int, err error) {
 	fe := t.getFileError(err)
-	t.assert.Equal(lineNumber, fe.Position().LineNumber, fmt.Sprintf("[%s]  got => %s\n%s", t.name, fe, stackTrace()))
+	t.c.Assert(fe.Position().LineNumber, qt.Equals, lineNumber)
 }
 
 func (t testSiteBuildErrorAsserter) assertErrorMessage(e1, e2 string) {
 	// The error message will contain filenames with OS slashes. Normalize before compare.
 	e1, e2 = filepath.ToSlash(e1), filepath.ToSlash(e2)
-	t.assert.Contains(e2, e1, stackTrace())
+	t.c.Assert(e2, qt.Contains, e1)
 
 }
 
@@ -89,9 +89,9 @@
 			},
 			assertCreateError: func(a testSiteBuildErrorAsserter, err error) {
 				fe := a.getFileError(err)
-				a.assert.Equal(5, fe.Position().LineNumber)
-				a.assert.Equal(1, fe.Position().ColumnNumber)
-				a.assert.Equal("go-html-template", fe.ChromaLexer)
+				a.c.Assert(fe.Position().LineNumber, qt.Equals, 5)
+				a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 1)
+				a.c.Assert(fe.ChromaLexer, qt.Equals, "go-html-template")
 				a.assertErrorMessage("\"layouts/_default/single.html:5:1\": parse failed: template: _default/single.html:5: unexpected \"}\" in operand", fe.Error())
 
 			},
@@ -104,9 +104,9 @@
 			},
 			assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
 				fe := a.getFileError(err)
-				a.assert.Equal(5, fe.Position().LineNumber)
-				a.assert.Equal(14, fe.Position().ColumnNumber)
-				a.assert.Equal("go-html-template", fe.ChromaLexer)
+				a.c.Assert(fe.Position().LineNumber, qt.Equals, 5)
+				a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 14)
+				a.c.Assert(fe.ChromaLexer, qt.Equals, "go-html-template")
 				a.assertErrorMessage("\"layouts/_default/single.html:5:14\": execute of template failed", fe.Error())
 
 			},
@@ -119,9 +119,9 @@
 			},
 			assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
 				fe := a.getFileError(err)
-				a.assert.Equal(5, fe.Position().LineNumber)
-				a.assert.Equal(14, fe.Position().ColumnNumber)
-				a.assert.Equal("go-html-template", fe.ChromaLexer)
+				a.c.Assert(fe.Position().LineNumber, qt.Equals, 5)
+				a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 14)
+				a.c.Assert(fe.ChromaLexer, qt.Equals, "go-html-template")
 				a.assertErrorMessage("\"layouts/_default/single.html:5:14\": execute of template failed", fe.Error())
 
 			},
@@ -144,8 +144,8 @@
 			},
 			assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
 				fe := a.getFileError(err)
-				a.assert.Equal(7, fe.Position().LineNumber)
-				a.assert.Equal("md", fe.ChromaLexer)
+				a.c.Assert(fe.Position().LineNumber, qt.Equals, 7)
+				a.c.Assert(fe.ChromaLexer, qt.Equals, "md")
 				// Make sure that it contains both the content file and template
 				a.assertErrorMessage(`content/myyaml.md:7:10": failed to render shortcode "sc"`, fe.Error())
 				a.assertErrorMessage(`shortcodes/sc.html:4:22: executing "shortcodes/sc.html" at <.Page.Titles>: can't evaluate`, fe.Error())
@@ -159,9 +159,9 @@
 			},
 			assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
 				fe := a.getFileError(err)
-				a.assert.Equal(7, fe.Position().LineNumber)
-				a.assert.Equal(10, fe.Position().ColumnNumber)
-				a.assert.Equal("md", fe.ChromaLexer)
+				a.c.Assert(fe.Position().LineNumber, qt.Equals, 7)
+				a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 10)
+				a.c.Assert(fe.ChromaLexer, qt.Equals, "md")
 				a.assertErrorMessage(`"content/myyaml.md:7:10": failed to extract shortcode: template for shortcode "nono" not found`, fe.Error())
 			},
 		},
@@ -183,8 +183,8 @@
 			},
 			assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
 				fe := a.getFileError(err)
-				a.assert.Equal(6, fe.Position().LineNumber)
-				a.assert.Equal("toml", fe.ErrorContext.ChromaLexer)
+				a.c.Assert(fe.Position().LineNumber, qt.Equals, 6)
+				a.c.Assert(fe.ErrorContext.ChromaLexer, qt.Equals, "toml")
 
 			},
 		},
@@ -197,8 +197,8 @@
 			assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
 				fe := a.getFileError(err)
 
-				a.assert.Equal(3, fe.Position().LineNumber)
-				a.assert.Equal("json", fe.ErrorContext.ChromaLexer)
+				a.c.Assert(fe.Position().LineNumber, qt.Equals, 3)
+				a.c.Assert(fe.ErrorContext.ChromaLexer, qt.Equals, "json")
 
 			},
 		},
@@ -211,14 +211,14 @@
 			},
 
 			assertBuildError: func(a testSiteBuildErrorAsserter, err error) {
-				a.assert.Error(err)
+				a.c.Assert(err, qt.Not(qt.IsNil))
 				// This is fixed in latest Go source
 				if regexp.MustCompile("devel|12").MatchString(runtime.Version()) {
 					fe := a.getFileError(err)
-					a.assert.Equal(5, fe.Position().LineNumber)
-					a.assert.Equal(21, fe.Position().ColumnNumber)
+					a.c.Assert(fe.Position().LineNumber, qt.Equals, 5)
+					a.c.Assert(fe.Position().ColumnNumber, qt.Equals, 21)
 				} else {
-					a.assert.Contains(err.Error(), `execute of template failed: panic in Execute`)
+					a.c.Assert(err.Error(), qt.Contains, `execute of template failed: panic in Execute`)
 				}
 			},
 		},
@@ -228,10 +228,10 @@
 		test := test
 		t.Run(test.name, func(t *testing.T) {
 			t.Parallel()
-			assert := require.New(t)
+			c := qt.New(t)
 			errorAsserter := testSiteBuildErrorAsserter{
-				assert: assert,
-				name:   test.name,
+				c:    c,
+				name: test.name,
 			}
 
 			b := newTestSitesBuilder(t).WithSimpleConfigFile()
@@ -306,7 +306,7 @@
 			if test.assertCreateError != nil {
 				test.assertCreateError(errorAsserter, createErr)
 			} else {
-				assert.NoError(createErr)
+				c.Assert(createErr, qt.IsNil)
 			}
 
 			if createErr == nil {
@@ -314,7 +314,7 @@
 				if test.assertBuildError != nil {
 					test.assertBuildError(errorAsserter, buildErr)
 				} else {
-					assert.NoError(buildErr)
+					c.Assert(buildErr, qt.IsNil)
 				}
 			}
 		})
--- a/hugolib/hugo_sites_build_test.go
+++ b/hugolib/hugo_sites_build_test.go
@@ -8,6 +8,7 @@
 	"path/filepath"
 	"time"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/resources/page"
 
 	"github.com/fortytw2/leaktest"
@@ -15,7 +16,6 @@
 	"github.com/gohugoio/hugo/helpers"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/afero"
-	"github.com/stretchr/testify/require"
 )
 
 func TestMultiSitesMainLangInRoot(t *testing.T) {
@@ -26,7 +26,7 @@
 }
 
 func doTestMultiSitesMainLangInRoot(t *testing.T, defaultInSubDir bool) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	siteConfig := map[string]interface{}{
 		"DefaultContentLanguage":         "fr",
@@ -49,21 +49,20 @@
 	b.Build(BuildCfg{})
 
 	sites := b.H.Sites
+	c.Assert(len(sites), qt.Equals, 4)
 
-	require.Len(t, sites, 4)
-
 	enSite := sites[0]
 	frSite := sites[1]
 
-	assert.Equal("/en", enSite.Info.LanguagePrefix)
+	c.Assert(enSite.Info.LanguagePrefix, qt.Equals, "/en")
 
 	if defaultInSubDir {
-		assert.Equal("/fr", frSite.Info.LanguagePrefix)
+		c.Assert(frSite.Info.LanguagePrefix, qt.Equals, "/fr")
 	} else {
-		assert.Equal("", frSite.Info.LanguagePrefix)
+		c.Assert(frSite.Info.LanguagePrefix, qt.Equals, "")
 	}
 
-	assert.Equal("/blog/en/foo", enSite.PathSpec.RelURL("foo", true))
+	c.Assert(enSite.PathSpec.RelURL("foo", true), qt.Equals, "/blog/en/foo")
 
 	doc1en := enSite.RegularPages()[0]
 	doc1fr := frSite.RegularPages()[0]
@@ -70,8 +69,8 @@
 
 	enPerm := doc1en.Permalink()
 	enRelPerm := doc1en.RelPermalink()
-	assert.Equal("http://example.com/blog/en/sect/doc1-slug/", enPerm)
-	assert.Equal("/blog/en/sect/doc1-slug/", enRelPerm)
+	c.Assert(enPerm, qt.Equals, "http://example.com/blog/en/sect/doc1-slug/")
+	c.Assert(enRelPerm, qt.Equals, "/blog/en/sect/doc1-slug/")
 
 	frPerm := doc1fr.Permalink()
 	frRelPerm := doc1fr.RelPermalink()
@@ -80,15 +79,15 @@
 	b.AssertFileContent("public/en/sect/doc1-slug/index.html", "Single", "Hello")
 
 	if defaultInSubDir {
-		assert.Equal("http://example.com/blog/fr/sect/doc1/", frPerm)
-		assert.Equal("/blog/fr/sect/doc1/", frRelPerm)
+		c.Assert(frPerm, qt.Equals, "http://example.com/blog/fr/sect/doc1/")
+		c.Assert(frRelPerm, qt.Equals, "/blog/fr/sect/doc1/")
 
 		// should have a redirect on top level.
 		b.AssertFileContent("public/index.html", `<meta http-equiv="refresh" content="0; url=http://example.com/blog/fr" />`)
 	} else {
 		// Main language in root
-		assert.Equal("http://example.com/blog/sect/doc1/", frPerm)
-		assert.Equal("/blog/sect/doc1/", frRelPerm)
+		c.Assert(frPerm, qt.Equals, "http://example.com/blog/sect/doc1/")
+		c.Assert(frRelPerm, qt.Equals, "/blog/sect/doc1/")
 
 		// should have redirect back to root
 		b.AssertFileContent("public/fr/index.html", `<meta http-equiv="refresh" content="0; url=http://example.com/blog" />`)
@@ -154,7 +153,7 @@
 func TestMultiSitesWithTwoLanguages(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 	b := newTestSitesBuilder(t).WithConfigFile("toml", `
 
 defaultContentLanguage = "nn"
@@ -179,23 +178,23 @@
 	b.Build(BuildCfg{SkipRender: true})
 	sites := b.H.Sites
 
-	assert.Len(sites, 2)
+	c.Assert(len(sites), qt.Equals, 2)
 
 	nnSite := sites[0]
 	nnHome := nnSite.getPage(page.KindHome)
-	assert.Len(nnHome.AllTranslations(), 2)
-	assert.Len(nnHome.Translations(), 1)
-	assert.True(nnHome.IsTranslated())
+	c.Assert(len(nnHome.AllTranslations()), qt.Equals, 2)
+	c.Assert(len(nnHome.Translations()), qt.Equals, 1)
+	c.Assert(nnHome.IsTranslated(), qt.Equals, true)
 
 	enHome := sites[1].getPage(page.KindHome)
 
 	p1, err := enHome.Param("p1")
-	assert.NoError(err)
-	assert.Equal("p1en", p1)
+	c.Assert(err, qt.IsNil)
+	c.Assert(p1, qt.Equals, "p1en")
 
 	p1, err = nnHome.Param("p1")
-	assert.NoError(err)
-	assert.Equal("p1nn", p1)
+	c.Assert(err, qt.IsNil)
+	c.Assert(p1, qt.Equals, "p1nn")
 }
 
 func TestMultiSitesBuild(t *testing.T) {
@@ -217,38 +216,38 @@
 }
 
 func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	b := newMultiSiteTestBuilder(t, configSuffix, configTemplate, nil)
 	b.CreateSites()
 
 	sites := b.H.Sites
-	assert.Equal(4, len(sites))
+	c.Assert(len(sites), qt.Equals, 4)
 
 	b.Build(BuildCfg{})
 
 	// Check site config
 	for _, s := range sites {
-		require.True(t, s.Info.defaultContentLanguageInSubdir, s.Info.title)
-		require.NotNil(t, s.disabledKinds)
+		c.Assert(s.Info.defaultContentLanguageInSubdir, qt.Equals, true)
+		c.Assert(s.disabledKinds, qt.Not(qt.IsNil))
 	}
 
 	gp1 := b.H.GetContentPage(filepath.FromSlash("content/sect/doc1.en.md"))
-	require.NotNil(t, gp1)
-	require.Equal(t, "doc1", gp1.Title())
+	c.Assert(gp1, qt.Not(qt.IsNil))
+	c.Assert(gp1.Title(), qt.Equals, "doc1")
 	gp2 := b.H.GetContentPage(filepath.FromSlash("content/dummysect/notfound.md"))
-	require.Nil(t, gp2)
+	c.Assert(gp2, qt.IsNil)
 
 	enSite := sites[0]
 	enSiteHome := enSite.getPage(page.KindHome)
-	require.True(t, enSiteHome.IsTranslated())
+	c.Assert(enSiteHome.IsTranslated(), qt.Equals, true)
 
-	require.Equal(t, "en", enSite.language.Lang)
+	c.Assert(enSite.language.Lang, qt.Equals, "en")
 
 	//dumpPages(enSite.RegularPages()...)
 
-	assert.Equal(5, len(enSite.RegularPages()))
-	assert.Equal(32, len(enSite.AllPages()))
+	c.Assert(len(enSite.RegularPages()), qt.Equals, 5)
+	c.Assert(len(enSite.AllPages()), qt.Equals, 32)
 
 	// Check 404s
 	b.AssertFileContent("public/en/404.html", "404|en|404 Page not found")
@@ -264,33 +263,33 @@
 
 	doc2 := enSite.RegularPages()[1]
 	doc3 := enSite.RegularPages()[2]
-	require.Equal(t, doc2.Prev(), doc3, "doc3 should follow doc2, in .PrevPage")
+	c.Assert(doc3, qt.Equals, doc2.Prev())
 	doc1en := enSite.RegularPages()[0]
 	doc1fr := doc1en.Translations()[0]
 	b.AssertFileContent("public/fr/sect/doc1/index.html", "Permalink: http://example.com/blog/fr/sect/doc1/")
 
-	require.Equal(t, doc1en.Translations()[0], doc1fr, "doc1-en should have doc1-fr as translation")
-	require.Equal(t, doc1fr.Translations()[0], doc1en, "doc1-fr should have doc1-en as translation")
-	require.Equal(t, "fr", doc1fr.Language().Lang)
+	c.Assert(doc1fr, qt.Equals, doc1en.Translations()[0])
+	c.Assert(doc1en, qt.Equals, doc1fr.Translations()[0])
+	c.Assert(doc1fr.Language().Lang, qt.Equals, "fr")
 
 	doc4 := enSite.AllPages()[4]
-	require.Len(t, doc4.Translations(), 0, "found translations for doc4")
+	c.Assert(len(doc4.Translations()), qt.Equals, 0)
 
 	// Taxonomies and their URLs
-	require.Len(t, enSite.Taxonomies, 1, "should have 1 taxonomy")
+	c.Assert(len(enSite.Taxonomies), qt.Equals, 1)
 	tags := enSite.Taxonomies["tags"]
-	require.Len(t, tags, 2, "should have 2 different tags")
-	require.Equal(t, tags["tag1"][0].Page, doc1en, "first tag1 page should be doc1")
+	c.Assert(len(tags), qt.Equals, 2)
+	c.Assert(doc1en, qt.Equals, tags["tag1"][0].Page)
 
 	frSite := sites[1]
 
-	require.Equal(t, "fr", frSite.language.Lang)
-	require.Len(t, frSite.RegularPages(), 4, "should have 3 pages")
-	require.Len(t, frSite.AllPages(), 32, "should have 32 total pages (including translations and nodes)")
+	c.Assert(frSite.language.Lang, qt.Equals, "fr")
+	c.Assert(len(frSite.RegularPages()), qt.Equals, 4)
+	c.Assert(len(frSite.AllPages()), qt.Equals, 32)
 
 	for _, frenchPage := range frSite.RegularPages() {
 		p := frenchPage
-		require.Equal(t, "fr", p.Language().Lang)
+		c.Assert(p.Language().Lang, qt.Equals, "fr")
 	}
 
 	// See https://github.com/gohugoio/hugo/issues/4285
@@ -302,10 +301,10 @@
 	getPageDoc1EnBase := enSite.getPage(page.KindPage, "sect/doc1")
 	getPageDoc1Fr := frSite.getPage(page.KindPage, filepath.ToSlash(doc1fr.File().Path()))
 	getPageDoc1FrBase := frSite.getPage(page.KindPage, "sect/doc1")
-	require.Equal(t, doc1en, getPageDoc1En)
-	require.Equal(t, doc1fr, getPageDoc1Fr)
-	require.Equal(t, doc1en, getPageDoc1EnBase)
-	require.Equal(t, doc1fr, getPageDoc1FrBase)
+	c.Assert(getPageDoc1En, qt.Equals, doc1en)
+	c.Assert(getPageDoc1Fr, qt.Equals, doc1fr)
+	c.Assert(getPageDoc1EnBase, qt.Equals, doc1en)
+	c.Assert(getPageDoc1FrBase, qt.Equals, doc1fr)
 
 	// Check redirect to main language, French
 	b.AssertFileContent("public/index.html", "0; url=http://example.com/blog/fr")
@@ -320,35 +319,35 @@
 
 	// Check node translations
 	homeEn := enSite.getPage(page.KindHome)
-	require.NotNil(t, homeEn)
-	require.Len(t, homeEn.Translations(), 3)
-	require.Equal(t, "fr", homeEn.Translations()[0].Language().Lang)
-	require.Equal(t, "nn", homeEn.Translations()[1].Language().Lang)
-	require.Equal(t, "På nynorsk", homeEn.Translations()[1].Title())
-	require.Equal(t, "nb", homeEn.Translations()[2].Language().Lang)
-	require.Equal(t, "På bokmål", homeEn.Translations()[2].Title(), configSuffix)
-	require.Equal(t, "Bokmål", homeEn.Translations()[2].Language().LanguageName, configSuffix)
+	c.Assert(homeEn, qt.Not(qt.IsNil))
+	c.Assert(len(homeEn.Translations()), qt.Equals, 3)
+	c.Assert(homeEn.Translations()[0].Language().Lang, qt.Equals, "fr")
+	c.Assert(homeEn.Translations()[1].Language().Lang, qt.Equals, "nn")
+	c.Assert(homeEn.Translations()[1].Title(), qt.Equals, "På nynorsk")
+	c.Assert(homeEn.Translations()[2].Language().Lang, qt.Equals, "nb")
+	c.Assert(homeEn.Translations()[2].Title(), qt.Equals, "På bokmål")
+	c.Assert(homeEn.Translations()[2].Language().LanguageName, qt.Equals, "Bokmål")
 
 	sectFr := frSite.getPage(page.KindSection, "sect")
-	require.NotNil(t, sectFr)
+	c.Assert(sectFr, qt.Not(qt.IsNil))
 
-	require.Equal(t, "fr", sectFr.Language().Lang)
-	require.Len(t, sectFr.Translations(), 1)
-	require.Equal(t, "en", sectFr.Translations()[0].Language().Lang)
-	require.Equal(t, "Sects", sectFr.Translations()[0].Title())
+	c.Assert(sectFr.Language().Lang, qt.Equals, "fr")
+	c.Assert(len(sectFr.Translations()), qt.Equals, 1)
+	c.Assert(sectFr.Translations()[0].Language().Lang, qt.Equals, "en")
+	c.Assert(sectFr.Translations()[0].Title(), qt.Equals, "Sects")
 
 	nnSite := sites[2]
-	require.Equal(t, "nn", nnSite.language.Lang)
+	c.Assert(nnSite.language.Lang, qt.Equals, "nn")
 	taxNn := nnSite.getPage(page.KindTaxonomyTerm, "lag")
-	require.NotNil(t, taxNn)
-	require.Len(t, taxNn.Translations(), 1)
-	require.Equal(t, "nb", taxNn.Translations()[0].Language().Lang)
+	c.Assert(taxNn, qt.Not(qt.IsNil))
+	c.Assert(len(taxNn.Translations()), qt.Equals, 1)
+	c.Assert(taxNn.Translations()[0].Language().Lang, qt.Equals, "nb")
 
 	taxTermNn := nnSite.getPage(page.KindTaxonomy, "lag", "sogndal")
-	require.NotNil(t, taxTermNn)
-	require.Equal(t, taxTermNn, nnSite.getPage(page.KindTaxonomy, "LAG", "SOGNDAL"))
-	require.Len(t, taxTermNn.Translations(), 1)
-	require.Equal(t, "nb", taxTermNn.Translations()[0].Language().Lang)
+	c.Assert(taxTermNn, qt.Not(qt.IsNil))
+	c.Assert(nnSite.getPage(page.KindTaxonomy, "LAG", "SOGNDAL"), qt.Equals, taxTermNn)
+	c.Assert(len(taxTermNn.Translations()), qt.Equals, 1)
+	c.Assert(taxTermNn.Translations()[0].Language().Lang, qt.Equals, "nb")
 
 	// Check sitemap(s)
 	b.AssertFileContent("public/sitemap.xml",
@@ -360,35 +359,35 @@
 	// Check taxonomies
 	enTags := enSite.Taxonomies["tags"]
 	frTags := frSite.Taxonomies["plaques"]
-	require.Len(t, enTags, 2, fmt.Sprintf("Tags in en: %v", enTags))
-	require.Len(t, frTags, 2, fmt.Sprintf("Tags in fr: %v", frTags))
-	require.NotNil(t, enTags["tag1"])
-	require.NotNil(t, frTags["FRtag1"])
+	c.Assert(len(enTags), qt.Equals, 2, qt.Commentf("Tags in en: %v", enTags))
+	c.Assert(len(frTags), qt.Equals, 2, qt.Commentf("Tags in fr: %v", frTags))
+	c.Assert(enTags["tag1"], qt.Not(qt.IsNil))
+	c.Assert(frTags["FRtag1"], qt.Not(qt.IsNil))
 	b.AssertFileContent("public/fr/plaques/FRtag1/index.html", "FRtag1|Bonjour|http://example.com/blog/fr/plaques/FRtag1/")
 
 	// Check Blackfriday config
-	require.True(t, strings.Contains(content(doc1fr), "&laquo;"), content(doc1fr))
-	require.False(t, strings.Contains(content(doc1en), "&laquo;"), content(doc1en))
-	require.True(t, strings.Contains(content(doc1en), "&ldquo;"), content(doc1en))
+	c.Assert(strings.Contains(content(doc1fr), "&laquo;"), qt.Equals, true)
+	c.Assert(strings.Contains(content(doc1en), "&laquo;"), qt.Equals, false)
+	c.Assert(strings.Contains(content(doc1en), "&ldquo;"), qt.Equals, true)
 
 	// en and nn have custom site menus
-	require.Len(t, frSite.Menus(), 0, "fr: "+configSuffix)
-	require.Len(t, enSite.Menus(), 1, "en: "+configSuffix)
-	require.Len(t, nnSite.Menus(), 1, "nn: "+configSuffix)
+	c.Assert(len(frSite.Menus()), qt.Equals, 0)
+	c.Assert(len(enSite.Menus()), qt.Equals, 1)
+	c.Assert(len(nnSite.Menus()), qt.Equals, 1)
 
-	require.Equal(t, "Home", enSite.Menus()["main"].ByName()[0].Name)
-	require.Equal(t, "Heim", nnSite.Menus()["main"].ByName()[0].Name)
+	c.Assert(enSite.Menus()["main"].ByName()[0].Name, qt.Equals, "Home")
+	c.Assert(nnSite.Menus()["main"].ByName()[0].Name, qt.Equals, "Heim")
 
 	// Issue #3108
 	prevPage := enSite.RegularPages()[0].Prev()
-	require.NotNil(t, prevPage)
-	require.Equal(t, page.KindPage, prevPage.Kind())
+	c.Assert(prevPage, qt.Not(qt.IsNil))
+	c.Assert(prevPage.Kind(), qt.Equals, page.KindPage)
 
 	for {
 		if prevPage == nil {
 			break
 		}
-		require.Equal(t, page.KindPage, prevPage.Kind())
+		c.Assert(prevPage.Kind(), qt.Equals, page.KindPage)
 		prevPage = prevPage.Prev()
 	}
 
@@ -395,19 +394,19 @@
 	// Check bundles
 	b.AssertFileContent("public/fr/bundles/b1/index.html", "RelPermalink: /blog/fr/bundles/b1/|")
 	bundleFr := frSite.getPage(page.KindPage, "bundles/b1/index.md")
-	require.NotNil(t, bundleFr)
-	require.Equal(t, 1, len(bundleFr.Resources()))
+	c.Assert(bundleFr, qt.Not(qt.IsNil))
+	c.Assert(len(bundleFr.Resources()), qt.Equals, 1)
 	logoFr := bundleFr.Resources().GetMatch("logo*")
-	require.NotNil(t, logoFr)
+	c.Assert(logoFr, qt.Not(qt.IsNil))
 	b.AssertFileContent("public/fr/bundles/b1/index.html", "Resources: image/png: /blog/fr/bundles/b1/logo.png")
 	b.AssertFileContent("public/fr/bundles/b1/logo.png", "PNG Data")
 
 	bundleEn := enSite.getPage(page.KindPage, "bundles/b1/index.en.md")
-	require.NotNil(t, bundleEn)
+	c.Assert(bundleEn, qt.Not(qt.IsNil))
 	b.AssertFileContent("public/en/bundles/b1/index.html", "RelPermalink: /blog/en/bundles/b1/|")
-	require.Equal(t, 1, len(bundleEn.Resources()))
+	c.Assert(len(bundleEn.Resources()), qt.Equals, 1)
 	logoEn := bundleEn.Resources().GetMatch("logo*")
-	require.NotNil(t, logoEn)
+	c.Assert(logoEn, qt.Not(qt.IsNil))
 	b.AssertFileContent("public/en/bundles/b1/index.html", "Resources: image/png: /blog/en/bundles/b1/logo.png")
 	b.AssertFileContent("public/en/bundles/b1/logo.png", "PNG Data")
 
@@ -420,7 +419,7 @@
 		defer leaktest.CheckTimeout(t, 10*time.Second)()
 	}
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	b := newMultiSiteTestDefaultBuilder(t).Running().CreateSites().Build(BuildCfg{})
 
@@ -432,8 +431,8 @@
 	enSite := sites[0]
 	frSite := sites[1]
 
-	assert.Len(enSite.RegularPages(), 5)
-	assert.Len(frSite.RegularPages(), 4)
+	c.Assert(len(enSite.RegularPages()), qt.Equals, 5)
+	c.Assert(len(frSite.RegularPages()), qt.Equals, 4)
 
 	// Verify translations
 	b.AssertFileContent("public/en/sect/doc1-slug/index.html", "Hello")
@@ -444,8 +443,8 @@
 	b.AssertFileContent("public/en/sect/doc1-slug/index.html", "Single", "Shortcode: Hello")
 
 	homeEn := enSite.getPage(page.KindHome)
-	require.NotNil(t, homeEn)
-	assert.Len(homeEn.Translations(), 3)
+	c.Assert(homeEn, qt.Not(qt.IsNil))
+	c.Assert(len(homeEn.Translations()), qt.Equals, 3)
 
 	contentFs := b.H.Fs.Source
 
@@ -467,7 +466,7 @@
 			},
 			[]fsnotify.Event{{Name: filepath.FromSlash("content/sect/doc2.en.md"), Op: fsnotify.Remove}},
 			func(t *testing.T) {
-				assert.Len(enSite.RegularPages(), 4, "1 en removed")
+				c.Assert(len(enSite.RegularPages()), qt.Equals, 4, qt.Commentf("1 en removed"))
 
 			},
 		},
@@ -483,15 +482,15 @@
 				{Name: filepath.FromSlash("content/new1.fr.md"), Op: fsnotify.Create},
 			},
 			func(t *testing.T) {
-				assert.Len(enSite.RegularPages(), 6)
-				assert.Len(enSite.AllPages(), 34)
-				assert.Len(frSite.RegularPages(), 5)
-				require.Equal(t, "new_fr_1", frSite.RegularPages()[3].Title())
-				require.Equal(t, "new_en_2", enSite.RegularPages()[0].Title())
-				require.Equal(t, "new_en_1", enSite.RegularPages()[1].Title())
+				c.Assert(len(enSite.RegularPages()), qt.Equals, 6)
+				c.Assert(len(enSite.AllPages()), qt.Equals, 34)
+				c.Assert(len(frSite.RegularPages()), qt.Equals, 5)
+				c.Assert(frSite.RegularPages()[3].Title(), qt.Equals, "new_fr_1")
+				c.Assert(enSite.RegularPages()[0].Title(), qt.Equals, "new_en_2")
+				c.Assert(enSite.RegularPages()[1].Title(), qt.Equals, "new_en_1")
 
 				rendered := readDestination(t, fs, "public/en/new1/index.html")
-				require.True(t, strings.Contains(rendered, "new_en_1"), rendered)
+				c.Assert(strings.Contains(rendered, "new_en_1"), qt.Equals, true)
 			},
 		},
 		{
@@ -503,9 +502,9 @@
 			},
 			[]fsnotify.Event{{Name: filepath.FromSlash("content/sect/doc1.en.md"), Op: fsnotify.Write}},
 			func(t *testing.T) {
-				assert.Len(enSite.RegularPages(), 6)
+				c.Assert(len(enSite.RegularPages()), qt.Equals, 6)
 				doc1 := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
-				require.True(t, strings.Contains(doc1, "CHANGED"), doc1)
+				c.Assert(strings.Contains(doc1, "CHANGED"), qt.Equals, true)
 
 			},
 		},
@@ -521,10 +520,10 @@
 				{Name: filepath.FromSlash("content/new1.en.md"), Op: fsnotify.Rename},
 			},
 			func(t *testing.T) {
-				assert.Len(enSite.RegularPages(), 6, "Rename")
-				require.Equal(t, "new_en_1", enSite.RegularPages()[1].Title())
+				c.Assert(len(enSite.RegularPages()), qt.Equals, 6, qt.Commentf("Rename"))
+				c.Assert(enSite.RegularPages()[1].Title(), qt.Equals, "new_en_1")
 				rendered := readDestination(t, fs, "public/en/new1renamed/index.html")
-				require.True(t, strings.Contains(rendered, "new_en_1"), rendered)
+				c.Assert(rendered, qt.Contains, "new_en_1")
 			}},
 		{
 			// Change a template
@@ -536,11 +535,11 @@
 			},
 			[]fsnotify.Event{{Name: filepath.FromSlash("layouts/_default/single.html"), Op: fsnotify.Write}},
 			func(t *testing.T) {
-				assert.Len(enSite.RegularPages(), 6)
-				assert.Len(enSite.AllPages(), 34)
-				assert.Len(frSite.RegularPages(), 5)
+				c.Assert(len(enSite.RegularPages()), qt.Equals, 6)
+				c.Assert(len(enSite.AllPages()), qt.Equals, 34)
+				c.Assert(len(frSite.RegularPages()), qt.Equals, 5)
 				doc1 := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
-				require.True(t, strings.Contains(doc1, "Template Changed"), doc1)
+				c.Assert(strings.Contains(doc1, "Template Changed"), qt.Equals, true)
 			},
 		},
 		{
@@ -553,18 +552,18 @@
 			},
 			[]fsnotify.Event{{Name: filepath.FromSlash("i18n/fr.yaml"), Op: fsnotify.Write}},
 			func(t *testing.T) {
-				assert.Len(enSite.RegularPages(), 6)
-				assert.Len(enSite.AllPages(), 34)
-				assert.Len(frSite.RegularPages(), 5)
+				c.Assert(len(enSite.RegularPages()), qt.Equals, 6)
+				c.Assert(len(enSite.AllPages()), qt.Equals, 34)
+				c.Assert(len(frSite.RegularPages()), qt.Equals, 5)
 				docEn := readDestination(t, fs, "public/en/sect/doc1-slug/index.html")
-				require.True(t, strings.Contains(docEn, "Hello"), "No Hello")
+				c.Assert(strings.Contains(docEn, "Hello"), qt.Equals, true)
 				docFr := readDestination(t, fs, "public/fr/sect/doc1/index.html")
-				require.True(t, strings.Contains(docFr, "Salut"), "No Salut")
+				c.Assert(strings.Contains(docFr, "Salut"), qt.Equals, true)
 
 				homeEn := enSite.getPage(page.KindHome)
-				require.NotNil(t, homeEn)
-				assert.Len(homeEn.Translations(), 3)
-				require.Equal(t, "fr", homeEn.Translations()[0].Language().Lang)
+				c.Assert(homeEn, qt.Not(qt.IsNil))
+				c.Assert(len(homeEn.Translations()), qt.Equals, 3)
+				c.Assert(homeEn.Translations()[0].Language().Lang, qt.Equals, "fr")
 
 			},
 		},
@@ -577,9 +576,9 @@
 				{Name: filepath.FromSlash("layouts/shortcodes/shortcode.html"), Op: fsnotify.Write},
 			},
 			func(t *testing.T) {
-				assert.Len(enSite.RegularPages(), 6)
-				assert.Len(enSite.AllPages(), 34)
-				assert.Len(frSite.RegularPages(), 5)
+				c.Assert(len(enSite.RegularPages()), qt.Equals, 6)
+				c.Assert(len(enSite.AllPages()), qt.Equals, 34)
+				c.Assert(len(frSite.RegularPages()), qt.Equals, 5)
 				b.AssertFileContent("public/fr/sect/doc1/index.html", "Single", "Modified Shortcode: Salut")
 				b.AssertFileContent("public/en/sect/doc1-slug/index.html", "Single", "Modified Shortcode: Hello")
 			},
@@ -781,24 +780,24 @@
 	} {
 
 		t.Run(path, func(t *testing.T) {
-			assert := require.New(t)
+			c := qt.New(t)
 
 			s1, _ := b.H.Sites[0].getPageNew(nil, path)
 			s2, _ := b.H.Sites[1].getPageNew(nil, path)
 
-			assert.NotNil(s1)
-			assert.NotNil(s2)
+			c.Assert(s1, qt.Not(qt.IsNil))
+			c.Assert(s2, qt.Not(qt.IsNil))
 
-			assert.Equal(1, len(s1.Translations()))
-			assert.Equal(1, len(s2.Translations()))
-			assert.Equal(s2, s1.Translations()[0])
-			assert.Equal(s1, s2.Translations()[0])
+			c.Assert(len(s1.Translations()), qt.Equals, 1)
+			c.Assert(len(s2.Translations()), qt.Equals, 1)
+			c.Assert(s1.Translations()[0], qt.Equals, s2)
+			c.Assert(s2.Translations()[0], qt.Equals, s1)
 
 			m1 := s1.Translations().MergeByLanguage(s2.Translations())
 			m2 := s2.Translations().MergeByLanguage(s1.Translations())
 
-			assert.Equal(1, len(m1))
-			assert.Equal(1, len(m2))
+			c.Assert(len(m1), qt.Equals, 1)
+			c.Assert(len(m2), qt.Equals, 1)
 		})
 
 	}
--- a/hugolib/hugo_sites_multihost_test.go
+++ b/hugolib/hugo_sites_multihost_test.go
@@ -5,13 +5,13 @@
 
 	"github.com/gohugoio/hugo/resources/page"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestMultihosts(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	var configTemplate = `
 paginate = 1
@@ -58,9 +58,9 @@
 	s1 := b.H.Sites[0]
 
 	s1h := s1.getPage(page.KindHome)
-	assert.True(s1h.IsTranslated())
-	assert.Len(s1h.Translations(), 2)
-	assert.Equal("https://example.com/docs/", s1h.Permalink())
+	c.Assert(s1h.IsTranslated(), qt.Equals, true)
+	c.Assert(len(s1h.Translations()), qt.Equals, 2)
+	c.Assert(s1h.Permalink(), qt.Equals, "https://example.com/docs/")
 
 	// For “regular multilingual” we kept the aliases pages with url in front matter
 	// as a literal value that we use as is.
@@ -69,8 +69,8 @@
 	//
 	// check url in front matter:
 	pageWithURLInFrontMatter := s1.getPage(page.KindPage, "sect/doc3.en.md")
-	assert.NotNil(pageWithURLInFrontMatter)
-	assert.Equal("/docs/superbob/", pageWithURLInFrontMatter.RelPermalink())
+	c.Assert(pageWithURLInFrontMatter, qt.Not(qt.IsNil))
+	c.Assert(pageWithURLInFrontMatter.RelPermalink(), qt.Equals, "/docs/superbob/")
 	b.AssertFileContent("public/en/superbob/index.html", "doc3|Hello|en")
 
 	// check alias:
@@ -80,7 +80,7 @@
 	s2 := b.H.Sites[1]
 
 	s2h := s2.getPage(page.KindHome)
-	assert.Equal("https://example.fr/", s2h.Permalink())
+	c.Assert(s2h.Permalink(), qt.Equals, "https://example.fr/")
 
 	b.AssertFileContent("public/fr/index.html", "French Home Page", "String Resource: /docs/text/pipes.txt")
 	b.AssertFileContent("public/fr/text/pipes.txt", "Hugo Pipes")
@@ -96,17 +96,17 @@
 	// Check bundles
 
 	bundleEn := s1.getPage(page.KindPage, "bundles/b1/index.en.md")
-	require.NotNil(t, bundleEn)
-	require.Equal(t, "/docs/bundles/b1/", bundleEn.RelPermalink())
-	require.Equal(t, 1, len(bundleEn.Resources()))
+	c.Assert(bundleEn, qt.Not(qt.IsNil))
+	c.Assert(bundleEn.RelPermalink(), qt.Equals, "/docs/bundles/b1/")
+	c.Assert(len(bundleEn.Resources()), qt.Equals, 1)
 
 	b.AssertFileContent("public/en/bundles/b1/logo.png", "PNG Data")
 	b.AssertFileContent("public/en/bundles/b1/index.html", " image/png: /docs/bundles/b1/logo.png")
 
 	bundleFr := s2.getPage(page.KindPage, "bundles/b1/index.md")
-	require.NotNil(t, bundleFr)
-	require.Equal(t, "/bundles/b1/", bundleFr.RelPermalink())
-	require.Equal(t, 1, len(bundleFr.Resources()))
+	c.Assert(bundleFr, qt.Not(qt.IsNil))
+	c.Assert(bundleFr.RelPermalink(), qt.Equals, "/bundles/b1/")
+	c.Assert(len(bundleFr.Resources()), qt.Equals, 1)
 	b.AssertFileContent("public/fr/bundles/b1/logo.png", "PNG Data")
 	b.AssertFileContent("public/fr/bundles/b1/index.html", " image/png: /bundles/b1/logo.png")
 
--- a/hugolib/hugo_smoke_test.go
+++ b/hugolib/hugo_smoke_test.go
@@ -18,13 +18,13 @@
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestSmoke(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	const configFile = `
 baseURL = "https://example.com"
@@ -203,8 +203,8 @@
 
 	// Check RSS
 	rssHome := b.FileContent("public/index.xml")
-	assert.Contains(rssHome, `<atom:link href="https://example.com/index.xml" rel="self" type="application/rss+xml" />`)
-	assert.Equal(3, strings.Count(rssHome, "<item>")) // rssLimit = 3
+	c.Assert(rssHome, qt.Contains, `<atom:link href="https://example.com/index.xml" rel="self" type="application/rss+xml" />`)
+	c.Assert(strings.Count(rssHome, "<item>"), qt.Equals, 3) // rssLimit = 3
 
 	// .Render should use template/content from the current output format
 	// even if that output format isn't configured for that page.
--- a/hugolib/image_test.go
+++ b/hugolib/image_test.go
@@ -21,18 +21,18 @@
 
 	"github.com/gohugoio/hugo/htesting"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 // We have many tests for the different resize operations etc. in the resource package,
 // this is an integration test.
 func TestImageResize(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	// Make this a real as possible.
 	workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "image-resize")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer clean()
 
 	newBuilder := func() *sitesBuilder {
@@ -74,22 +74,22 @@
 	imageDir := filepath.Join(workDir, "assets", "images")
 	bundleDir := filepath.Join(workDir, "content", "mybundle")
 
-	assert.NoError(os.MkdirAll(imageDir, 0777))
-	assert.NoError(os.MkdirAll(bundleDir, 0777))
+	c.Assert(os.MkdirAll(imageDir, 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(bundleDir, 0777), qt.IsNil)
 	src, err := os.Open("testdata/sunset.jpg")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	out, err := os.Create(filepath.Join(imageDir, "sunset.jpg"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	_, err = io.Copy(out, src)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	out.Close()
 
 	src.Seek(0, 0)
 
 	out, err = os.Create(filepath.Join(bundleDir, "sunset.jpg"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	_, err = io.Copy(out, src)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	out.Close()
 	src.Close()
 
--- a/hugolib/language_content_dir_test.go
+++ b/hugolib/language_content_dir_test.go
@@ -19,9 +19,11 @@
 	"path/filepath"
 	"testing"
 
+	"github.com/spf13/cast"
+
 	"github.com/gohugoio/hugo/resources/page"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 /*
@@ -42,7 +44,7 @@
 
 func TestLanguageContentRoot(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	config := `
 baseURL = "https://example.org/"
@@ -215,9 +217,9 @@
 
 	//dumpPages(b.H.Sites[1].RegularPages()...)
 
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal(3, len(b.H.Sites))
+	c.Assert(len(b.H.Sites), qt.Equals, 3)
 
 	enSite := b.H.Sites[0]
 	nnSite := b.H.Sites[1]
@@ -228,25 +230,26 @@
 
 	//dumpPages(nnSite.RegularPages()...)
 
-	assert.Equal(12, len(nnSite.RegularPages()))
-	assert.Equal(13, len(enSite.RegularPages()))
+	c.Assert(len(nnSite.RegularPages()), qt.Equals, 12)
+	c.Assert(len(enSite.RegularPages()), qt.Equals, 13)
 
-	assert.Equal(10, len(svSite.RegularPages()))
+	c.Assert(len(svSite.RegularPages()), qt.Equals, 10)
 
 	svP2, err := svSite.getPageNew(nil, "/sect/page2.md")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	nnP2, err := nnSite.getPageNew(nil, "/sect/page2.md")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	enP2, err := enSite.getPageNew(nil, "/sect/page2.md")
-	assert.NoError(err)
-	assert.Equal("en", enP2.Language().Lang)
-	assert.Equal("sv", svP2.Language().Lang)
-	assert.Equal("nn", nnP2.Language().Lang)
+	c.Assert(err, qt.IsNil)
+	c.Assert(enP2.Language().Lang, qt.Equals, "en")
+	c.Assert(svP2.Language().Lang, qt.Equals, "sv")
+	c.Assert(nnP2.Language().Lang, qt.Equals, "nn")
 
 	content, _ := nnP2.Content()
-	assert.Contains(content, "SVP3-REF: https://example.org/sv/sect/p-sv-3/")
-	assert.Contains(content, "SVP3-RELREF: /sv/sect/p-sv-3/")
+	contentStr := cast.ToString(content)
+	c.Assert(contentStr, qt.Contains, "SVP3-REF: https://example.org/sv/sect/p-sv-3/")
+	c.Assert(contentStr, qt.Contains, "SVP3-RELREF: /sv/sect/p-sv-3/")
 
 	// Test RelRef with and without language indicator.
 	nn3RefArgs := map[string]interface{}{
@@ -256,38 +259,34 @@
 	nnP3RelRef, err := svP2.RelRef(
 		nn3RefArgs,
 	)
-	assert.NoError(err)
-	assert.Equal("/nn/sect/p-nn-3/", nnP3RelRef)
+	c.Assert(err, qt.IsNil)
+	c.Assert(nnP3RelRef, qt.Equals, "/nn/sect/p-nn-3/")
 	nnP3Ref, err := svP2.Ref(
 		nn3RefArgs,
 	)
-	assert.NoError(err)
-	assert.Equal("https://example.org/nn/sect/p-nn-3/", nnP3Ref)
+	c.Assert(err, qt.IsNil)
+	c.Assert(nnP3Ref, qt.Equals, "https://example.org/nn/sect/p-nn-3/")
 
 	for i, p := range enSite.RegularPages() {
 		j := i + 1
-		msg := fmt.Sprintf("Test %d", j)
-		assert.Equal("en", p.Language().Lang, msg)
-		assert.Equal("sect", p.Section())
+		c.Assert(p.Language().Lang, qt.Equals, "en")
+		c.Assert(p.Section(), qt.Equals, "sect")
 		if j < 9 {
 			if j%4 == 0 {
-				assert.Contains(p.Title(), fmt.Sprintf("p-sv-%d.en", i+1), msg)
 			} else {
-				assert.Contains(p.Title(), "p-en", msg)
+				c.Assert(p.Title(), qt.Contains, "p-en")
 			}
 		}
 	}
 
-	for i, p := range nnSite.RegularPages() {
-		msg := fmt.Sprintf("Test %d", i+1)
-		assert.Equal("nn", p.Language().Lang, msg)
-		assert.Contains(p.Title(), "nn", msg)
+	for _, p := range nnSite.RegularPages() {
+		c.Assert(p.Language().Lang, qt.Equals, "nn")
+		c.Assert(p.Title(), qt.Contains, "nn")
 	}
 
-	for i, p := range svSite.RegularPages() {
-		msg := fmt.Sprintf("Test %d", i+1)
-		assert.Equal("sv", p.Language().Lang, msg)
-		assert.Contains(p.Title(), "sv", msg)
+	for _, p := range svSite.RegularPages() {
+		c.Assert(p.Language().Lang, qt.Equals, "sv")
+		c.Assert(p.Title(), qt.Contains, "sv")
 	}
 
 	// Check bundles
@@ -295,12 +294,12 @@
 	bundleNn := nnSite.RegularPages()[len(nnSite.RegularPages())-1]
 	bundleSv := svSite.RegularPages()[len(svSite.RegularPages())-1]
 
-	assert.Equal("/en/sect/mybundle/", bundleEn.RelPermalink())
-	assert.Equal("/sv/sect/mybundle/", bundleSv.RelPermalink())
+	c.Assert(bundleEn.RelPermalink(), qt.Equals, "/en/sect/mybundle/")
+	c.Assert(bundleSv.RelPermalink(), qt.Equals, "/sv/sect/mybundle/")
 
-	assert.Equal(4, len(bundleNn.Resources()))
-	assert.Equal(4, len(bundleSv.Resources()))
-	assert.Equal(4, len(bundleEn.Resources()))
+	c.Assert(len(bundleNn.Resources()), qt.Equals, 4)
+	c.Assert(len(bundleSv.Resources()), qt.Equals, 4)
+	c.Assert(len(bundleEn.Resources()), qt.Equals, 4)
 
 	b.AssertFileContent("/my/project/public/en/sect/mybundle/index.html", "image/png: /en/sect/mybundle/logo.png")
 	b.AssertFileContent("/my/project/public/nn/sect/mybundle/index.html", "image/png: /nn/sect/mybundle/logo.png")
@@ -314,9 +313,9 @@
 	b.AssertFileContent("/my/project/public/nn/sect/mybundle/logo.png", "PNG Data")
 
 	nnSect := nnSite.getPage(page.KindSection, "sect")
-	assert.NotNil(nnSect)
-	assert.Equal(12, len(nnSect.Pages()))
+	c.Assert(nnSect, qt.Not(qt.IsNil))
+	c.Assert(len(nnSect.Pages()), qt.Equals, 12)
 	nnHome, _ := nnSite.Info.Home()
-	assert.Equal("/nn/", nnHome.RelPermalink())
+	c.Assert(nnHome.RelPermalink(), qt.Equals, "/nn/")
 
 }
--- a/hugolib/menu_test.go
+++ b/hugolib/menu_test.go
@@ -18,7 +18,7 @@
 
 	"fmt"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 const (
@@ -77,12 +77,12 @@
 
 	s := h.Sites[0]
 
-	require.Len(t, s.Menus(), 2)
+	b.Assert(len(s.Menus()), qt.Equals, 2)
 
 	p1 := s.RegularPages()[0].Menus()
 
 	// There is only one menu in the page, but it is "member of" 2
-	require.Len(t, p1, 1)
+	b.Assert(len(p1), qt.Equals, 1)
 
 	b.AssertFileContent("public/sect1/p1/index.html", "Single",
 		"Menu Sect:  "+
--- a/hugolib/page_permalink_test.go
+++ b/hugolib/page_permalink_test.go
@@ -19,7 +19,7 @@
 	"path/filepath"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 
 	"github.com/gohugoio/hugo/deps"
 )
@@ -66,6 +66,7 @@
 		test := test
 		t.Run(fmt.Sprintf("%s-%d", test.file, i), func(t *testing.T) {
 			t.Parallel()
+			c := qt.New(t)
 			cfg, fs := newTestCfg()
 
 			cfg.Set("uglyURLs", test.uglyURLs)
@@ -84,7 +85,7 @@
 			writeSource(t, fs, filepath.Join("content", filepath.FromSlash(test.file)), pageContent)
 
 			s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
-			require.Len(t, s.RegularPages(), 1)
+			c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 			p := s.RegularPages()[0]
 
--- a/hugolib/page_test.go
+++ b/hugolib/page_test.go
@@ -34,10 +34,9 @@
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/helpers"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 const (
@@ -306,7 +305,6 @@
 	a := normalizeContent(expected)
 	b := normalizeContent(content(page))
 	if a != b {
-		t.Log(stackTrace())
 		t.Fatalf("Page content is:\n%q\nExpected:\n%q (%q)", b, a, msg)
 	}
 }
@@ -422,15 +420,15 @@
 
 		s := b.H.Sites[0]
 
-		require.Len(t, s.RegularPages(), len(pageSources))
+		b.Assert(len(s.RegularPages()), qt.Equals, len(pageSources))
 
 		assertFunc(t, e.ext, s.RegularPages())
 
 		home, err := s.Info.Home()
-		require.NoError(t, err)
-		require.NotNil(t, home)
-		require.Equal(t, homePath, home.File().Path())
-		require.Contains(t, content(home), "Home Page Content")
+		b.Assert(err, qt.IsNil)
+		b.Assert(home, qt.Not(qt.IsNil))
+		b.Assert(home.File().Path(), qt.Equals, homePath)
+		b.Assert(content(home), qt.Contains, "Home Page Content")
 
 	}
 
@@ -440,12 +438,13 @@
 func TestPageWithDelimiterForMarkdownThatCrossesBorder(t *testing.T) {
 	t.Parallel()
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	writeSource(t, fs, filepath.Join("content", "simple.md"), simplePageWithSummaryDelimiterAndMarkdownThatCrossesBorder)
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.Len(t, s.RegularPages(), 1)
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	p := s.RegularPages()[0]
 
@@ -454,15 +453,14 @@
 		t.Fatalf("Got summary:\n%q", p.Summary())
 	}
 
-	c := content(p)
-	if c != "<p>The <a href=\"http://gohugo.io/\">best static site generator</a>.<sup class=\"footnote-ref\" id=\"fnref:1\"><a href=\"#fn:1\">1</a></sup></p>\n\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:1\">Many people say so.\n <a class=\"footnote-return\" href=\"#fnref:1\"><sup>[return]</sup></a></li>\n</ol>\n</div>" {
-		t.Fatalf("Got content:\n%q", c)
+	cnt := content(p)
+	if cnt != "<p>The <a href=\"http://gohugo.io/\">best static site generator</a>.<sup class=\"footnote-ref\" id=\"fnref:1\"><a href=\"#fn:1\">1</a></sup></p>\n\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:1\">Many people say so.\n <a class=\"footnote-return\" href=\"#fnref:1\"><sup>[return]</sup></a></li>\n</ol>\n</div>" {
+		t.Fatalf("Got content:\n%q", cnt)
 	}
 }
 
 func TestPageDatesAllKinds(t *testing.T) {
 	t.Parallel()
-	assert := assert.New(t)
 
 	pageContent := `
 ---
@@ -479,11 +477,11 @@
 
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
+	b.Assert(len(b.H.Sites), qt.Equals, 1)
 	s := b.H.Sites[0]
 
 	checkDate := func(t time.Time, msg string) {
-		assert.Equal(2017, t.Year(), msg)
+		b.Assert(t.Year(), qt.Equals, 2017)
 	}
 
 	checkDated := func(d resource.Dated, msg string) {
@@ -499,7 +497,6 @@
 
 func TestPageDatesSections(t *testing.T) {
 	t.Parallel()
-	assert := assert.New(t)
 
 	b := newTestSitesBuilder(t)
 	b.WithSimpleConfigFile().WithContent("no-index/page.md", `
@@ -524,23 +521,24 @@
 
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
+	b.Assert(len(b.H.Sites), qt.Equals, 1)
 	s := b.H.Sites[0]
 
-	assert.Equal(2017, s.getPage("/").Date().Year())
-	assert.Equal(2017, s.getPage("/no-index").Date().Year())
-	assert.True(s.getPage("/with-index-no-date").Date().IsZero())
-	assert.Equal(2018, s.getPage("/with-index-date").Date().Year())
+	b.Assert(s.getPage("/").Date().Year(), qt.Equals, 2017)
+	b.Assert(s.getPage("/no-index").Date().Year(), qt.Equals, 2017)
+	b.Assert(s.getPage("/with-index-no-date").Date().IsZero(), qt.Equals, true)
+	b.Assert(s.getPage("/with-index-date").Date().Year(), qt.Equals, 2018)
 }
 
 func TestCreateNewPage(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	assertFunc := func(t *testing.T, ext string, pages page.Pages) {
 		p := pages[0]
 
 		// issue #2290: Path is relative to the content dir and will continue to be so.
-		require.Equal(t, filepath.FromSlash(fmt.Sprintf("p0.%s", ext)), p.File().Path())
-		assert.False(t, p.IsHome())
+		c.Assert(p.File().Path(), qt.Equals, fmt.Sprintf("p0.%s", ext))
+		c.Assert(p.IsHome(), qt.Equals, false)
 		checkPageTitle(t, p, "Simple")
 		checkPageContent(t, p, normalizeExpected(ext, "<p>Simple Page</p>\n"))
 		checkPageSummary(t, p, "Simple Page")
@@ -602,7 +600,7 @@
 // Issue #3854
 // Also see https://github.com/gohugoio/hugo/issues/3977
 func TestPageWithDateFields(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	pageWithDate := `---
 title: P%d
 weight: %d
@@ -620,9 +618,9 @@
 
 	t.Parallel()
 	assertFunc := func(t *testing.T, ext string, pages page.Pages) {
-		assert.True(len(pages) > 0)
+		c.Assert(len(pages) > 0, qt.Equals, true)
 		for _, p := range pages {
-			assert.True(hasDate(p))
+			c.Assert(hasDate(p), qt.Equals, true)
 		}
 
 	}
@@ -640,6 +638,7 @@
 func TestPageRawContent(t *testing.T) {
 	t.Parallel()
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	writeSource(t, fs, filepath.Join("content", "raw.md"), `---
 title: Raw
@@ -650,10 +649,10 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.Len(t, s.RegularPages(), 1)
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 	p := s.RegularPages()[0]
 
-	require.Equal(t, p.RawContent(), "**Raw**")
+	c.Assert("**Raw**", qt.Equals, p.RawContent())
 
 }
 
@@ -687,12 +686,13 @@
 func TestPageWithAdditionalExtension(t *testing.T) {
 	t.Parallel()
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	writeSource(t, fs, filepath.Join("content", "simple.md"), simplePageWithAdditionalExtension)
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.Len(t, s.RegularPages(), 1)
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	p := s.RegularPages()[0]
 
@@ -702,12 +702,13 @@
 func TestTableOfContents(t *testing.T) {
 
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	writeSource(t, fs, filepath.Join("content", "tocpage.md"), pageWithToC)
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.Len(t, s.RegularPages(), 1)
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	p := s.RegularPages()[0]
 
@@ -733,9 +734,11 @@
 func TestSummaryWithHTMLTagsOnNextLine(t *testing.T) {
 
 	assertFunc := func(t *testing.T, ext string, pages page.Pages) {
+		c := qt.New(t)
 		p := pages[0]
-		require.Contains(t, p.Summary(), "Happy new year everyone!")
-		require.NotContains(t, p.Summary(), "User interface")
+		s := string(p.Summary())
+		c.Assert(s, qt.Contains, "Happy new year everyone!")
+		c.Assert(s, qt.Not(qt.Contains), "User interface")
 	}
 
 	testAllMarkdownEnginesForPages(t, assertFunc, nil, `---
@@ -755,12 +758,13 @@
 func TestPageWithDate(t *testing.T) {
 	t.Parallel()
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	writeSource(t, fs, filepath.Join("content", "simple.md"), simplePageRFC3339Date)
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.Len(t, s.RegularPages(), 1)
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	p := s.RegularPages()[0]
 	d, _ := time.Parse(time.RFC3339, "2013-05-17T16:59:30Z")
@@ -769,7 +773,7 @@
 }
 
 func TestPageWithLastmodFromGitInfo(t *testing.T) {
-	assrt := require.New(t)
+	c := qt.New(t)
 
 	// We need to use the OS fs for this.
 	cfg := viper.New()
@@ -777,7 +781,7 @@
 	fs.Destination = &afero.MemMapFs{}
 
 	wd, err := os.Getwd()
-	assrt.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	cfg.Set("frontmatter", map[string]interface{}{
 		"lastmod": []string{":git", "lastmod"},
@@ -807,19 +811,19 @@
 	b.Build(BuildCfg{SkipRender: true})
 	h := b.H
 
-	assrt.Len(h.Sites, 2)
+	c.Assert(len(h.Sites), qt.Equals, 2)
 
 	enSite := h.Sites[0]
-	assrt.Len(enSite.RegularPages(), 1)
+	c.Assert(len(enSite.RegularPages()), qt.Equals, 1)
 
 	// 2018-03-11 is the Git author date for testsite/content/first-post.md
-	assrt.Equal("2018-03-11", enSite.RegularPages()[0].Lastmod().Format("2006-01-02"))
+	c.Assert(enSite.RegularPages()[0].Lastmod().Format("2006-01-02"), qt.Equals, "2018-03-11")
 
 	nnSite := h.Sites[1]
-	assrt.Len(nnSite.RegularPages(), 1)
+	c.Assert(len(nnSite.RegularPages()), qt.Equals, 1)
 
 	// 2018-08-11 is the Git author date for testsite/content_nn/first-post.md
-	assrt.Equal("2018-08-11", nnSite.RegularPages()[0].Lastmod().Format("2006-01-02"))
+	c.Assert(nnSite.RegularPages()[0].Lastmod().Format("2006-01-02"), qt.Equals, "2018-08-11")
 
 }
 
@@ -828,7 +832,7 @@
 		dateHandler := dateHandler
 		t.Run(fmt.Sprintf("dateHandler=%q", dateHandler), func(t *testing.T) {
 			t.Parallel()
-			assrt := require.New(t)
+			c := qt.New(t)
 			cfg, fs := newTestCfg()
 
 			pageTemplate := `
@@ -852,36 +856,36 @@
 			writeSource(t, fs, c2, fmt.Sprintf(pageTemplate, 2, "slug: aslug"))
 
 			c1fi, err := fs.Source.Stat(c1)
-			assrt.NoError(err)
+			c.Assert(err, qt.IsNil)
 			c2fi, err := fs.Source.Stat(c2)
-			assrt.NoError(err)
+			c.Assert(err, qt.IsNil)
 
 			b := newTestSitesBuilderFromDepsCfg(t, deps.DepsCfg{Fs: fs, Cfg: cfg}).WithNothingAdded()
 			b.Build(BuildCfg{SkipRender: true})
 
 			s := b.H.Sites[0]
-			assrt.Len(s.RegularPages(), 2)
+			c.Assert(len(s.RegularPages()), qt.Equals, 2)
 
 			noSlug := s.RegularPages()[0]
 			slug := s.RegularPages()[1]
 
-			assrt.Equal(28, noSlug.Lastmod().Day())
+			c.Assert(noSlug.Lastmod().Day(), qt.Equals, 28)
 
 			switch strings.ToLower(dateHandler) {
 			case ":filename":
-				assrt.False(noSlug.Date().IsZero())
-				assrt.False(slug.Date().IsZero())
-				assrt.Equal(2012, noSlug.Date().Year())
-				assrt.Equal(2012, slug.Date().Year())
-				assrt.Equal("noslug", noSlug.Slug())
-				assrt.Equal("aslug", slug.Slug())
+				c.Assert(noSlug.Date().IsZero(), qt.Equals, false)
+				c.Assert(slug.Date().IsZero(), qt.Equals, false)
+				c.Assert(noSlug.Date().Year(), qt.Equals, 2012)
+				c.Assert(slug.Date().Year(), qt.Equals, 2012)
+				c.Assert(noSlug.Slug(), qt.Equals, "noslug")
+				c.Assert(slug.Slug(), qt.Equals, "aslug")
 			case ":filemodtime":
-				assrt.Equal(c1fi.ModTime().Year(), noSlug.Date().Year())
-				assrt.Equal(c2fi.ModTime().Year(), slug.Date().Year())
+				c.Assert(noSlug.Date().Year(), qt.Equals, c1fi.ModTime().Year())
+				c.Assert(slug.Date().Year(), qt.Equals, c2fi.ModTime().Year())
 				fallthrough
 			default:
-				assrt.Equal("", noSlug.Slug())
-				assrt.Equal("aslug", slug.Slug())
+				c.Assert(noSlug.Slug(), qt.Equals, "")
+				c.Assert(slug.Slug(), qt.Equals, "aslug")
 
 			}
 		})
@@ -978,6 +982,7 @@
 
 func TestPagePaths(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	siteParmalinksSetting := map[string]string{
 		"post": ":year/:month/:day/:title/",
@@ -1009,7 +1014,7 @@
 		writeSource(t, fs, filepath.Join("content", filepath.FromSlash(test.path)), test.content)
 
 		s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
-		require.Len(t, s.RegularPages(), 1)
+		c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	}
 }
@@ -1016,7 +1021,7 @@
 
 func TestTranslationKey(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 	cfg, fs := newTestCfg()
 
 	writeSource(t, fs, filepath.Join("content", filepath.FromSlash("sect/simple.no.md")), "---\ntitle: \"A1\"\ntranslationKey: \"k1\"\n---\nContent\n")
@@ -1024,20 +1029,21 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.Len(t, s.RegularPages(), 2)
+	c.Assert(len(s.RegularPages()), qt.Equals, 2)
 
 	home, _ := s.Info.Home()
-	assert.NotNil(home)
-	assert.Equal("home", home.TranslationKey())
-	assert.Equal("page/k1", s.RegularPages()[0].TranslationKey())
+	c.Assert(home, qt.Not(qt.IsNil))
+	c.Assert(home.TranslationKey(), qt.Equals, "home")
+	c.Assert(s.RegularPages()[0].TranslationKey(), qt.Equals, "page/k1")
 	p2 := s.RegularPages()[1]
 
-	assert.Equal("page/sect/simple", p2.TranslationKey())
+	c.Assert(p2.TranslationKey(), qt.Equals, "page/sect/simple")
 
 }
 
 func TestChompBOM(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	const utf8BOM = "\xef\xbb\xbf"
 
 	cfg, fs := newTestCfg()
@@ -1046,7 +1052,7 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.Len(t, s.RegularPages(), 1)
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	p := s.RegularPages()[0]
 
@@ -1340,7 +1346,8 @@
 			t.Run(fmt.Sprintf("disablePathToLower=%t,uglyURLs=%t", disablePathToLower, uglyURLs), func(t *testing.T) {
 				t.Parallel()
 				cfg, fs := newTestCfg()
-				th := testHelper{cfg, fs, t}
+				th := newTestHelper(cfg, fs, t)
+				c := qt.New(t)
 
 				cfg.Set("permalinks", map[string]string{
 					"post": ":section/:title",
@@ -1376,7 +1383,7 @@
 
 				s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
 
-				require.Len(t, s.RegularPages(), 4)
+				c.Assert(len(s.RegularPages()), qt.Equals, 4)
 
 				pathFunc := func(s string) string {
 					if uglyURLs {
@@ -1409,9 +1416,9 @@
 
 				p := s.RegularPages()[0]
 				if uglyURLs {
-					require.Equal(t, "/post/test0.dot.html", p.RelPermalink())
+					c.Assert(p.RelPermalink(), qt.Equals, "/post/test0.dot.html")
 				} else {
-					require.Equal(t, "/post/test0.dot/", p.RelPermalink())
+					c.Assert(p.RelPermalink(), qt.Equals, "/post/test0.dot/")
 				}
 
 			})
@@ -1423,7 +1430,7 @@
 func TestWordCountAndSimilarVsSummary(t *testing.T) {
 
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	single := []string{"_default/single.html", `
 WordCount: {{ .WordCount }}
@@ -1502,8 +1509,8 @@
 
 	b.CreateSites().Build(BuildCfg{})
 
-	assert.Equal(1, len(b.H.Sites))
-	require.Len(t, b.H.Sites[0].RegularPages(), 6)
+	c.Assert(len(b.H.Sites), qt.Equals, 1)
+	c.Assert(len(b.H.Sites[0].RegularPages()), qt.Equals, 6)
 
 	b.AssertFileContent("public/p1/index.html", "WordCount: 510\nFuzzyWordCount: 600\nReadingTime: 3\nLen Plain: 2550\nLen PlainWords: 510\nTruncated: false\nLen Summary: 2549\nLen Content: 2557")
 
--- a/hugolib/page_unwrap_test.go
+++ b/hugolib/page_unwrap_test.go
@@ -16,16 +16,16 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/resources/page"
-	"github.com/stretchr/testify/require"
 )
 
 func TestUnwrapPage(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	p := &pageState{}
 
-	assert.Equal(p, mustUnwrap(newPageForShortcode(p)))
+	c.Assert(mustUnwrap(newPageForShortcode(p)), qt.Equals, p)
 }
 
 func mustUnwrap(v interface{}) page.Page {
--- a/hugolib/pagebundler_test.go
+++ b/hugolib/pagebundler_test.go
@@ -38,7 +38,7 @@
 	"github.com/gohugoio/hugo/deps"
 	"github.com/spf13/viper"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestPageBundlerSiteRegular(t *testing.T) {
@@ -63,7 +63,7 @@
 						if canonify {
 							relURLBase = ""
 						}
-						assert := require.New(t)
+						c := qt.New(t)
 						fs, cfg := newTestBundleSources(t)
 						cfg.Set("baseURL", baseURL)
 						cfg.Set("canonifyURLs", canonify)
@@ -98,16 +98,16 @@
 
 						s := b.H.Sites[0]
 
-						assert.Len(s.RegularPages(), 8)
+						c.Assert(len(s.RegularPages()), qt.Equals, 8)
 
 						singlePage := s.getPage(page.KindPage, "a/1.md")
-						assert.Equal("", singlePage.BundleType())
+						c.Assert(singlePage.BundleType(), qt.Equals, "")
 
-						assert.NotNil(singlePage)
-						assert.Equal(singlePage, s.getPage("page", "a/1"))
-						assert.Equal(singlePage, s.getPage("page", "1"))
+						c.Assert(singlePage, qt.Not(qt.IsNil))
+						c.Assert(s.getPage("page", "a/1"), qt.Equals, singlePage)
+						c.Assert(s.getPage("page", "1"), qt.Equals, singlePage)
 
-						assert.Contains(content(singlePage), "TheContent")
+						c.Assert(content(singlePage), qt.Contains, "TheContent")
 
 						relFilename := func(basePath, outBase string) (string, string) {
 							rel := basePath
@@ -147,19 +147,19 @@
 						b.AssertFileContent(filepath.FromSlash("/work/public/assets/pic1.png"), "content")
 
 						leafBundle1 := s.getPage(page.KindPage, "b/my-bundle/index.md")
-						assert.NotNil(leafBundle1)
-						assert.Equal("leaf", leafBundle1.BundleType())
-						assert.Equal("b", leafBundle1.Section())
+						c.Assert(leafBundle1, qt.Not(qt.IsNil))
+						c.Assert(leafBundle1.BundleType(), qt.Equals, "leaf")
+						c.Assert(leafBundle1.Section(), qt.Equals, "b")
 						sectionB := s.getPage(page.KindSection, "b")
-						assert.NotNil(sectionB)
+						c.Assert(sectionB, qt.Not(qt.IsNil))
 						home, _ := s.Info.Home()
-						assert.Equal("branch", home.BundleType())
+						c.Assert(home.BundleType(), qt.Equals, "branch")
 
 						// This is a root bundle and should live in the "home section"
 						// See https://github.com/gohugoio/hugo/issues/4332
 						rootBundle := s.getPage(page.KindPage, "root")
-						assert.NotNil(rootBundle)
-						assert.True(rootBundle.Parent().IsHome())
+						c.Assert(rootBundle, qt.Not(qt.IsNil))
+						c.Assert(rootBundle.Parent().IsHome(), qt.Equals, true)
 						if !ugly {
 							b.AssertFileContent(filepath.FromSlash("/work/public/root/index.html"), "Single RelPermalink: "+relURLBase+"/root/")
 							b.AssertFileContent(filepath.FromSlash("/work/public/cpath/root/cindex.html"), "Single RelPermalink: "+relURLBase+"/cpath/root/")
@@ -166,34 +166,34 @@
 						}
 
 						leafBundle2 := s.getPage(page.KindPage, "a/b/index.md")
-						assert.NotNil(leafBundle2)
+						c.Assert(leafBundle2, qt.Not(qt.IsNil))
 						unicodeBundle := s.getPage(page.KindPage, "c/bundle/index.md")
-						assert.NotNil(unicodeBundle)
+						c.Assert(unicodeBundle, qt.Not(qt.IsNil))
 
 						pageResources := leafBundle1.Resources().ByType(pageResourceType)
-						assert.Len(pageResources, 2)
+						c.Assert(len(pageResources), qt.Equals, 2)
 						firstPage := pageResources[0].(page.Page)
 						secondPage := pageResources[1].(page.Page)
 
-						assert.Equal(filepath.FromSlash("/work/base/b/my-bundle/1.md"), firstPage.File().Filename(), secondPage.File().Filename())
-						assert.Contains(content(firstPage), "TheContent")
-						assert.Equal(6, len(leafBundle1.Resources()))
+						c.Assert(firstPage.File().Filename(), qt.Equals, filepath.FromSlash("/work/base/b/my-bundle/1.md"))
+						c.Assert(content(firstPage), qt.Contains, "TheContent")
+						c.Assert(len(leafBundle1.Resources()), qt.Equals, 6)
 
 						// Verify shortcode in bundled page
-						assert.Contains(content(secondPage), filepath.FromSlash("MyShort in b/my-bundle/2.md"))
+						c.Assert(content(secondPage), qt.Contains, filepath.FromSlash("MyShort in b/my-bundle/2.md"))
 
 						// https://github.com/gohugoio/hugo/issues/4582
-						assert.Equal(leafBundle1, firstPage.Parent())
-						assert.Equal(leafBundle1, secondPage.Parent())
+						c.Assert(firstPage.Parent(), qt.Equals, leafBundle1)
+						c.Assert(secondPage.Parent(), qt.Equals, leafBundle1)
 
-						assert.Equal(firstPage, pageResources.GetMatch("1*"))
-						assert.Equal(secondPage, pageResources.GetMatch("2*"))
-						assert.Nil(pageResources.GetMatch("doesnotexist*"))
+						c.Assert(pageResources.GetMatch("1*"), qt.Equals, firstPage)
+						c.Assert(pageResources.GetMatch("2*"), qt.Equals, secondPage)
+						c.Assert(pageResources.GetMatch("doesnotexist*"), qt.IsNil)
 
 						imageResources := leafBundle1.Resources().ByType("image")
-						assert.Equal(3, len(imageResources))
+						c.Assert(len(imageResources), qt.Equals, 3)
 
-						assert.NotNil(leafBundle1.OutputFormats().Get("CUSTOMO"))
+						c.Assert(leafBundle1.OutputFormats().Get("CUSTOMO"), qt.Not(qt.IsNil))
 
 						relPermalinker := func(s string) string {
 							return fmt.Sprintf(s, relURLBase)
@@ -224,10 +224,10 @@
 
 						b.AssertFileContent(filepath.FromSlash("/work/public/2017/pageslug/c/logo.png"), "content")
 						b.AssertFileContent(filepath.FromSlash("/work/public/cpath/2017/pageslug/c/logo.png"), "content")
-						assert.False(b.CheckExists("/work/public/cpath/cpath/2017/pageslug/c/logo.png"))
+						c.Assert(b.CheckExists("/work/public/cpath/cpath/2017/pageslug/c/logo.png"), qt.Equals, false)
 
 						// Custom media type defined in site config.
-						assert.Len(leafBundle1.Resources().ByType("bepsays"), 1)
+						c.Assert(len(leafBundle1.Resources().ByType("bepsays")), qt.Equals, 1)
 
 						if ugly {
 							b.AssertFileContent(filepath.FromSlash("/work/public/2017/pageslug.html"),
@@ -279,7 +279,7 @@
 		t.Run(fmt.Sprintf("ugly=%t", ugly),
 			func(t *testing.T) {
 				t.Parallel()
-				assert := require.New(t)
+				c := qt.New(t)
 				fs, cfg := newTestBundleSourcesMultilingual(t)
 				cfg.Set("uglyURLs", ugly)
 
@@ -288,17 +288,17 @@
 
 				sites := b.H
 
-				assert.Equal(2, len(sites.Sites))
+				c.Assert(len(sites.Sites), qt.Equals, 2)
 
 				s := sites.Sites[0]
 
-				assert.Equal(8, len(s.RegularPages()))
-				assert.Equal(16, len(s.Pages()))
+				c.Assert(len(s.RegularPages()), qt.Equals, 8)
+				c.Assert(len(s.Pages()), qt.Equals, 16)
 				//dumpPages(s.AllPages()...)
-				assert.Equal(31, len(s.AllPages()))
+				c.Assert(len(s.AllPages()), qt.Equals, 31)
 
 				bundleWithSubPath := s.getPage(page.KindPage, "lb/index")
-				assert.NotNil(bundleWithSubPath)
+				c.Assert(bundleWithSubPath, qt.Not(qt.IsNil))
 
 				// See https://github.com/gohugoio/hugo/issues/4312
 				// Before that issue:
@@ -312,37 +312,36 @@
 				// These may also be translated, so we also need to test that.
 				//  "bf", "my-bf-bundle", "index.md + nn
 				bfBundle := s.getPage(page.KindPage, "bf/my-bf-bundle/index")
-				assert.NotNil(bfBundle)
-				assert.Equal("en", bfBundle.Language().Lang)
-				assert.Equal(bfBundle, s.getPage(page.KindPage, "bf/my-bf-bundle/index.md"))
-				assert.Equal(bfBundle, s.getPage(page.KindPage, "bf/my-bf-bundle"))
-				assert.Equal(bfBundle, s.getPage(page.KindPage, "my-bf-bundle"))
+				c.Assert(bfBundle, qt.Not(qt.IsNil))
+				c.Assert(bfBundle.Language().Lang, qt.Equals, "en")
+				c.Assert(s.getPage(page.KindPage, "bf/my-bf-bundle/index.md"), qt.Equals, bfBundle)
+				c.Assert(s.getPage(page.KindPage, "bf/my-bf-bundle"), qt.Equals, bfBundle)
+				c.Assert(s.getPage(page.KindPage, "my-bf-bundle"), qt.Equals, bfBundle)
 
 				nnSite := sites.Sites[1]
-				assert.Equal(7, len(nnSite.RegularPages()))
+				c.Assert(len(nnSite.RegularPages()), qt.Equals, 7)
 
 				bfBundleNN := nnSite.getPage(page.KindPage, "bf/my-bf-bundle/index")
-				assert.NotNil(bfBundleNN)
-				assert.Equal("nn", bfBundleNN.Language().Lang)
-				assert.Equal(bfBundleNN, nnSite.getPage(page.KindPage, "bf/my-bf-bundle/index.nn.md"))
-				assert.Equal(bfBundleNN, nnSite.getPage(page.KindPage, "bf/my-bf-bundle"))
-				assert.Equal(bfBundleNN, nnSite.getPage(page.KindPage, "my-bf-bundle"))
+				c.Assert(bfBundleNN, qt.Not(qt.IsNil))
+				c.Assert(bfBundleNN.Language().Lang, qt.Equals, "nn")
+				c.Assert(nnSite.getPage(page.KindPage, "bf/my-bf-bundle/index.nn.md"), qt.Equals, bfBundleNN)
+				c.Assert(nnSite.getPage(page.KindPage, "bf/my-bf-bundle"), qt.Equals, bfBundleNN)
+				c.Assert(nnSite.getPage(page.KindPage, "my-bf-bundle"), qt.Equals, bfBundleNN)
 
 				// See https://github.com/gohugoio/hugo/issues/4295
 				// Every resource should have its Name prefixed with its base folder.
 				cBundleResources := bundleWithSubPath.Resources().Match("c/**")
-				assert.Equal(4, len(cBundleResources))
+				c.Assert(len(cBundleResources), qt.Equals, 4)
 				bundlePage := bundleWithSubPath.Resources().GetMatch("c/page*")
-				assert.NotNil(bundlePage)
-				assert.IsType(&pageState{}, bundlePage)
+				c.Assert(bundlePage, qt.Not(qt.IsNil))
 
 				bcBundleNN, _ := nnSite.getPageNew(nil, "bc")
-				assert.NotNil(bcBundleNN)
+				c.Assert(bcBundleNN, qt.Not(qt.IsNil))
 				bcBundleEN, _ := s.getPageNew(nil, "bc")
-				assert.Equal("nn", bcBundleNN.Language().Lang)
-				assert.Equal("en", bcBundleEN.Language().Lang)
-				assert.Equal(3, len(bcBundleNN.Resources()))
-				assert.Equal(3, len(bcBundleEN.Resources()))
+				c.Assert(bcBundleNN.Language().Lang, qt.Equals, "nn")
+				c.Assert(bcBundleEN.Language().Lang, qt.Equals, "en")
+				c.Assert(len(bcBundleNN.Resources()), qt.Equals, 3)
+				c.Assert(len(bcBundleEN.Resources()), qt.Equals, 3)
 				b.AssertFileContent("public/en/bc/data1.json", "data1")
 				b.AssertFileContent("public/en/bc/data2.json", "data2")
 				b.AssertFileContent("public/en/bc/logo-bc.png", "logo")
@@ -357,22 +356,22 @@
 func TestMultilingualDisableDefaultLanguage(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 	_, cfg := newTestBundleSourcesMultilingual(t)
 
 	cfg.Set("disableLanguages", []string{"en"})
 
 	err := loadDefaultSettingsFor(cfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	err = loadLanguageSettings(cfg, nil)
-	assert.Error(err)
-	assert.Contains(err.Error(), "cannot disable default language")
+	c.Assert(err, qt.Not(qt.IsNil))
+	c.Assert(err.Error(), qt.Contains, "cannot disable default language")
 }
 
 func TestMultilingualDisableLanguage(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 	fs, cfg := newTestBundleSourcesMultilingual(t)
 	cfg.Set("disableLanguages", []string{"nn"})
 
@@ -380,19 +379,19 @@
 	b.Build(BuildCfg{})
 	sites := b.H
 
-	assert.Equal(1, len(sites.Sites))
+	c.Assert(len(sites.Sites), qt.Equals, 1)
 
 	s := sites.Sites[0]
 
-	assert.Equal(8, len(s.RegularPages()))
-	assert.Equal(16, len(s.Pages()))
+	c.Assert(len(s.RegularPages()), qt.Equals, 8)
+	c.Assert(len(s.Pages()), qt.Equals, 16)
 	// No nn pages
-	assert.Equal(16, len(s.AllPages()))
+	c.Assert(len(s.AllPages()), qt.Equals, 16)
 	for _, p := range s.rawAllPages {
-		assert.True(p.Language().Lang != "nn")
+		c.Assert(p.Language().Lang != "nn", qt.Equals, true)
 	}
 	for _, p := range s.AllPages() {
-		assert.True(p.Language().Lang != "nn")
+		c.Assert(p.Language().Lang != "nn", qt.Equals, true)
 	}
 
 }
@@ -405,42 +404,42 @@
 		os.Chdir(wd)
 	}()
 
-	assert := require.New(t)
+	c := qt.New(t)
 	// We need to use the OS fs for this.
 	cfg := viper.New()
 	fs := hugofs.NewFrom(hugofs.Os, cfg)
 
 	workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugosym")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	contentDirName := "content"
 
 	contentDir := filepath.Join(workDir, contentDirName)
-	assert.NoError(os.MkdirAll(filepath.Join(contentDir, "a"), 0777))
+	c.Assert(os.MkdirAll(filepath.Join(contentDir, "a"), 0777), qt.IsNil)
 
 	for i := 1; i <= 3; i++ {
-		assert.NoError(os.MkdirAll(filepath.Join(workDir, fmt.Sprintf("symcontent%d", i)), 0777))
+		c.Assert(os.MkdirAll(filepath.Join(workDir, fmt.Sprintf("symcontent%d", i)), 0777), qt.IsNil)
 	}
 
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "symcontent2", "a1"), 0777))
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "symcontent2", "a1"), 0777), qt.IsNil)
 
 	// Symlinked sections inside content.
 	os.Chdir(contentDir)
 	for i := 1; i <= 3; i++ {
-		assert.NoError(os.Symlink(filepath.FromSlash(fmt.Sprintf(("../symcontent%d"), i)), fmt.Sprintf("symbolic%d", i)))
+		c.Assert(os.Symlink(filepath.FromSlash(fmt.Sprintf(("../symcontent%d"), i)), fmt.Sprintf("symbolic%d", i)), qt.IsNil)
 	}
 
-	assert.NoError(os.Chdir(filepath.Join(contentDir, "a")))
+	c.Assert(os.Chdir(filepath.Join(contentDir, "a")), qt.IsNil)
 
 	// Create a symlink to one single content file
-	assert.NoError(os.Symlink(filepath.FromSlash("../../symcontent2/a1/page.md"), "page_s.md"))
+	c.Assert(os.Symlink(filepath.FromSlash("../../symcontent2/a1/page.md"), "page_s.md"), qt.IsNil)
 
-	assert.NoError(os.Chdir(filepath.FromSlash("../../symcontent3")))
+	c.Assert(os.Chdir(filepath.FromSlash("../../symcontent3")), qt.IsNil)
 
 	// Create a circular symlink. Will print some warnings.
-	assert.NoError(os.Symlink(filepath.Join("..", contentDirName), filepath.FromSlash("circus")))
+	c.Assert(os.Symlink(filepath.Join("..", contentDirName), filepath.FromSlash("circus")), qt.IsNil)
 
-	assert.NoError(os.Chdir(workDir))
+	c.Assert(os.Chdir(workDir), qt.IsNil)
 
 	defer clean()
 
@@ -491,11 +490,11 @@
 	b.Build(BuildCfg{})
 	s := b.H.Sites[0]
 
-	assert.Equal(7, len(s.RegularPages()))
+	c.Assert(len(s.RegularPages()), qt.Equals, 7)
 	a1Bundle := s.getPage(page.KindPage, "symbolic2/a1/index.md")
-	assert.NotNil(a1Bundle)
-	assert.Equal(2, len(a1Bundle.Resources()))
-	assert.Equal(1, len(a1Bundle.Resources().ByType(pageResourceType)))
+	c.Assert(a1Bundle, qt.Not(qt.IsNil))
+	c.Assert(len(a1Bundle.Resources()), qt.Equals, 2)
+	c.Assert(len(a1Bundle.Resources().ByType(pageResourceType)), qt.Equals, 1)
 
 	b.AssertFileContent(filepath.FromSlash(workDir+"/public/a/page/index.html"), "TheContent")
 	b.AssertFileContent(filepath.FromSlash(workDir+"/public/symbolic1/s1/index.html"), "TheContent")
@@ -507,7 +506,7 @@
 	t.Parallel()
 
 	cfg, fs := newTestCfg()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	workDir := "/work"
 	cfg.Set("workingDir", workDir)
@@ -549,30 +548,29 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
 
-	assert.Equal(1, len(s.RegularPages()))
-	assert.Equal(1, len(s.headlessPages))
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
+	c.Assert(len(s.headlessPages), qt.Equals, 1)
 
 	regular := s.getPage(page.KindPage, "a/index")
-	assert.Equal("/s1/", regular.RelPermalink())
+	c.Assert(regular.RelPermalink(), qt.Equals, "/s1/")
 
 	headless := s.getPage(page.KindPage, "b/index")
-	assert.NotNil(headless)
-	assert.Equal("Headless Bundle in Topless Bar", headless.Title())
-	assert.Equal("", headless.RelPermalink())
-	assert.Equal("", headless.Permalink())
-	assert.Contains(content(headless), "HEADLESS SHORTCODE")
+	c.Assert(headless, qt.Not(qt.IsNil))
+	c.Assert(headless.Title(), qt.Equals, "Headless Bundle in Topless Bar")
+	c.Assert(headless.RelPermalink(), qt.Equals, "")
+	c.Assert(headless.Permalink(), qt.Equals, "")
+	c.Assert(content(headless), qt.Contains, "HEADLESS SHORTCODE")
 
 	headlessResources := headless.Resources()
-	assert.Equal(3, len(headlessResources))
-	assert.Equal(2, len(headlessResources.Match("l*")))
+	c.Assert(len(headlessResources), qt.Equals, 3)
+	c.Assert(len(headlessResources.Match("l*")), qt.Equals, 2)
 	pageResource := headlessResources.GetMatch("p*")
-	assert.NotNil(pageResource)
-	assert.IsType(&pageState{}, pageResource)
+	c.Assert(pageResource, qt.Not(qt.IsNil))
 	p := pageResource.(page.Page)
-	assert.Contains(content(p), "SHORTCODE")
-	assert.Equal("p1.md", p.Name())
+	c.Assert(content(p), qt.Contains, "SHORTCODE")
+	c.Assert(p.Name(), qt.Equals, "p1.md")
 
-	th := testHelper{s.Cfg, s.Fs, t}
+	th := newTestHelper(s.Cfg, s.Fs, t)
 
 	th.assertFileContent(filepath.FromSlash(workDir+"/public/s1/index.html"), "TheContent")
 	th.assertFileContent(filepath.FromSlash(workDir+"/public/s1/l1.png"), "PNG")
@@ -584,7 +582,7 @@
 }
 
 func TestMultiSiteBundles(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	b := newTestSitesBuilder(t)
 	b.WithConfigFile("toml", `
 
@@ -656,12 +654,12 @@
 	b.AssertFileContent("public/mybundle/data.yaml", "data en")
 	b.AssertFileContent("public/mybundle/forms.yaml", "forms en")
 
-	assert.False(b.CheckExists("public/nn/nn/mybundle/data.yaml"))
-	assert.False(b.CheckExists("public/en/mybundle/data.yaml"))
+	c.Assert(b.CheckExists("public/nn/nn/mybundle/data.yaml"), qt.Equals, false)
+	c.Assert(b.CheckExists("public/en/mybundle/data.yaml"), qt.Equals, false)
 
 	homeEn := b.H.Sites[0].home
-	assert.NotNil(homeEn)
-	assert.Equal(2018, homeEn.Date().Year())
+	c.Assert(homeEn, qt.Not(qt.IsNil))
+	c.Assert(homeEn.Date().Year(), qt.Equals, 2018)
 
 	b.AssertFileContent("public/section-not-bundle/index.html", "Section Page", "Content: <p>Section content.</p>")
 	b.AssertFileContent("public/section-not-bundle/single/index.html", "Section Single", "|<p>Single content.</p>")
@@ -670,7 +668,7 @@
 
 func newTestBundleSources(t *testing.T) (*hugofs.Fs, *viper.Viper) {
 	cfg, fs := newTestCfgBasic()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	workDir := "/work"
 	cfg.Set("workingDir", workDir)
@@ -814,22 +812,22 @@
 
 	// Write a real image into one of the bundle above.
 	src, err := os.Open("testdata/sunset.jpg")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	// We need 2 to test https://github.com/gohugoio/hugo/issues/4202
 	out, err := fs.Source.Create(filepath.Join(workDir, "base", "b", "my-bundle", "sunset1.jpg"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	out2, err := fs.Source.Create(filepath.Join(workDir, "base", "b", "my-bundle", "sunset2.jpg"))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	_, err = io.Copy(out, src)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	out.Close()
 	src.Seek(0, 0)
 	_, err = io.Copy(out2, src)
 	out2.Close()
 	src.Close()
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	return fs, cfg
 
@@ -959,7 +957,7 @@
 // https://github.com/gohugoio/hugo/issues/4870
 func TestBundleSlug(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	const pageTemplate = `---
 title: Title
@@ -980,8 +978,8 @@
 		"|/about/services1/this-is-the-slug/|/",
 		"|/about/services2/this-is-another-slug/|")
 
-	assert.True(b.CheckExists("public/about/services1/this-is-the-slug/index.html"))
-	assert.True(b.CheckExists("public/about/services2/this-is-another-slug/index.html"))
+	c.Assert(b.CheckExists("public/about/services1/this-is-the-slug/index.html"), qt.Equals, true)
+	c.Assert(b.CheckExists("public/about/services2/this-is-another-slug/index.html"), qt.Equals, true)
 
 }
 
@@ -1087,8 +1085,8 @@
 	b.AssertFileContent("public/en/enonly/myen/index.html", "Single: en: Page")
 	b.AssertFileContent("public/en/enonly/myendata.json", "mydata")
 
-	assert := require.New(t)
-	assert.False(b.CheckExists("public/sv/enonly/myen/index.html"))
+	c := qt.New(t)
+	c.Assert(b.CheckExists("public/sv/enonly/myen/index.html"), qt.Equals, false)
 
 	// Both leaf and branch bundle in same dir
 	// We log a warning about it, but we keep both.
--- a/hugolib/pagecollections_test.go
+++ b/hugolib/pagecollections_test.go
@@ -21,10 +21,10 @@
 	"testing"
 	"time"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/resources/page"
 
 	"github.com/gohugoio/hugo/deps"
-	"github.com/stretchr/testify/require"
 )
 
 const pageCollectionsPageTemplate = `---
@@ -72,6 +72,7 @@
 
 func BenchmarkGetPageRegular(b *testing.B) {
 	var (
+		c       = qt.New(b)
 		cfg, fs = newTestCfg()
 		r       = rand.New(rand.NewSource(time.Now().UnixNano()))
 	)
@@ -94,7 +95,7 @@
 	b.ResetTimer()
 	for i := 0; i < b.N; i++ {
 		page, _ := s.getPageNew(nil, pagePaths[i])
-		require.NotNil(b, page)
+		c.Assert(page, qt.Not(qt.IsNil))
 	}
 }
 
@@ -105,19 +106,20 @@
 	expectedTitle string
 }
 
-func (t *testCase) check(p page.Page, err error, errorMsg string, assert *require.Assertions) {
+func (t *testCase) check(p page.Page, err error, errorMsg string, c *qt.C) {
+	errorComment := qt.Commentf(errorMsg)
 	switch t.kind {
 	case "Ambiguous":
-		assert.Error(err)
-		assert.Nil(p, errorMsg)
+		c.Assert(err, qt.Not(qt.IsNil))
+		c.Assert(p, qt.IsNil, errorComment)
 	case "NoPage":
-		assert.NoError(err)
-		assert.Nil(p, errorMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(p, qt.IsNil, errorComment)
 	default:
-		assert.NoError(err, errorMsg)
-		assert.NotNil(p, errorMsg)
-		assert.Equal(t.kind, p.Kind(), errorMsg)
-		assert.Equal(t.expectedTitle, p.Title(), errorMsg)
+		c.Assert(err, qt.IsNil, errorComment)
+		c.Assert(p, qt.Not(qt.IsNil), errorComment)
+		c.Assert(p.Kind(), qt.Equals, t.kind, errorComment)
+		c.Assert(p.Title(), qt.Equals, t.expectedTitle, errorComment)
 	}
 }
 
@@ -124,8 +126,8 @@
 func TestGetPage(t *testing.T) {
 
 	var (
-		assert  = require.New(t)
 		cfg, fs = newTestCfg()
+		c       = qt.New(t)
 	)
 
 	for i := 0; i < 10; i++ {
@@ -156,8 +158,8 @@
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
 	sec3, err := s.getPageNew(nil, "/sect3")
-	assert.NoError(err, "error getting Page for /sec3")
-	assert.NotNil(sec3, "failed to get Page for /sec3")
+	c.Assert(err, qt.IsNil)
+	c.Assert(sec3, qt.Not(qt.IsNil))
 
 	tests := []testCase{
 		// legacy content root relative paths
@@ -227,7 +229,7 @@
 		if test.context == nil {
 			args := append([]string{test.kind}, test.path...)
 			page, err := s.Info.GetPage(args...)
-			test.check(page, err, errorMsg, assert)
+			test.check(page, err, errorMsg, c)
 		}
 
 		// test new internal Site.getPageNew
@@ -238,7 +240,7 @@
 			ref = path.Join(test.path...)
 		}
 		page2, err := s.getPageNew(test.context, ref)
-		test.check(page2, err, errorMsg, assert)
+		test.check(page2, err, errorMsg, c)
 	}
 
 }
--- a/hugolib/pages_capture_test.go
+++ b/hugolib/pages_capture_test.go
@@ -26,9 +26,9 @@
 
 	"github.com/gohugoio/hugo/common/loggers"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/afero"
-	"github.com/stretchr/testify/require"
 )
 
 func TestPagesCapture(t *testing.T) {
@@ -36,10 +36,10 @@
 	cfg, hfs := newTestCfg()
 	fs := hfs.Source
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	var writeFile = func(filename string) {
-		assert.NoError(afero.WriteFile(fs, filepath.FromSlash(filename), []byte(fmt.Sprintf("content-%s", filename)), 0755))
+		c.Assert(afero.WriteFile(fs, filepath.FromSlash(filename), []byte(fmt.Sprintf("content-%s", filename)), 0755), qt.IsNil)
 	}
 
 	writeFile("_index.md")
@@ -53,22 +53,22 @@
 	writeFile("pages/page.png")
 
 	ps, err := helpers.NewPathSpec(hugofs.NewFrom(fs, cfg), cfg, loggers.NewErrorLogger())
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	sourceSpec := source.NewSourceSpec(ps, fs)
 
 	t.Run("Collect", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		proc := &testPagesCollectorProcessor{}
-		c := newPagesCollector(sourceSpec, loggers.NewErrorLogger(), nil, proc)
-		assert.NoError(c.Collect())
-		assert.Equal(4, len(proc.items))
+		coll := newPagesCollector(sourceSpec, loggers.NewErrorLogger(), nil, proc)
+		c.Assert(coll.Collect(), qt.IsNil)
+		c.Assert(len(proc.items), qt.Equals, 4)
 	})
 
 	t.Run("error in Wait", func(t *testing.T) {
-		assert := require.New(t)
-		c := newPagesCollector(sourceSpec, loggers.NewErrorLogger(), nil,
+		c := qt.New(t)
+		coll := newPagesCollector(sourceSpec, loggers.NewErrorLogger(), nil,
 			&testPagesCollectorProcessor{waitErr: errors.New("failed")})
-		assert.Error(c.Collect())
+		c.Assert(coll.Collect(), qt.Not(qt.IsNil))
 	})
 }
 
--- a/hugolib/pages_language_merge_test.go
+++ b/hugolib/pages_language_merge_test.go
@@ -17,8 +17,8 @@
 	"fmt"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/resources/resource"
-	"github.com/stretchr/testify/require"
 )
 
 // TODO(bep) move and rewrite in resource/page.
@@ -25,7 +25,7 @@
 
 func TestMergeLanguages(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	b := newTestSiteForLanguageMerge(t, 30)
 	b.CreateSites()
@@ -38,13 +38,13 @@
 	frSite := h.Sites[1]
 	nnSite := h.Sites[2]
 
-	assert.Equal(31, len(enSite.RegularPages()))
-	assert.Equal(6, len(frSite.RegularPages()))
-	assert.Equal(12, len(nnSite.RegularPages()))
+	c.Assert(len(enSite.RegularPages()), qt.Equals, 31)
+	c.Assert(len(frSite.RegularPages()), qt.Equals, 6)
+	c.Assert(len(nnSite.RegularPages()), qt.Equals, 12)
 
 	for i := 0; i < 2; i++ {
 		mergedNN := nnSite.RegularPages().MergeByLanguage(enSite.RegularPages())
-		assert.Equal(31, len(mergedNN))
+		c.Assert(len(mergedNN), qt.Equals, 31)
 		for i := 1; i <= 31; i++ {
 			expectedLang := "en"
 			if i == 2 || i%3 == 0 || i == 31 {
@@ -51,12 +51,12 @@
 				expectedLang = "nn"
 			}
 			p := mergedNN[i-1]
-			assert.Equal(expectedLang, p.Language().Lang, fmt.Sprintf("Test %d", i))
+			c.Assert(p.Language().Lang, qt.Equals, expectedLang)
 		}
 	}
 
 	mergedFR := frSite.RegularPages().MergeByLanguage(enSite.RegularPages())
-	assert.Equal(31, len(mergedFR))
+	c.Assert(len(mergedFR), qt.Equals, 31)
 	for i := 1; i <= 31; i++ {
 		expectedLang := "en"
 		if i%5 == 0 {
@@ -63,28 +63,28 @@
 			expectedLang = "fr"
 		}
 		p := mergedFR[i-1]
-		assert.Equal(expectedLang, p.Language().Lang, fmt.Sprintf("Test %d", i))
+		c.Assert(p.Language().Lang, qt.Equals, expectedLang)
 	}
 
 	firstNN := nnSite.RegularPages()[0]
-	assert.Equal(4, len(firstNN.Sites()))
-	assert.Equal("en", firstNN.Sites().First().Language().Lang)
+	c.Assert(len(firstNN.Sites()), qt.Equals, 4)
+	c.Assert(firstNN.Sites().First().Language().Lang, qt.Equals, "en")
 
 	nnBundle := nnSite.getPage("page", "bundle")
 	enBundle := enSite.getPage("page", "bundle")
 
-	assert.Equal(6, len(enBundle.Resources()))
-	assert.Equal(2, len(nnBundle.Resources()))
+	c.Assert(len(enBundle.Resources()), qt.Equals, 6)
+	c.Assert(len(nnBundle.Resources()), qt.Equals, 2)
 
 	var ri interface{} = nnBundle.Resources()
 
 	// This looks less ugly in the templates ...
 	mergedNNResources := ri.(resource.ResourcesLanguageMerger).MergeByLanguage(enBundle.Resources())
-	assert.Equal(6, len(mergedNNResources))
+	c.Assert(len(mergedNNResources), qt.Equals, 6)
 
 	unchanged, err := nnSite.RegularPages().MergeByLanguageInterface(nil)
-	assert.NoError(err)
-	assert.Equal(nnSite.RegularPages(), unchanged)
+	c.Assert(err, qt.IsNil)
+	c.Assert(unchanged, deepEqualsPages, nnSite.RegularPages())
 
 }
 
--- a/hugolib/paths/baseURL_test.go
+++ b/hugolib/paths/baseURL_test.go
@@ -16,51 +16,52 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestBaseURL(t *testing.T) {
+	c := qt.New(t)
 	b, err := newBaseURLFromString("http://example.com")
-	require.NoError(t, err)
-	require.Equal(t, "http://example.com", b.String())
+	c.Assert(err, qt.IsNil)
+	c.Assert(b.String(), qt.Equals, "http://example.com")
 
 	p, err := b.WithProtocol("webcal://")
-	require.NoError(t, err)
-	require.Equal(t, "webcal://example.com", p)
+	c.Assert(err, qt.IsNil)
+	c.Assert(p, qt.Equals, "webcal://example.com")
 
 	p, err = b.WithProtocol("webcal")
-	require.NoError(t, err)
-	require.Equal(t, "webcal://example.com", p)
+	c.Assert(err, qt.IsNil)
+	c.Assert(p, qt.Equals, "webcal://example.com")
 
 	_, err = b.WithProtocol("mailto:")
-	require.Error(t, err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	b, err = newBaseURLFromString("mailto:[email protected]")
-	require.NoError(t, err)
-	require.Equal(t, "mailto:[email protected]", b.String())
+	c.Assert(err, qt.IsNil)
+	c.Assert(b.String(), qt.Equals, "mailto:[email protected]")
 
 	// These are pretty constructed
 	p, err = b.WithProtocol("webcal")
-	require.NoError(t, err)
-	require.Equal(t, "webcal:[email protected]", p)
+	c.Assert(err, qt.IsNil)
+	c.Assert(p, qt.Equals, "webcal:[email protected]")
 
 	p, err = b.WithProtocol("webcal://")
-	require.NoError(t, err)
-	require.Equal(t, "webcal://[email protected]", p)
+	c.Assert(err, qt.IsNil)
+	c.Assert(p, qt.Equals, "webcal://[email protected]")
 
 	// Test with "non-URLs". Some people will try to use these as a way to get
 	// relative URLs working etc.
 	b, err = newBaseURLFromString("/")
-	require.NoError(t, err)
-	require.Equal(t, "/", b.String())
+	c.Assert(err, qt.IsNil)
+	c.Assert(b.String(), qt.Equals, "/")
 
 	b, err = newBaseURLFromString("")
-	require.NoError(t, err)
-	require.Equal(t, "", b.String())
+	c.Assert(err, qt.IsNil)
+	c.Assert(b.String(), qt.Equals, "")
 
 	// BaseURL with sub path
 	b, err = newBaseURLFromString("http://example.com/sub")
-	require.NoError(t, err)
-	require.Equal(t, "http://example.com/sub", b.String())
-	require.Equal(t, "http://example.com", b.HostURL())
+	c.Assert(err, qt.IsNil)
+	c.Assert(b.String(), qt.Equals, "http://example.com/sub")
+	c.Assert(b.HostURL(), qt.Equals, "http://example.com")
 }
--- a/hugolib/paths/paths_test.go
+++ b/hugolib/paths/paths_test.go
@@ -18,13 +18,13 @@
 
 	"github.com/gohugoio/hugo/langs"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestNewPaths(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	v := viper.New()
 	fs := hugofs.NewMem(v)
@@ -43,9 +43,9 @@
 	langs.LoadLanguageSettings(v, nil)
 
 	p, err := New(fs, v)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal(true, p.defaultContentLanguageInSubdir)
-	assert.Equal("no", p.DefaultContentLanguage)
-	assert.Equal(true, p.multilingual)
+	c.Assert(p.defaultContentLanguageInSubdir, qt.Equals, true)
+	c.Assert(p.DefaultContentLanguage, qt.Equals, "no")
+	c.Assert(p.multilingual, qt.Equals, true)
 }
--- a/hugolib/resource_chain_test.go
+++ b/hugolib/resource_chain_test.go
@@ -22,7 +22,7 @@
 
 	"github.com/spf13/viper"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 
 	"github.com/gohugoio/hugo/hugofs"
 
@@ -34,9 +34,9 @@
 	if !scss.Supports() {
 		t.Skip("Skip SCSS")
 	}
-	assert := require.New(t)
+	c := qt.New(t)
 	workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-scss-include")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer clean()
 
 	v := viper.New()
@@ -49,13 +49,13 @@
 
 	fooDir := filepath.Join(workDir, "node_modules", "foo")
 	scssDir := filepath.Join(workDir, "assets", "scss")
-	assert.NoError(os.MkdirAll(fooDir, 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "content", "sect"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "data"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "i18n"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "layouts", "shortcodes"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "layouts", "_default"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(scssDir), 0777))
+	c.Assert(os.MkdirAll(fooDir, 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "content", "sect"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "data"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "i18n"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "layouts", "shortcodes"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "layouts", "_default"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(scssDir), 0777), qt.IsNil)
 
 	b.WithSourceFile(filepath.Join(fooDir, "_moo.scss"), `
 $moolor: #fff;
@@ -85,9 +85,9 @@
 	if !scss.Supports() {
 		t.Skip("Skip SCSS")
 	}
-	assert := require.New(t)
+	c := qt.New(t)
 	workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-scss-include")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer clean()
 
 	theme := "mytheme"
@@ -105,14 +105,14 @@
 	fooDir := filepath.Join(workDir, "node_modules", "foo")
 	scssDir := filepath.Join(workDir, "assets", "scss")
 	scssThemeDir := filepath.Join(themeDirs, "assets", "scss")
-	assert.NoError(os.MkdirAll(fooDir, 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "content", "sect"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "data"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "i18n"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "layouts", "shortcodes"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(workDir, "layouts", "_default"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(scssDir, "components"), 0777))
-	assert.NoError(os.MkdirAll(filepath.Join(scssThemeDir, "components"), 0777))
+	c.Assert(os.MkdirAll(fooDir, 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "content", "sect"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "data"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "i18n"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "layouts", "shortcodes"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(workDir, "layouts", "_default"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(scssDir, "components"), 0777), qt.IsNil)
+	c.Assert(os.MkdirAll(filepath.Join(scssThemeDir, "components"), 0777), qt.IsNil)
 
 	b.WithSourceFile(filepath.Join(scssThemeDir, "components", "_imports.scss"), `
 @import "moo";
@@ -170,7 +170,7 @@
 func TestResourceChain(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tests := []struct {
 		name      string
@@ -203,7 +203,7 @@
 			b.AssertFileContent("public/index.html", `T5 RelPermalink: /sass/styles3.css|`)
 			b.AssertFileContent("public/index.html", `T6: http://example.com/styles/bundle1.css`)
 
-			assert.False(b.CheckExists("public/styles/templ.min.css"))
+			c.Assert(b.CheckExists("public/styles/templ.min.css"), qt.Equals, false)
 			b.AssertFileContent("public/styles/bundle1.css", `.home{color:blue}body{color:#333}`)
 
 		}},
@@ -353,10 +353,9 @@
 				"Publish 1: body{color:blue} /external1.min.css",
 				"Publish 2: http://example.com/external2.min.css",
 			)
-			assert.True(b.CheckExists("public/external2.min.css"), "Referenced content should be copied to /public")
-			assert.True(b.CheckExists("public/external1.min.css"), "Referenced content should be copied to /public")
-
-			assert.False(b.CheckExists("public/inline.min.css"), "Inline content should not be copied to /public")
+			c.Assert(b.CheckExists("public/external2.min.css"), qt.Equals, true)
+			c.Assert(b.CheckExists("public/external1.min.css"), qt.Equals, true)
+			c.Assert(b.CheckExists("public/inline.min.css"), qt.Equals, false)
 		}},
 
 		{"unmarshal", func() bool { return true }, func(b *sitesBuilder) {
@@ -489,7 +488,7 @@
 
 func TestMultiSiteResource(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	b := newMultiSiteTestDefaultBuilder(t)
 
@@ -497,8 +496,8 @@
 
 	// This build is multilingual, but not multihost. There should be only one pipes.txt
 	b.AssertFileContent("public/fr/index.html", "French Home Page", "String Resource: /blog/text/pipes.txt")
-	assert.False(b.CheckExists("public/fr/text/pipes.txt"))
-	assert.False(b.CheckExists("public/en/text/pipes.txt"))
+	c.Assert(b.CheckExists("public/fr/text/pipes.txt"), qt.Equals, false)
+	c.Assert(b.CheckExists("public/en/text/pipes.txt"), qt.Equals, false)
 	b.AssertFileContent("public/en/index.html", "Default Home Page", "String Resource: /blog/text/pipes.txt")
 	b.AssertFileContent("public/text/pipes.txt", "Hugo Pipes")
 
--- a/hugolib/rss_test.go
+++ b/hugolib/rss_test.go
@@ -25,7 +25,7 @@
 	t.Parallel()
 	var (
 		cfg, fs = newTestCfg()
-		th      = testHelper{cfg, fs, t}
+		th      = newTestHelper(cfg, fs, t)
 	)
 
 	rssLimit := len(weightedSources) - 1
--- a/hugolib/shortcode_test.go
+++ b/hugolib/shortcode_test.go
@@ -16,7 +16,6 @@
 import (
 	"fmt"
 	"path/filepath"
-	"regexp"
 
 	"reflect"
 
@@ -31,7 +30,7 @@
 	"github.com/gohugoio/hugo/tpl"
 	"github.com/spf13/cast"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tpl.TemplateHandler) error) {
@@ -41,6 +40,7 @@
 func CheckShortCodeMatchAndError(t *testing.T, input, expected string, withTemplate func(templ tpl.TemplateHandler) error, expectError bool) {
 
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	// Need some front matter, see https://github.com/gohugoio/hugo/issues/2337
 	contentFile := `---
@@ -62,9 +62,9 @@
 	}
 
 	h := b.H
-	require.Len(t, h.Sites, 1)
+	c.Assert(len(h.Sites), qt.Equals, 1)
 
-	require.Len(t, h.Sites[0].RegularPages(), 1)
+	c.Assert(len(h.Sites[0].RegularPages()), qt.Equals, 1)
 
 	output := strings.TrimSpace(content(h.Sites[0].RegularPages()[0]))
 	output = strings.TrimPrefix(output, "<p>")
@@ -358,8 +358,8 @@
 
 	/*errCheck := func(s string) func(name string, assert *require.Assertions, shortcode *shortcode, err error) {
 		return func(name string, assert *require.Assertions, shortcode *shortcode, err error) {
-			assert.Error(err, name)
-			assert.Equal(s, err.Error(), name)
+			c.Assert(err, name, qt.Not(qt.IsNil))
+			c.Assert(err.Error(), name, qt.Equals, s)
 		}
 	}*/
 
@@ -374,11 +374,11 @@
 			s.name, s.isInline, s.isClosing, s.inner, s.params, s.ordinal, s.doMarkup, s.info.Config.Version, s.pos))
 	}
 
-	regexpCheck := func(re string) func(assert *require.Assertions, shortcode *shortcode, err error) {
-		return func(assert *require.Assertions, shortcode *shortcode, err error) {
-			assert.NoError(err)
-			got := str(shortcode)
-			assert.Regexp(regexp.MustCompile(re), got, got)
+	regexpCheck := func(re string) func(c *qt.C, shortcode *shortcode, err error) {
+		return func(c *qt.C, shortcode *shortcode, err error) {
+			c.Assert(err, qt.IsNil)
+			c.Assert(str(shortcode), qt.Matches, ".*"+re+".*")
+
 		}
 	}
 
@@ -385,7 +385,7 @@
 	for _, test := range []struct {
 		name  string
 		input string
-		check func(assert *require.Assertions, shortcode *shortcode, err error)
+		check func(c *qt.C, shortcode *shortcode, err error)
 	}{
 		{"one shortcode, no markup", "{{< tag >}}", regexpCheck("tag.*closing:false.*markup:false")},
 		{"one shortcode, markup", "{{% tag %}}", regexpCheck("tag.*closing:false.*markup:true;version:2")},
@@ -411,7 +411,7 @@
 
 		t.Run(test.name, func(t *testing.T) {
 			t.Parallel()
-			assert := require.New(t)
+			c := qt.New(t)
 
 			counter := 0
 			placeholderFunc := func() string {
@@ -420,13 +420,13 @@
 			}
 
 			p, err := pageparser.ParseMain(strings.NewReader(test.input), pageparser.Config{})
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 			handler := newShortcodeHandler(nil, s, placeholderFunc)
 			iter := p.Iterator()
 
 			short, err := handler.extractShortcode(0, 0, iter)
 
-			test.check(assert, short, err)
+			test.check(c, short, err)
 
 		})
 	}
@@ -582,7 +582,7 @@
 				t.Skip("Skip Rst test case as no rst2html present.")
 			}
 
-			th := testHelper{s.Cfg, s.Fs, t}
+			th := newTestHelper(s.Cfg, s.Fs, t)
 
 			expected := cast.ToStringSlice(test.expected)
 			th.assertFileContent(filepath.FromSlash(test.outFile), expected...)
@@ -655,12 +655,12 @@
 
 	b.Build(BuildCfg{})
 	h := b.H
-	require.Len(t, h.Sites, 1)
+	b.Assert(len(h.Sites), qt.Equals, 1)
 
 	s := h.Sites[0]
 	home := s.getPage(page.KindHome)
-	require.NotNil(t, home)
-	require.Len(t, home.OutputFormats(), 3)
+	b.Assert(home, qt.Not(qt.IsNil))
+	b.Assert(len(home.OutputFormats()), qt.Equals, 3)
 
 	b.AssertFileContent("public/index.html",
 		"Home HTML",
@@ -827,7 +827,6 @@
 
 func TestShortcodeGetContent(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
 
 	contentShortcode := `
 {{- $t := .Get 0 -}}
@@ -878,7 +877,7 @@
 
 	builder.WithContent(content...).WithTemplates(templates...).CreateSites().Build(BuildCfg{})
 	s := builder.H.Sites[0]
-	assert.Equal(3, len(s.RegularPages()))
+	builder.Assert(len(s.RegularPages()), qt.Equals, 3)
 
 	builder.AssertFileContent("public/en/section1/index.html",
 		"List Content: <p>Logo:P1:|P2:logo.png/PNG logo|:P1: P1:|P2:docs1p1/<p>C-s1p1</p>\n|",
@@ -958,7 +957,7 @@
 
 func TestShortcodePreserveOrder(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	contentTemplate := `---
 title: doc%d
@@ -1004,7 +1003,7 @@
 	builder.WithContent(content...).WithTemplatesAdded(shortcodes...).CreateSites().Build(BuildCfg{})
 
 	s := builder.H.Sites[0]
-	assert.Equal(3, len(s.RegularPages()))
+	c.Assert(len(s.RegularPages()), qt.Equals, 3)
 
 	builder.AssertFileContent("public/en/p1/index.html", `v1: 0 sgo: |v2: 1 sgo: 0|v3: 2 sgo: 1|v4: 3 sgo: 2|v5: 4 sgo: 3`)
 	builder.AssertFileContent("public/en/p1/index.html", `outer ordinal: 5 inner: 
@@ -1016,7 +1015,7 @@
 
 func TestShortcodeVariables(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	builder := newTestSitesBuilder(t).WithSimpleConfigFile()
 
@@ -1041,7 +1040,7 @@
 `).CreateSites().Build(BuildCfg{})
 
 	s := builder.H.Sites[0]
-	assert.Equal(1, len(s.RegularPages()))
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	builder.AssertFileContent("public/page/index.html",
 		filepath.FromSlash("File: content/page.md"),
@@ -1134,7 +1133,7 @@
 // https://github.com/gohugoio/hugo/issues/5863
 func TestShortcodeNamespaced(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	builder := newTestSitesBuilder(t).WithSimpleConfigFile()
 
@@ -1152,7 +1151,7 @@
 		"layouts/shortcodes/test/hello.html", `test/hello`).CreateSites().Build(BuildCfg{})
 
 	s := builder.H.Sites[0]
-	assert.Equal(1, len(s.RegularPages()))
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 	builder.AssertFileContent("public/page/index.html",
 		"hello: hello",
--- a/hugolib/site_benchmark_new_test.go
+++ b/hugolib/site_benchmark_new_test.go
@@ -20,6 +20,8 @@
 	"strconv"
 	"strings"
 	"testing"
+
+	qt "github.com/frankban/quicktest"
 )
 
 type siteBenchmarkTestcase struct {
@@ -182,9 +184,9 @@
 		},
 			func(s *sitesBuilder) {
 				s.CheckExists("public/blog/mybundle/index.html")
-				s.Assertions.Equal(4, len(s.H.Sites))
-				s.Assertions.Equal(len(s.H.Sites[0].RegularPages()), len(s.H.Sites[1].RegularPages()))
-				s.Assertions.Equal(30, len(s.H.Sites[0].RegularPages()))
+				s.Assert(len(s.H.Sites), qt.Equals, 4)
+				s.Assert(len(s.H.Sites[0].RegularPages()), qt.Equals, len(s.H.Sites[1].RegularPages()))
+				s.Assert(len(s.H.Sites[0].RegularPages()), qt.Equals, 30)
 
 			},
 		},
--- a/hugolib/site_output_test.go
+++ b/hugolib/site_output_test.go
@@ -17,12 +17,11 @@
 	"strings"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/resources/page"
 
 	"github.com/spf13/afero"
 
-	"github.com/stretchr/testify/require"
-
 	"fmt"
 
 	"github.com/gohugoio/hugo/helpers"
@@ -142,15 +141,15 @@
 	b.Build(BuildCfg{})
 
 	s := b.H.Sites[0]
-	require.Equal(t, "en", s.language.Lang)
+	b.Assert(s.language.Lang, qt.Equals, "en")
 
 	home := s.getPage(page.KindHome)
 
-	require.NotNil(t, home)
+	b.Assert(home, qt.Not(qt.IsNil))
 
 	lenOut := len(outputs)
 
-	require.Len(t, home.OutputFormats(), lenOut)
+	b.Assert(len(home.OutputFormats()), qt.Equals, lenOut)
 
 	// There is currently always a JSON output to make it simpler ...
 	altFormats := lenOut - 1
@@ -179,9 +178,8 @@
 			"OtherShort: <h1>Hi!</h1>",
 			"Len Pages: home 10",
 		)
-		assert := require.New(t)
 		b.AssertFileContent("public/page/2/index.html", "Page Number: 2")
-		assert.False(b.CheckExists("public/page/2/index.json"))
+		b.Assert(b.CheckExists("public/page/2/index.json"), qt.Equals, false)
 
 		b.AssertFileContent("public/nn/index.html",
 			"List HTML|JSON Nynorsk Heim|",
@@ -204,19 +202,19 @@
 	of := home.OutputFormats()
 
 	json := of.Get("JSON")
-	require.NotNil(t, json)
-	require.Equal(t, "/blog/index.json", json.RelPermalink())
-	require.Equal(t, "http://example.com/blog/index.json", json.Permalink())
+	b.Assert(json, qt.Not(qt.IsNil))
+	b.Assert(json.RelPermalink(), qt.Equals, "/blog/index.json")
+	b.Assert(json.Permalink(), qt.Equals, "http://example.com/blog/index.json")
 
 	if helpers.InStringArray(outputs, "cal") {
 		cal := of.Get("calendar")
-		require.NotNil(t, cal)
-		require.Equal(t, "/blog/index.ics", cal.RelPermalink())
-		require.Equal(t, "webcal://example.com/blog/index.ics", cal.Permalink())
+		b.Assert(cal, qt.Not(qt.IsNil))
+		b.Assert(cal.RelPermalink(), qt.Equals, "/blog/index.ics")
+		b.Assert(cal.Permalink(), qt.Equals, "webcal://example.com/blog/index.ics")
 	}
 
-	require.True(t, home.HasShortcode("myShort"))
-	require.False(t, home.HasShortcode("doesNotExist"))
+	b.Assert(home.HasShortcode("myShort"), qt.Equals, true)
+	b.Assert(home.HasShortcode("doesNotExist"), qt.Equals, false)
 
 }
 
@@ -237,6 +235,8 @@
 
 `
 
+	c := qt.New(t)
+
 	mf := afero.NewMemMapFs()
 	writeToFs(t, mf, "content/foo.html", `foo`)
 
@@ -244,7 +244,7 @@
 
 	err := h.Build(BuildCfg{})
 
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	th.assertFileContent("public/feed.xml", "Recent content on")
 
@@ -251,7 +251,7 @@
 	s := h.Sites[0]
 
 	//Issue #3450
-	require.Equal(t, "http://example.com/blog/feed.xml", s.Info.RSSLink)
+	c.Assert(s.Info.RSSLink, qt.Equals, "http://example.com/blog/feed.xml")
 
 }
 
@@ -294,6 +294,8 @@
 
 `
 
+	c := qt.New(t)
+
 	mf := afero.NewMemMapFs()
 	writeToFs(t, mf, "content/foo.html", `foo`)
 	writeToFs(t, mf, "layouts/_default/list.dotless", `a dotless`)
@@ -305,7 +307,7 @@
 
 	err := h.Build(BuildCfg{})
 
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	th.assertFileContent("public/_redirects", "a dotless")
 	th.assertFileContent("public/defaultdelimbase.defd", "default delimim")
@@ -315,14 +317,14 @@
 
 	s := h.Sites[0]
 	home := s.getPage(page.KindHome)
-	require.NotNil(t, home)
+	c.Assert(home, qt.Not(qt.IsNil))
 
 	outputs := home.OutputFormats()
 
-	require.Equal(t, "/blog/_redirects", outputs.Get("DOTLESS").RelPermalink())
-	require.Equal(t, "/blog/defaultdelimbase.defd", outputs.Get("DEF").RelPermalink())
-	require.Equal(t, "/blog/nosuffixbase", outputs.Get("NOS").RelPermalink())
-	require.Equal(t, "/blog/customdelimbase_del", outputs.Get("CUS").RelPermalink())
+	c.Assert(outputs.Get("DOTLESS").RelPermalink(), qt.Equals, "/blog/_redirects")
+	c.Assert(outputs.Get("DEF").RelPermalink(), qt.Equals, "/blog/defaultdelimbase.defd")
+	c.Assert(outputs.Get("NOS").RelPermalink(), qt.Equals, "/blog/nosuffixbase")
+	c.Assert(outputs.Get("CUS").RelPermalink(), qt.Equals, "/blog/customdelimbase_del")
 
 }
 
@@ -329,7 +331,7 @@
 func TestCreateSiteOutputFormats(t *testing.T) {
 
 	t.Run("Basic", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
 		outputsConfig := map[string]interface{}{
 			page.KindHome:    []string{"HTML", "JSON"},
@@ -340,28 +342,28 @@
 		cfg.Set("outputs", outputsConfig)
 
 		outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg)
-		assert.NoError(err)
-		assert.Equal(output.Formats{output.JSONFormat}, outputs[page.KindSection])
-		assert.Equal(output.Formats{output.HTMLFormat, output.JSONFormat}, outputs[page.KindHome])
+		c.Assert(err, qt.IsNil)
+		c.Assert(outputs[page.KindSection], deepEqualsOutputFormats, output.Formats{output.JSONFormat})
+		c.Assert(outputs[page.KindHome], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.JSONFormat})
 
 		// Defaults
-		assert.Equal(output.Formats{output.HTMLFormat, output.RSSFormat}, outputs[page.KindTaxonomy])
-		assert.Equal(output.Formats{output.HTMLFormat, output.RSSFormat}, outputs[page.KindTaxonomyTerm])
-		assert.Equal(output.Formats{output.HTMLFormat}, outputs[page.KindPage])
+		c.Assert(outputs[page.KindTaxonomy], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.RSSFormat})
+		c.Assert(outputs[page.KindTaxonomyTerm], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.RSSFormat})
+		c.Assert(outputs[page.KindPage], deepEqualsOutputFormats, output.Formats{output.HTMLFormat})
 
 		// These aren't (currently) in use when rendering in Hugo,
 		// but the pages needs to be assigned an output format,
 		// so these should also be correct/sensible.
-		assert.Equal(output.Formats{output.RSSFormat}, outputs[kindRSS])
-		assert.Equal(output.Formats{output.SitemapFormat}, outputs[kindSitemap])
-		assert.Equal(output.Formats{output.RobotsTxtFormat}, outputs[kindRobotsTXT])
-		assert.Equal(output.Formats{output.HTMLFormat}, outputs[kind404])
+		c.Assert(outputs[kindRSS], deepEqualsOutputFormats, output.Formats{output.RSSFormat})
+		c.Assert(outputs[kindSitemap], deepEqualsOutputFormats, output.Formats{output.SitemapFormat})
+		c.Assert(outputs[kindRobotsTXT], deepEqualsOutputFormats, output.Formats{output.RobotsTxtFormat})
+		c.Assert(outputs[kind404], deepEqualsOutputFormats, output.Formats{output.HTMLFormat})
 
 	})
 
 	// Issue #4528
 	t.Run("Mixed case", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		cfg := viper.New()
 
 		outputsConfig := map[string]interface{}{
@@ -370,8 +372,8 @@
 		cfg.Set("outputs", outputsConfig)
 
 		outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg)
-		assert.NoError(err)
-		assert.Equal(output.Formats{output.JSONFormat}, outputs[page.KindTaxonomyTerm])
+		c.Assert(err, qt.IsNil)
+		c.Assert(outputs[page.KindTaxonomyTerm], deepEqualsOutputFormats, output.Formats{output.JSONFormat})
 
 	})
 
@@ -378,7 +380,7 @@
 }
 
 func TestCreateSiteOutputFormatsInvalidConfig(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	outputsConfig := map[string]interface{}{
 		page.KindHome: []string{"FOO", "JSON"},
@@ -388,11 +390,11 @@
 	cfg.Set("outputs", outputsConfig)
 
 	_, err := createSiteOutputFormats(output.DefaultFormats, cfg)
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 }
 
 func TestCreateSiteOutputFormatsEmptyConfig(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	outputsConfig := map[string]interface{}{
 		page.KindHome: []string{},
@@ -402,12 +404,12 @@
 	cfg.Set("outputs", outputsConfig)
 
 	outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg)
-	assert.NoError(err)
-	assert.Equal(output.Formats{output.HTMLFormat, output.RSSFormat}, outputs[page.KindHome])
+	c.Assert(err, qt.IsNil)
+	c.Assert(outputs[page.KindHome], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.RSSFormat})
 }
 
 func TestCreateSiteOutputFormatsCustomFormats(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	outputsConfig := map[string]interface{}{
 		page.KindHome: []string{},
@@ -422,8 +424,8 @@
 	)
 
 	outputs, err := createSiteOutputFormats(output.Formats{customRSS, customHTML}, cfg)
-	assert.NoError(err)
-	assert.Equal(output.Formats{customHTML, customRSS}, outputs[page.KindHome])
+	c.Assert(err, qt.IsNil)
+	c.Assert(outputs[page.KindHome], deepEqualsOutputFormats, output.Formats{customHTML, customRSS})
 }
 
 // https://github.com/gohugoio/hugo/issues/5849
--- a/hugolib/site_sections_test.go
+++ b/hugolib/site_sections_test.go
@@ -19,17 +19,17 @@
 	"strings"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/resources/page"
-	"github.com/stretchr/testify/require"
 )
 
 func TestNestedSections(t *testing.T) {
 
 	var (
-		assert  = require.New(t)
+		c       = qt.New(t)
 		cfg, fs = newTestCfg()
-		th      = testHelper{cfg, fs, t}
+		th      = newTestHelper(cfg, fs, t)
 	)
 
 	cfg.Set("permalinks", map[string]string{
@@ -117,179 +117,179 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
 
-	require.Len(t, s.RegularPages(), 21)
+	c.Assert(len(s.RegularPages()), qt.Equals, 21)
 
 	tests := []struct {
 		sections string
-		verify   func(assert *require.Assertions, p page.Page)
+		verify   func(c *qt.C, p page.Page)
 	}{
-		{"elsewhere", func(assert *require.Assertions, p page.Page) {
-			assert.Len(p.Pages(), 1)
+		{"elsewhere", func(c *qt.C, p page.Page) {
+			c.Assert(len(p.Pages()), qt.Equals, 1)
 			for _, p := range p.Pages() {
-				assert.Equal("elsewhere", p.SectionsPath())
+				c.Assert(p.SectionsPath(), qt.Equals, "elsewhere")
 			}
 		}},
-		{"post", func(assert *require.Assertions, p page.Page) {
-			assert.Len(p.Pages(), 2)
+		{"post", func(c *qt.C, p page.Page) {
+			c.Assert(len(p.Pages()), qt.Equals, 2)
 			for _, p := range p.Pages() {
-				assert.Equal("post", p.Section())
+				c.Assert(p.Section(), qt.Equals, "post")
 			}
 		}},
-		{"empty1", func(assert *require.Assertions, p page.Page) {
+		{"empty1", func(c *qt.C, p page.Page) {
 			// > b,c
-			assert.Nil(getPage(p, "/empty1/b")) // No _index.md page.
-			assert.NotNil(getPage(p, "/empty1/b/c"))
+			c.Assert(getPage(p, "/empty1/b"), qt.IsNil) // No _index.md page.
+			c.Assert(getPage(p, "/empty1/b/c"), qt.Not(qt.IsNil))
 
 		}},
-		{"empty2", func(assert *require.Assertions, p page.Page) {
+		{"empty2", func(c *qt.C, p page.Page) {
 			// > b,c,d where b and d have _index.md files.
 			b := getPage(p, "/empty2/b")
-			assert.NotNil(b)
-			assert.Equal("T40_-1", b.Title())
+			c.Assert(b, qt.Not(qt.IsNil))
+			c.Assert(b.Title(), qt.Equals, "T40_-1")
 
-			c := getPage(p, "/empty2/b/c")
-			assert.Nil(c) // No _index.md
+			cp := getPage(p, "/empty2/b/c")
+			c.Assert(cp, qt.IsNil) // No _index.md
 
 			d := getPage(p, "/empty2/b/c/d")
-			assert.NotNil(d)
-			assert.Equal("T41_-1", d.Title())
+			c.Assert(d, qt.Not(qt.IsNil))
+			c.Assert(d.Title(), qt.Equals, "T41_-1")
 
-			assert.False(c.Eq(d))
-			assert.True(c.Eq(c))
-			assert.False(c.Eq("asdf"))
+			c.Assert(cp.Eq(d), qt.Equals, false)
+			c.Assert(cp.Eq(cp), qt.Equals, true)
+			c.Assert(cp.Eq("asdf"), qt.Equals, false)
 
 		}},
-		{"empty3", func(assert *require.Assertions, p page.Page) {
+		{"empty3", func(c *qt.C, p page.Page) {
 			// b,c,d with regular page in b
 			b := getPage(p, "/empty3/b")
-			assert.Nil(b) // No _index.md
+			c.Assert(b, qt.IsNil) // No _index.md
 			e3 := getPage(p, "/empty3/b/empty3")
-			assert.NotNil(e3)
-			assert.Equal("empty3.md", e3.File().LogicalName())
+			c.Assert(e3, qt.Not(qt.IsNil))
+			c.Assert(e3.File().LogicalName(), qt.Equals, "empty3.md")
 
 		}},
-		{"empty3", func(assert *require.Assertions, p page.Page) {
+		{"empty3", func(c *qt.C, p page.Page) {
 			xxx := getPage(p, "/empty3/nil")
-			assert.Nil(xxx)
+			c.Assert(xxx, qt.IsNil)
 		}},
-		{"top", func(assert *require.Assertions, p page.Page) {
-			assert.Equal("Tops", p.Title())
-			assert.Len(p.Pages(), 2)
-			assert.Equal("mypage2.md", p.Pages()[0].File().LogicalName())
-			assert.Equal("mypage3.md", p.Pages()[1].File().LogicalName())
+		{"top", func(c *qt.C, p page.Page) {
+			c.Assert(p.Title(), qt.Equals, "Tops")
+			c.Assert(len(p.Pages()), qt.Equals, 2)
+			c.Assert(p.Pages()[0].File().LogicalName(), qt.Equals, "mypage2.md")
+			c.Assert(p.Pages()[1].File().LogicalName(), qt.Equals, "mypage3.md")
 			home := p.Parent()
-			assert.True(home.IsHome())
-			assert.Len(p.Sections(), 0)
-			assert.Equal(home, home.CurrentSection())
+			c.Assert(home.IsHome(), qt.Equals, true)
+			c.Assert(len(p.Sections()), qt.Equals, 0)
+			c.Assert(home.CurrentSection(), qt.Equals, home)
 			active, err := home.InSection(home)
-			assert.NoError(err)
-			assert.True(active)
-			assert.Equal(p, p.FirstSection())
+			c.Assert(err, qt.IsNil)
+			c.Assert(active, qt.Equals, true)
+			c.Assert(p.FirstSection(), qt.Equals, p)
 		}},
-		{"l1", func(assert *require.Assertions, p page.Page) {
-			assert.Equal("L1s", p.Title())
-			assert.Len(p.Pages(), 4) // 2 pages + 2 sections
-			assert.True(p.Parent().IsHome())
-			assert.Len(p.Sections(), 2)
+		{"l1", func(c *qt.C, p page.Page) {
+			c.Assert(p.Title(), qt.Equals, "L1s")
+			c.Assert(len(p.Pages()), qt.Equals, 4) // 2 pages + 2 sections
+			c.Assert(p.Parent().IsHome(), qt.Equals, true)
+			c.Assert(len(p.Sections()), qt.Equals, 2)
 		}},
-		{"l1,l2", func(assert *require.Assertions, p page.Page) {
-			assert.Equal("T2_-1", p.Title())
-			assert.Len(p.Pages(), 4) // 3 pages + 1 section
-			assert.Equal(p, p.Pages()[0].Parent())
-			assert.Equal("L1s", p.Parent().Title())
-			assert.Equal("/l1/l2/", p.RelPermalink())
-			assert.Len(p.Sections(), 1)
+		{"l1,l2", func(c *qt.C, p page.Page) {
+			c.Assert(p.Title(), qt.Equals, "T2_-1")
+			c.Assert(len(p.Pages()), qt.Equals, 4) // 3 pages + 1 section
+			c.Assert(p.Pages()[0].Parent(), qt.Equals, p)
+			c.Assert(p.Parent().Title(), qt.Equals, "L1s")
+			c.Assert(p.RelPermalink(), qt.Equals, "/l1/l2/")
+			c.Assert(len(p.Sections()), qt.Equals, 1)
 
 			for _, child := range p.Pages() {
 				if child.IsSection() {
-					assert.Equal(child, child.CurrentSection())
+					c.Assert(child.CurrentSection(), qt.Equals, child)
 					continue
 				}
 
-				assert.Equal(p, child.CurrentSection())
+				c.Assert(child.CurrentSection(), qt.Equals, p)
 				active, err := child.InSection(p)
-				assert.NoError(err)
+				c.Assert(err, qt.IsNil)
 
-				assert.True(active)
+				c.Assert(active, qt.Equals, true)
 				active, err = p.InSection(child)
-				assert.NoError(err)
-				assert.True(active)
+				c.Assert(err, qt.IsNil)
+				c.Assert(active, qt.Equals, true)
 				active, err = p.InSection(getPage(p, "/"))
-				assert.NoError(err)
-				assert.False(active)
+				c.Assert(err, qt.IsNil)
+				c.Assert(active, qt.Equals, false)
 
 				isAncestor, err := p.IsAncestor(child)
-				assert.NoError(err)
-				assert.True(isAncestor)
+				c.Assert(err, qt.IsNil)
+				c.Assert(isAncestor, qt.Equals, true)
 				isAncestor, err = child.IsAncestor(p)
-				assert.NoError(err)
-				assert.False(isAncestor)
+				c.Assert(err, qt.IsNil)
+				c.Assert(isAncestor, qt.Equals, false)
 
 				isDescendant, err := p.IsDescendant(child)
-				assert.NoError(err)
-				assert.False(isDescendant)
+				c.Assert(err, qt.IsNil)
+				c.Assert(isDescendant, qt.Equals, false)
 				isDescendant, err = child.IsDescendant(p)
-				assert.NoError(err)
-				assert.True(isDescendant)
+				c.Assert(err, qt.IsNil)
+				c.Assert(isDescendant, qt.Equals, true)
 			}
 
-			assert.True(p.Eq(p.CurrentSection()))
+			c.Assert(p.Eq(p.CurrentSection()), qt.Equals, true)
 
 		}},
-		{"l1,l2_2", func(assert *require.Assertions, p page.Page) {
-			assert.Equal("T22_-1", p.Title())
-			assert.Len(p.Pages(), 2)
-			assert.Equal(filepath.FromSlash("l1/l2_2/page_2_2_1.md"), p.Pages()[0].File().Path())
-			assert.Equal("L1s", p.Parent().Title())
-			assert.Len(p.Sections(), 0)
+		{"l1,l2_2", func(c *qt.C, p page.Page) {
+			c.Assert(p.Title(), qt.Equals, "T22_-1")
+			c.Assert(len(p.Pages()), qt.Equals, 2)
+			c.Assert(p.Pages()[0].File().Path(), qt.Equals, filepath.FromSlash("l1/l2_2/page_2_2_1.md"))
+			c.Assert(p.Parent().Title(), qt.Equals, "L1s")
+			c.Assert(len(p.Sections()), qt.Equals, 0)
 		}},
-		{"l1,l2,l3", func(assert *require.Assertions, p page.Page) {
+		{"l1,l2,l3", func(c *qt.C, p page.Page) {
 			nilp, _ := p.GetPage("this/does/not/exist")
 
-			assert.Equal("T3_-1", p.Title())
-			assert.Len(p.Pages(), 2)
-			assert.Equal("T2_-1", p.Parent().Title())
-			assert.Len(p.Sections(), 0)
+			c.Assert(p.Title(), qt.Equals, "T3_-1")
+			c.Assert(len(p.Pages()), qt.Equals, 2)
+			c.Assert(p.Parent().Title(), qt.Equals, "T2_-1")
+			c.Assert(len(p.Sections()), qt.Equals, 0)
 
 			l1 := getPage(p, "/l1")
 			isDescendant, err := l1.IsDescendant(p)
-			assert.NoError(err)
-			assert.False(isDescendant)
+			c.Assert(err, qt.IsNil)
+			c.Assert(isDescendant, qt.Equals, false)
 			isDescendant, err = l1.IsDescendant(nil)
-			assert.NoError(err)
-			assert.False(isDescendant)
+			c.Assert(err, qt.IsNil)
+			c.Assert(isDescendant, qt.Equals, false)
 			isDescendant, err = nilp.IsDescendant(p)
-			assert.NoError(err)
-			assert.False(isDescendant)
+			c.Assert(err, qt.IsNil)
+			c.Assert(isDescendant, qt.Equals, false)
 			isDescendant, err = p.IsDescendant(l1)
-			assert.NoError(err)
-			assert.True(isDescendant)
+			c.Assert(err, qt.IsNil)
+			c.Assert(isDescendant, qt.Equals, true)
 
 			isAncestor, err := l1.IsAncestor(p)
-			assert.NoError(err)
-			assert.True(isAncestor)
+			c.Assert(err, qt.IsNil)
+			c.Assert(isAncestor, qt.Equals, true)
 			isAncestor, err = p.IsAncestor(l1)
-			assert.NoError(err)
-			assert.False(isAncestor)
-			assert.Equal(l1, p.FirstSection())
+			c.Assert(err, qt.IsNil)
+			c.Assert(isAncestor, qt.Equals, false)
+			c.Assert(p.FirstSection(), qt.Equals, l1)
 			isAncestor, err = p.IsAncestor(nil)
-			assert.NoError(err)
-			assert.False(isAncestor)
+			c.Assert(err, qt.IsNil)
+			c.Assert(isAncestor, qt.Equals, false)
 			isAncestor, err = nilp.IsAncestor(l1)
-			assert.NoError(err)
-			assert.False(isAncestor)
+			c.Assert(err, qt.IsNil)
+			c.Assert(isAncestor, qt.Equals, false)
 
 		}},
-		{"perm a,link", func(assert *require.Assertions, p page.Page) {
-			assert.Equal("T9_-1", p.Title())
-			assert.Equal("/perm-a/link/", p.RelPermalink())
-			assert.Len(p.Pages(), 4)
+		{"perm a,link", func(c *qt.C, p page.Page) {
+			c.Assert(p.Title(), qt.Equals, "T9_-1")
+			c.Assert(p.RelPermalink(), qt.Equals, "/perm-a/link/")
+			c.Assert(len(p.Pages()), qt.Equals, 4)
 			first := p.Pages()[0]
-			assert.Equal("/perm-a/link/t1_1/", first.RelPermalink())
+			c.Assert(first.RelPermalink(), qt.Equals, "/perm-a/link/t1_1/")
 			th.assertFileContent("public/perm-a/link/t1_1/index.html", "Single|T1_1")
 
 			last := p.Pages()[3]
-			assert.Equal("/perm-a/link/t1_5/", last.RelPermalink())
+			c.Assert(last.RelPermalink(), qt.Equals, "/perm-a/link/t1_5/")
 
 		}},
 	}
@@ -300,27 +300,27 @@
 		test := test
 		t.Run(fmt.Sprintf("sections %s", test.sections), func(t *testing.T) {
 			t.Parallel()
-			assert := require.New(t)
+			c := qt.New(t)
 			sections := strings.Split(test.sections, ",")
 			p := s.getPage(page.KindSection, sections...)
-			assert.NotNil(p, fmt.Sprint(sections))
+			c.Assert(p, qt.Not(qt.IsNil))
 
 			if p.Pages() != nil {
-				assert.Equal(p.Pages(), p.Data().(page.Data).Pages())
+				c.Assert(p.Data().(page.Data).Pages(), deepEqualsPages, p.Pages())
 			}
-			assert.NotNil(p.Parent(), fmt.Sprintf("Parent nil: %q", test.sections))
-			test.verify(assert, p)
+			c.Assert(p.Parent(), qt.Not(qt.IsNil))
+			test.verify(c, p)
 		})
 	}
 
-	assert.NotNil(home)
+	c.Assert(home, qt.Not(qt.IsNil))
 
-	assert.Len(home.Sections(), 9)
-	assert.Equal(home.Sections(), s.Info.Sections())
+	c.Assert(len(home.Sections()), qt.Equals, 9)
+	c.Assert(s.Info.Sections(), deepEqualsPages, home.Sections())
 
 	rootPage := s.getPage(page.KindPage, "mypage.md")
-	assert.NotNil(rootPage)
-	assert.True(rootPage.Parent().IsHome())
+	c.Assert(rootPage, qt.Not(qt.IsNil))
+	c.Assert(rootPage.Parent().IsHome(), qt.Equals, true)
 
 	// Add a odd test for this as this looks a little bit off, but I'm not in the mood
 	// to think too hard a out this right now. It works, but people will have to spell
@@ -329,8 +329,8 @@
 	// getPage.
 	// TODO(bep)
 	sectionWithSpace := s.getPage(page.KindSection, "Spaces in Section")
-	require.NotNil(t, sectionWithSpace)
-	require.Equal(t, "/spaces-in-section/", sectionWithSpace.RelPermalink())
+	c.Assert(sectionWithSpace, qt.Not(qt.IsNil))
+	c.Assert(sectionWithSpace.RelPermalink(), qt.Equals, "/spaces-in-section/")
 
 	th.assertFileContent("public/l1/l2/page/2/index.html", "L1/l2-IsActive: true", "PAG|T2_3|true")
 
--- a/hugolib/site_stats_test.go
+++ b/hugolib/site_stats_test.go
@@ -21,13 +21,13 @@
 
 	"github.com/gohugoio/hugo/helpers"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestSiteStats(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	siteConfig := `
 baseURL = "http://example.com/blog"
@@ -93,6 +93,6 @@
 
 	helpers.ProcessingStatsTable(&buff, stats...)
 
-	assert.Contains(buff.String(), "Pages            | 19 |  6")
+	c.Assert(buff.String(), qt.Contains, "Pages            | 19 |  6")
 
 }
--- a/hugolib/site_test.go
+++ b/hugolib/site_test.go
@@ -24,10 +24,9 @@
 
 	"github.com/gohugoio/hugo/helpers"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/resources/page"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 const (
@@ -145,6 +144,7 @@
 	t.Parallel()
 
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	writeSource(t, fs, filepath.Join("content", "sect/doc1.md"), "---\ntitle: doc1\nweight: 1\ndate: 2014-05-29\n---\n# doc1\n*some content*")
 	writeSource(t, fs, filepath.Join("content", "sect/doc2.md"), "---\ntitle: doc2\nweight: 2\ndate: 2015-05-29\n---\n# doc2\n*some content*")
@@ -154,8 +154,8 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.False(t, s.Info.LastChange().IsZero(), "Site.LastChange is zero")
-	require.Equal(t, 2017, s.Info.LastChange().Year(), "Site.LastChange should be set to the page with latest Lastmod (year 2017)")
+	c.Assert(s.Info.LastChange().IsZero(), qt.Equals, false)
+	c.Assert(s.Info.LastChange().Year(), qt.Equals, 2017)
 }
 
 // Issue #_index
@@ -163,12 +163,13 @@
 	t.Parallel()
 
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	writeSource(t, fs, filepath.Join("content", "sect/my_index_file.md"), "---\ntitle: doc1\nweight: 1\ndate: 2014-05-29\n---\n# doc1\n*some content*")
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	require.Len(t, s.RegularPages(), 1)
+	c.Assert(len(s.RegularPages()), qt.Equals, 1)
 
 }
 
@@ -184,6 +185,8 @@
 
 func doTestCrossrefs(t *testing.T, relative, uglyURLs bool) {
 
+	c := qt.New(t)
+
 	baseURL := "http://foo/bar"
 
 	var refShortcode string
@@ -253,9 +256,9 @@
 			WithTemplate: createWithTemplateFromNameValues("_default/single.html", "{{.Content}}")},
 		BuildCfg{})
 
-	require.Len(t, s.RegularPages(), 4)
+	c.Assert(len(s.RegularPages()), qt.Equals, 4)
 
-	th := testHelper{s.Cfg, s.Fs, t}
+	th := newTestHelper(s.Cfg, s.Fs, t)
 
 	tests := []struct {
 		doc      string
@@ -286,6 +289,7 @@
 func doTestShouldAlwaysHaveUglyURLs(t *testing.T, uglyURLs bool) {
 
 	cfg, fs := newTestCfg()
+	c := qt.New(t)
 
 	cfg.Set("verbose", true)
 	cfg.Set("baseURL", "http://auth/bub")
@@ -333,7 +337,7 @@
 	}
 
 	for _, p := range s.RegularPages() {
-		assert.False(t, p.IsHome())
+		c.Assert(p.IsHome(), qt.Equals, false)
 	}
 
 	for _, test := range tests {
@@ -355,7 +359,7 @@
 	writeSource(t, fs, filepath.Join("layouts", "_default/list.html"), "")
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
-	th := testHelper{s.Cfg, s.Fs, t}
+	th := newTestHelper(s.Cfg, s.Fs, t)
 
 	th.assertFileNotExist(filepath.Join("public", "index.html"))
 }
@@ -378,6 +382,7 @@
 }
 
 func doTestSectionNaming(t *testing.T, canonify, uglify, pluralize bool) {
+	c := qt.New(t)
 
 	var expectedPathSuffix string
 
@@ -412,10 +417,10 @@
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
 
 	mainSections, err := s.Info.Param("mainSections")
-	require.NoError(t, err)
-	require.Equal(t, []string{"sect"}, mainSections)
+	c.Assert(err, qt.IsNil)
+	c.Assert(mainSections, qt.DeepEquals, []string{"sect"})
 
-	th := testHelper{s.Cfg, s.Fs, t}
+	th := newTestHelper(s.Cfg, s.Fs, t)
 	tests := []struct {
 		doc         string
 		pluralAware bool
@@ -527,7 +532,7 @@
 			writeSource(t, fs, filepath.Join("layouts", "blue/single.html"), templateWithURLAbs)
 
 			s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
-			th := testHelper{s.Cfg, s.Fs, t}
+			th := newTestHelper(s.Cfg, s.Fs, t)
 
 			tests := []struct {
 				file, expected string
--- a/hugolib/site_url_test.go
+++ b/hugolib/site_url_test.go
@@ -22,8 +22,8 @@
 
 	"html/template"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
-	"github.com/stretchr/testify/require"
 )
 
 const slugDoc1 = "---\ntitle: slug doc 1\nslug: slug-doc-1\naliases:\n - /sd1/foo/\n - /sd2\n - /sd3/\n - /sd4.html\n---\nslug doc 1 content\n"
@@ -43,6 +43,8 @@
 // Issue #1105
 func TestShouldNotAddTrailingSlashToBaseURL(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
+
 	for i, this := range []struct {
 		in       string
 		expected string
@@ -56,8 +58,8 @@
 		cfg.Set("baseURL", this.in)
 		d := deps.DepsCfg{Cfg: cfg, Fs: fs}
 		s, err := NewSiteForCfg(d)
-		require.NoError(t, err)
-		require.NoError(t, s.initializeSiteInfo())
+		c.Assert(err, qt.IsNil)
+		c.Assert(s.initializeSiteInfo(), qt.IsNil)
 
 		if s.Info.BaseURL() != template.URL(this.expected) {
 			t.Errorf("[%d] got %s expected %s", i, s.Info.BaseURL(), this.expected)
@@ -94,7 +96,7 @@
 func TestUglyURLsPerSection(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	const dt = `---
 title: Do not go gentle into that good night
@@ -117,23 +119,23 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true})
 
-	assert.Len(s.RegularPages(), 2)
+	c.Assert(len(s.RegularPages()), qt.Equals, 2)
 
 	notUgly := s.getPage(page.KindPage, "sect1/p1.md")
-	assert.NotNil(notUgly)
-	assert.Equal("sect1", notUgly.Section())
-	assert.Equal("/sect1/p1/", notUgly.RelPermalink())
+	c.Assert(notUgly, qt.Not(qt.IsNil))
+	c.Assert(notUgly.Section(), qt.Equals, "sect1")
+	c.Assert(notUgly.RelPermalink(), qt.Equals, "/sect1/p1/")
 
 	ugly := s.getPage(page.KindPage, "sect2/p2.md")
-	assert.NotNil(ugly)
-	assert.Equal("sect2", ugly.Section())
-	assert.Equal("/sect2/p2.html", ugly.RelPermalink())
+	c.Assert(ugly, qt.Not(qt.IsNil))
+	c.Assert(ugly.Section(), qt.Equals, "sect2")
+	c.Assert(ugly.RelPermalink(), qt.Equals, "/sect2/p2.html")
 }
 
 func TestSectionWithURLInFrontMatter(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	const st = `---
 title: Do not go gentle into that good night
@@ -157,7 +159,7 @@
 `
 
 	cfg, fs := newTestCfg()
-	th := testHelper{cfg, fs, t}
+	th := newTestHelper(cfg, fs, t)
 
 	cfg.Set("paginate", 1)
 
@@ -175,11 +177,11 @@
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
 
-	assert.Len(s.RegularPages(), 10)
+	c.Assert(len(s.RegularPages()), qt.Equals, 10)
 
 	sect1 := s.getPage(page.KindSection, "sect1")
-	assert.NotNil(sect1)
-	assert.Equal("/ss1/", sect1.RelPermalink())
+	c.Assert(sect1, qt.Not(qt.IsNil))
+	c.Assert(sect1.RelPermalink(), qt.Equals, "/ss1/")
 	th.assertFileContent(filepath.Join("public", "ss1", "index.html"), "P1|URL: /ss1/|Next: /ss1/page/2/")
 	th.assertFileContent(filepath.Join("public", "ss1", "page", "2", "index.html"), "P2|URL: /ss1/page/2/|Next: /ss1/page/3/")
 
--- a/hugolib/sitemap_test.go
+++ b/hugolib/sitemap_test.go
@@ -18,10 +18,10 @@
 
 	"reflect"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/config"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl"
-	"github.com/stretchr/testify/require"
 )
 
 const sitemapTemplate = `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
@@ -44,6 +44,7 @@
 
 func doTestSitemapOutput(t *testing.T, internal bool) {
 
+	c := qt.New(t)
 	cfg, fs := newTestCfg()
 	cfg.Set("baseURL", "http://auth/bub/")
 
@@ -63,7 +64,7 @@
 
 	writeSourcesToSource(t, "content", fs, weightedSources...)
 	s := buildSingleSite(t, depsCfg, BuildCfg{})
-	th := testHelper{s.Cfg, s.Fs, t}
+	th := newTestHelper(s.Cfg, s.Fs, t)
 	outputSitemap := "public/sitemap.xml"
 
 	th.assertFileContent(outputSitemap,
@@ -79,8 +80,8 @@
 		"<loc>http://auth/bub/categories/hugo/</loc>",
 	)
 
-	content := readDestination(th.T, th.Fs, outputSitemap)
-	require.NotContains(t, content, "404")
+	content := readDestination(th, th.Fs, outputSitemap)
+	c.Assert(content, qt.Not(qt.Contains), "404")
 
 }
 
--- a/hugolib/taxonomy_test.go
+++ b/hugolib/taxonomy_test.go
@@ -23,7 +23,7 @@
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 
 	"github.com/gohugoio/hugo/deps"
 )
@@ -167,37 +167,37 @@
 
 	for taxonomy, count := range taxonomyTermPageCounts {
 		term := s.getPage(page.KindTaxonomyTerm, taxonomy)
-		require.NotNil(t, term)
-		require.Len(t, term.Pages(), count, taxonomy)
+		b.Assert(term, qt.Not(qt.IsNil))
+		b.Assert(len(term.Pages()), qt.Equals, count, qt.Commentf(taxonomy))
 
 		for _, p := range term.Pages() {
-			require.Equal(t, page.KindTaxonomy, p.Kind())
+			b.Assert(p.Kind(), qt.Equals, page.KindTaxonomy)
 		}
 	}
 
 	cat1 := s.getPage(page.KindTaxonomy, "categories", "cat1")
-	require.NotNil(t, cat1)
+	b.Assert(cat1, qt.Not(qt.IsNil))
 	if uglyURLs {
-		require.Equal(t, "/blog/categories/cat1.html", cat1.RelPermalink())
+		b.Assert(cat1.RelPermalink(), qt.Equals, "/blog/categories/cat1.html")
 	} else {
-		require.Equal(t, "/blog/categories/cat1/", cat1.RelPermalink())
+		b.Assert(cat1.RelPermalink(), qt.Equals, "/blog/categories/cat1/")
 	}
 
 	pl1 := s.getPage(page.KindTaxonomy, "permalinkeds", "pl1")
 	permalinkeds := s.getPage(page.KindTaxonomyTerm, "permalinkeds")
-	require.NotNil(t, pl1)
-	require.NotNil(t, permalinkeds)
+	b.Assert(pl1, qt.Not(qt.IsNil))
+	b.Assert(permalinkeds, qt.Not(qt.IsNil))
 	if uglyURLs {
-		require.Equal(t, "/blog/perma/pl1.html", pl1.RelPermalink())
-		require.Equal(t, "/blog/permalinkeds.html", permalinkeds.RelPermalink())
+		b.Assert(pl1.RelPermalink(), qt.Equals, "/blog/perma/pl1.html")
+		b.Assert(permalinkeds.RelPermalink(), qt.Equals, "/blog/permalinkeds.html")
 	} else {
-		require.Equal(t, "/blog/perma/pl1/", pl1.RelPermalink())
-		require.Equal(t, "/blog/permalinkeds/", permalinkeds.RelPermalink())
+		b.Assert(pl1.RelPermalink(), qt.Equals, "/blog/perma/pl1/")
+		b.Assert(permalinkeds.RelPermalink(), qt.Equals, "/blog/permalinkeds/")
 	}
 
 	helloWorld := s.getPage(page.KindTaxonomy, "others", "hello-hugo-world")
-	require.NotNil(t, helloWorld)
-	require.Equal(t, "Hello Hugo world", helloWorld.Title())
+	b.Assert(helloWorld, qt.Not(qt.IsNil))
+	b.Assert(helloWorld.Title(), qt.Equals, "Hello Hugo world")
 
 	// Issue #2977
 	b.AssertFileContent(pathFunc("public/empties/index.html"), "Taxonomy Term Page", "Empties")
@@ -209,8 +209,6 @@
 func TestTaxonomiesPathSeparation(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
-
 	config := `
 baseURL = "https://example.com"
 [taxonomies]
@@ -263,8 +261,8 @@
 	ta := s.findPagesByKind(page.KindTaxonomy)
 	te := s.findPagesByKind(page.KindTaxonomyTerm)
 
-	assert.Equal(4, len(te))
-	assert.Equal(7, len(ta))
+	b.Assert(len(te), qt.Equals, 4)
+	b.Assert(len(ta), qt.Equals, 7)
 
 	b.AssertFileContent("public/news/categories/a/index.html", "Taxonomy List Page 1|a|Hello|https://example.com/news/categories/a/|")
 	b.AssertFileContent("public/news/categories/b/index.html", "Taxonomy List Page 1|This is B|Hello|https://example.com/news/categories/b/|")
--- a/hugolib/template_engines_test.go
+++ b/hugolib/template_engines_test.go
@@ -97,7 +97,7 @@
 	writeSource(t, fs, filepath.Join("layouts", "shortcodes", fmt.Sprintf("myShort.%s", suffix)), shortcodeTempl)
 
 	s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{})
-	th := testHelper{s.Cfg, s.Fs, t}
+	th := newTestHelper(s.Cfg, s.Fs, t)
 
 	th.assertFileContent(filepath.Join("public", "p", "index.html"),
 		"Page Title: My Title",
--- a/hugolib/template_test.go
+++ b/hugolib/template_test.go
@@ -196,7 +196,7 @@
 		t.Run(this.name, func(t *testing.T) {
 			// TODO(bep) there are some function vars need to pull down here to enable => t.Parallel()
 			cfg, fs = newTestCfg()
-			th = testHelper{cfg, fs, t}
+			th = newTestHelper(cfg, fs, t)
 
 			for i := 1; i <= 3; i++ {
 				writeSource(t, fs, filepath.Join("content", fmt.Sprintf("sect%d", i), fmt.Sprintf("page%d.md", i)), `---
--- a/hugolib/testhelpers_test.go
+++ b/hugolib/testhelpers_test.go
@@ -8,7 +8,10 @@
 	"testing"
 	"unicode/utf8"
 
+	"github.com/gohugoio/hugo/output"
+
 	"github.com/gohugoio/hugo/parser/metadecoders"
+	"github.com/google/go-cmp/cmp"
 
 	"github.com/gohugoio/hugo/parser"
 	"github.com/pkg/errors"
@@ -36,12 +39,18 @@
 
 	"github.com/gohugoio/hugo/resources/resource"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/loggers"
 	"github.com/gohugoio/hugo/hugofs"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
+var (
+	deepEqualsPages         = qt.CmpEquals(cmp.Comparer(func(p1, p2 *pageState) bool { return p1 == p2 }))
+	deepEqualsOutputFormats = qt.CmpEquals(cmp.Comparer(func(o1, o2 output.Format) bool {
+		return o1.Name == o2.Name && o1.MediaType.Type() == o2.MediaType.Type()
+	}))
+)
+
 type sitesBuilder struct {
 	Cfg     config.Provider
 	environ []string
@@ -50,7 +59,7 @@
 	T       testing.TB
 	depsCfg deps.DepsCfg
 
-	*require.Assertions
+	*qt.C
 
 	logger *loggers.Logger
 
@@ -101,11 +110,11 @@
 		Separator:         " ",
 	}
 
-	return &sitesBuilder{T: t, Assertions: require.New(t), Fs: fs, configFormat: "toml", dumper: litterOptions}
+	return &sitesBuilder{T: t, C: qt.New(t), Fs: fs, configFormat: "toml", dumper: litterOptions}
 }
 
 func newTestSitesBuilderFromDepsCfg(t testing.TB, d deps.DepsCfg) *sitesBuilder {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	litterOptions := litter.Options{
 		HidePrivateFields: true,
@@ -113,7 +122,7 @@
 		Separator:         " ",
 	}
 
-	b := &sitesBuilder{T: t, Assertions: assert, depsCfg: d, Fs: d.Fs, dumper: litterOptions}
+	b := &sitesBuilder{T: t, C: c, depsCfg: d, Fs: d.Fs, dumper: litterOptions}
 	workingDir := d.Cfg.GetString("workingDir")
 
 	b.WithWorkingDir(workingDir)
@@ -177,7 +186,7 @@
 	// Write to a config file to make sure the tests follow the same code path.
 	var buff bytes.Buffer
 	m := v.AllSettings()
-	s.Assertions.NoError(parser.InterfaceToConfig(m, metadecoders.TOML, &buff))
+	s.Assert(parser.InterfaceToConfig(m, metadecoders.TOML, &buff), qt.IsNil)
 	return s.WithConfigFile("toml", buff.String())
 }
 
@@ -323,13 +332,13 @@
 func (s *sitesBuilder) WithSunset(in string) {
 	// Write a real image into one of the bundle above.
 	src, err := os.Open(filepath.FromSlash("testdata/sunset.jpg"))
-	s.NoError(err)
+	s.Assert(err, qt.IsNil)
 
 	out, err := s.Fs.Source.Create(filepath.FromSlash(in))
-	s.NoError(err)
+	s.Assert(err, qt.IsNil)
 
 	_, err = io.Copy(out, src)
-	s.NoError(err)
+	s.Assert(err, qt.IsNil)
 
 	out.Close()
 	src.Close()
@@ -630,10 +639,6 @@
 	s.T.Fatalf(format, args...)
 }
 
-func stackTrace() string {
-	return strings.Join(assert.CallerInfo(), "\n\r\t\t\t")
-}
-
 func (s *sitesBuilder) AssertFileContentFn(filename string, f func(s string) bool) {
 	s.T.Helper()
 	content := s.FileContent(filename)
@@ -698,36 +703,44 @@
 	return destinationExists(s.Fs, filepath.Clean(filename))
 }
 
+func newTestHelper(cfg config.Provider, fs *hugofs.Fs, t testing.TB) testHelper {
+	return testHelper{
+		Cfg: cfg,
+		Fs:  fs,
+		C:   qt.New(t),
+	}
+}
+
 type testHelper struct {
 	Cfg config.Provider
 	Fs  *hugofs.Fs
-	T   testing.TB
+	*qt.C
 }
 
 func (th testHelper) assertFileContent(filename string, matches ...string) {
-	th.T.Helper()
+	th.Helper()
 	filename = th.replaceDefaultContentLanguageValue(filename)
-	content := readDestination(th.T, th.Fs, filename)
+	content := readDestination(th, th.Fs, filename)
 	for _, match := range matches {
 		match = th.replaceDefaultContentLanguageValue(match)
-		require.True(th.T, strings.Contains(content, match), fmt.Sprintf("File no match for\n%q in\n%q:\n%s", strings.Replace(match, "%", "%%", -1), filename, strings.Replace(content, "%", "%%", -1)))
+		th.Assert(strings.Contains(content, match), qt.Equals, true)
 	}
 }
 
 func (th testHelper) assertFileContentRegexp(filename string, matches ...string) {
 	filename = th.replaceDefaultContentLanguageValue(filename)
-	content := readDestination(th.T, th.Fs, filename)
+	content := readDestination(th, th.Fs, filename)
 	for _, match := range matches {
 		match = th.replaceDefaultContentLanguageValue(match)
 		r := regexp.MustCompile(match)
-		require.True(th.T, r.MatchString(content), fmt.Sprintf("File no match for\n%q in\n%q:\n%s", strings.Replace(match, "%", "%%", -1), filename, strings.Replace(content, "%", "%%", -1)))
+		th.Assert(r.MatchString(content), qt.Equals, true)
 	}
 }
 
 func (th testHelper) assertFileNotExist(filename string) {
 	exists, err := helpers.Exists(filename, th.Fs.Destination)
-	require.NoError(th.T, err)
-	require.False(th.T, exists)
+	th.Assert(err, qt.IsNil)
+	th.Assert(exists, qt.Equals, false)
 }
 
 func (th testHelper) replaceDefaultContentLanguageValue(value string) string {
@@ -786,14 +799,16 @@
 		t.Fatalf("Layouts must be provided in pairs")
 	}
 
+	c := qt.New(t)
+
 	writeToFs(t, afs, filepath.Join("content", ".gitkeep"), "")
 	writeToFs(t, afs, "config.toml", tomlConfig)
 
 	cfg, err := LoadConfigDefault(afs)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	fs := hugofs.NewFrom(afs, cfg)
-	th := testHelper{cfg, fs, t}
+	th := newTestHelper(cfg, fs, t)
 
 	for i := 0; i < len(layoutPathContentPairs); i += 2 {
 		writeSource(t, fs, layoutPathContentPairs[i], layoutPathContentPairs[i+1])
@@ -801,7 +816,7 @@
 
 	h, err := NewHugoSites(deps.DepsCfg{Fs: fs, Cfg: cfg})
 
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	return th, h
 }
@@ -821,6 +836,7 @@
 
 // TODO(bep) replace these with the builder
 func buildSingleSite(t testing.TB, depsCfg deps.DepsCfg, buildCfg BuildCfg) *Site {
+	t.Helper()
 	return buildSingleSiteExpected(t, false, false, depsCfg, buildCfg)
 }
 
@@ -831,23 +847,23 @@
 	err := b.CreateSitesE()
 
 	if expectSiteInitEror {
-		require.Error(t, err)
+		b.Assert(err, qt.Not(qt.IsNil))
 		return nil
 	} else {
-		require.NoError(t, err)
+		b.Assert(err, qt.IsNil)
 	}
 
 	h := b.H
 
-	require.Len(t, h.Sites, 1)
+	b.Assert(len(h.Sites), qt.Equals, 1)
 
 	if expectBuildError {
-		require.Error(t, h.Build(buildCfg))
+		b.Assert(h.Build(buildCfg), qt.Not(qt.IsNil))
 		return nil
 
 	}
 
-	require.NoError(t, h.Build(buildCfg))
+	b.Assert(h.Build(buildCfg), qt.IsNil)
 
 	return h.Sites[0]
 }
--- a/langs/i18n/i18n_test.go
+++ b/langs/i18n/i18n_test.go
@@ -29,9 +29,9 @@
 
 	"github.com/gohugoio/hugo/deps"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/config"
 	"github.com/gohugoio/hugo/hugofs"
-	"github.com/stretchr/testify/require"
 )
 
 var logger = loggers.NewErrorLogger()
@@ -179,19 +179,19 @@
 }
 
 func prepareTranslationProvider(t testing.TB, test i18nTest, cfg config.Provider) *TranslationProvider {
-	assert := require.New(t)
+	c := qt.New(t)
 	fs := hugofs.NewMem(cfg)
 
 	for file, content := range test.data {
 		err := afero.WriteFile(fs.Source, filepath.Join("i18n", file), []byte(content), 0755)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 	}
 
 	tp := NewTranslationProvider()
 	depsCfg := newDepsConfig(tp, cfg, fs)
 	d, err := deps.New(depsCfg)
-	assert.NoError(err)
-	assert.NoError(d.LoadResources())
+	c.Assert(err, qt.IsNil)
+	c.Assert(d.LoadResources(), qt.IsNil)
 
 	return tp
 }
@@ -233,6 +233,7 @@
 }
 
 func TestI18nTranslate(t *testing.T) {
+	c := qt.New(t)
 	var actual, expected string
 	v := getConfig()
 
@@ -247,7 +248,7 @@
 				expected = test.expected
 			}
 			actual = doTestI18nTranslate(t, test, v)
-			require.Equal(t, expected, actual)
+			c.Assert(actual, qt.Equals, expected)
 		}
 	}
 }
--- a/langs/language_test.go
+++ b/langs/language_test.go
@@ -16,11 +16,12 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestGetGlobalOnlySetting(t *testing.T) {
+	c := qt.New(t)
 	v := viper.New()
 	v.Set("defaultContentLanguageInSubdir", true)
 	v.Set("contentDir", "content")
@@ -29,12 +30,12 @@
 	lang.Set("defaultContentLanguageInSubdir", false)
 	lang.Set("paginatePath", "side")
 
-	require.True(t, lang.GetBool("defaultContentLanguageInSubdir"))
-	require.Equal(t, "side", lang.GetString("paginatePath"))
+	c.Assert(lang.GetBool("defaultContentLanguageInSubdir"), qt.Equals, true)
+	c.Assert(lang.GetString("paginatePath"), qt.Equals, "side")
 }
 
 func TestLanguageParams(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	v := viper.New()
 	v.Set("p1", "p1cfg")
@@ -43,6 +44,6 @@
 	lang := NewDefaultLanguage(v)
 	lang.SetParam("p1", "p1p")
 
-	assert.Equal("p1p", lang.Params()["p1"])
-	assert.Equal("p1cfg", lang.Get("p1"))
+	c.Assert(lang.Params()["p1"], qt.Equals, "p1p")
+	c.Assert(lang.Get("p1"), qt.Equals, "p1cfg")
 }
--- a/lazy/init_test.go
+++ b/lazy/init_test.go
@@ -22,7 +22,7 @@
 	"testing"
 	"time"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 var (
@@ -44,7 +44,7 @@
 }
 
 func TestInit(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	var result string
 
@@ -84,7 +84,7 @@
 			var err error
 			if rnd.Intn(10) < 5 {
 				_, err = root.Do()
-				assert.NoError(err)
+				c.Assert(err, qt.IsNil)
 			}
 
 			// Add a new branch on the fly.
@@ -91,19 +91,19 @@
 			if rnd.Intn(10) > 5 {
 				branch := branch1_2.Branch(f2())
 				_, err = branch.Do()
-				assert.NoError(err)
+				c.Assert(err, qt.IsNil)
 			} else {
 				_, err = branch1_2_1.Do()
-				assert.NoError(err)
+				c.Assert(err, qt.IsNil)
 			}
 			_, err = branch1_2.Do()
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 
 		}(i)
 
 		wg.Wait()
 
-		assert.Equal("root(1)|root(2)|branch_1|branch_1_1|branch_1_2|branch_1_2_1|", result)
+		c.Assert(result, qt.Equals, "root(1)|root(2)|branch_1|branch_1_1|branch_1_2|branch_1_2_1|")
 
 	}
 
@@ -110,7 +110,7 @@
 }
 
 func TestInitAddWithTimeout(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) {
 		return nil, nil
@@ -118,11 +118,11 @@
 
 	_, err := init.Do()
 
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 }
 
 func TestInitAddWithTimeoutTimeout(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) {
 		time.Sleep(500 * time.Millisecond)
@@ -137,9 +137,9 @@
 
 	_, err := init.Do()
 
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
-	assert.Contains(err.Error(), "timed out")
+	c.Assert(err.Error(), qt.Contains, "timed out")
 
 	time.Sleep(1 * time.Second)
 
@@ -146,7 +146,7 @@
 }
 
 func TestInitAddWithTimeoutError(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) {
 		return nil, errors.New("failed")
@@ -154,7 +154,7 @@
 
 	_, err := init.Do()
 
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 }
 
 type T struct {
@@ -177,7 +177,7 @@
 
 // https://github.com/gohugoio/hugo/issues/5901
 func TestInitBranchOrder(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	base := New()
 
@@ -216,11 +216,11 @@
 		go func() {
 			defer wg.Done()
 			_, err := v.Do()
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 		}()
 	}
 
 	wg.Wait()
 
-	assert.Equal("ABAB", state.V2)
+	c.Assert(state.V2, qt.Equals, "ABAB")
 }
--- a/magefile.go
+++ b/magefile.go
@@ -304,7 +304,7 @@
 }
 
 func isGoLatest() bool {
-	return strings.Contains(runtime.Version(), "1.11")
+	return strings.Contains(runtime.Version(), "1.12")
 }
 
 func isCI() bool {
--- a/media/mediaType_test.go
+++ b/media/mediaType_test.go
@@ -16,10 +16,16 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
+	"github.com/google/go-cmp/cmp"
 )
 
+var eq = qt.CmpEquals(cmp.Comparer(func(m1, m2 Type) bool {
+	return m1.Type() == m2.Type()
+}))
+
 func TestDefaultTypes(t *testing.T) {
+	c := qt.New(t)
 	for _, test := range []struct {
 		tp               Type
 		expectedMainType string
@@ -42,103 +48,107 @@
 		{TOMLType, "application", "toml", "toml", "application/toml", "application/toml"},
 		{YAMLType, "application", "yaml", "yaml", "application/yaml", "application/yaml"},
 	} {
-		require.Equal(t, test.expectedMainType, test.tp.MainType)
-		require.Equal(t, test.expectedSubType, test.tp.SubType)
-		require.Equal(t, test.expectedSuffix, test.tp.Suffix(), test.tp.String())
-		require.Equal(t, defaultDelimiter, test.tp.Delimiter)
+		c.Assert(test.tp.MainType, qt.Equals, test.expectedMainType)
+		c.Assert(test.tp.SubType, qt.Equals, test.expectedSubType)
+		c.Assert(test.tp.Suffix(), qt.Equals, test.expectedSuffix)
+		c.Assert(test.tp.Delimiter, qt.Equals, defaultDelimiter)
 
-		require.Equal(t, test.expectedType, test.tp.Type())
-		require.Equal(t, test.expectedString, test.tp.String())
+		c.Assert(test.tp.Type(), qt.Equals, test.expectedType)
+		c.Assert(test.tp.String(), qt.Equals, test.expectedString)
 
 	}
 
-	require.Equal(t, 17, len(DefaultTypes))
+	c.Assert(len(DefaultTypes), qt.Equals, 17)
 
 }
 
 func TestGetByType(t *testing.T) {
+	c := qt.New(t)
+
 	types := Types{HTMLType, RSSType}
 
 	mt, found := types.GetByType("text/HTML")
-	require.True(t, found)
-	require.Equal(t, mt, HTMLType)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(HTMLType, eq, mt)
 
 	_, found = types.GetByType("text/nono")
-	require.False(t, found)
+	c.Assert(found, qt.Equals, false)
 
 	mt, found = types.GetByType("application/rss+xml")
-	require.True(t, found)
-	require.Equal(t, mt, RSSType)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(RSSType, eq, mt)
 
 	mt, found = types.GetByType("application/rss")
-	require.True(t, found)
-	require.Equal(t, mt, RSSType)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(RSSType, eq, mt)
 }
 
 func TestGetByMainSubType(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	f, found := DefaultTypes.GetByMainSubType("text", "plain")
-	assert.True(found)
-	assert.Equal(f, TextType)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(TextType, eq, f)
 	_, found = DefaultTypes.GetByMainSubType("foo", "plain")
-	assert.False(found)
+	c.Assert(found, qt.Equals, false)
 }
 
 func TestBySuffix(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	formats := DefaultTypes.BySuffix("xml")
-	assert.Equal(2, len(formats))
-	assert.Equal("rss", formats[0].SubType)
-	assert.Equal("xml", formats[1].SubType)
+	c.Assert(len(formats), qt.Equals, 2)
+	c.Assert(formats[0].SubType, qt.Equals, "rss")
+	c.Assert(formats[1].SubType, qt.Equals, "xml")
 }
 
 func TestGetFirstBySuffix(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	f, found := DefaultTypes.GetFirstBySuffix("xml")
-	assert.True(found)
-	assert.Equal(Type{MainType: "application", SubType: "rss", mimeSuffix: "xml", Delimiter: ".", Suffixes: []string{"xml"}, fileSuffix: "xml"}, f)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(f, eq, Type{MainType: "application", SubType: "rss", mimeSuffix: "xml", Delimiter: ".", Suffixes: []string{"xml"}, fileSuffix: "xml"})
 }
 
 func TestFromTypeString(t *testing.T) {
+	c := qt.New(t)
 	f, err := fromString("text/html")
-	require.NoError(t, err)
-	require.Equal(t, HTMLType.Type(), f.Type())
+	c.Assert(err, qt.IsNil)
+	c.Assert(f.Type(), eq, HTMLType.Type())
 
 	f, err = fromString("application/custom")
-	require.NoError(t, err)
-	require.Equal(t, Type{MainType: "application", SubType: "custom", mimeSuffix: "", fileSuffix: ""}, f)
+	c.Assert(err, qt.IsNil)
+	c.Assert(f, eq, Type{MainType: "application", SubType: "custom", mimeSuffix: "", fileSuffix: ""})
 
 	f, err = fromString("application/custom+sfx")
-	require.NoError(t, err)
-	require.Equal(t, Type{MainType: "application", SubType: "custom", mimeSuffix: "sfx"}, f)
+	c.Assert(err, qt.IsNil)
+	c.Assert(f, eq, Type{MainType: "application", SubType: "custom", mimeSuffix: "sfx"})
 
 	_, err = fromString("noslash")
-	require.Error(t, err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	f, err = fromString("text/xml; charset=utf-8")
-	require.NoError(t, err)
-	require.Equal(t, Type{MainType: "text", SubType: "xml", mimeSuffix: ""}, f)
-	require.Equal(t, "", f.Suffix())
+	c.Assert(err, qt.IsNil)
+	c.Assert(f, eq, Type{MainType: "text", SubType: "xml", mimeSuffix: ""})
+	c.Assert(f.Suffix(), qt.Equals, "")
 }
 
 // Add a test for the SVG case
 // https://github.com/gohugoio/hugo/issues/4920
 func TestFromExtensionMultipleSuffixes(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	tp, found := DefaultTypes.GetBySuffix("svg")
-	assert.True(found)
-	assert.Equal("image/svg+xml", tp.String())
-	assert.Equal("svg", tp.fileSuffix)
-	assert.Equal(".svg", tp.FullSuffix())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(tp.String(), qt.Equals, "image/svg+xml")
+	c.Assert(tp.fileSuffix, qt.Equals, "svg")
+	c.Assert(tp.FullSuffix(), qt.Equals, ".svg")
 	tp, found = DefaultTypes.GetByType("image/svg+xml")
-	assert.True(found)
-	assert.Equal("image/svg+xml", tp.String())
-	assert.True(found)
-	assert.Equal(".svg", tp.FullSuffix())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(tp.String(), qt.Equals, "image/svg+xml")
+	c.Assert(found, qt.Equals, true)
+	c.Assert(tp.FullSuffix(), qt.Equals, ".svg")
 
 }
 
 func TestDecodeTypes(t *testing.T) {
+	c := qt.New(t)
 
 	var tests = []struct {
 		name        string
@@ -154,11 +164,11 @@
 						"suffixes": []string{"jasn"}}}},
 			false,
 			func(t *testing.T, name string, tt Types) {
-				require.Len(t, tt, len(DefaultTypes))
+				c.Assert(len(tt), qt.Equals, len(DefaultTypes))
 				json, found := tt.GetBySuffix("jasn")
-				require.True(t, found)
-				require.Equal(t, "application/json", json.String(), name)
-				require.Equal(t, ".jasn", json.FullSuffix())
+				c.Assert(found, qt.Equals, true)
+				c.Assert(json.String(), qt.Equals, "application/json")
+				c.Assert(json.FullSuffix(), qt.Equals, ".jasn")
 			}},
 		{
 			"MIME suffix in key, multiple file suffixes, custom delimiter",
@@ -170,16 +180,16 @@
 					}}},
 			false,
 			func(t *testing.T, name string, tt Types) {
-				require.Len(t, tt, len(DefaultTypes)+1)
+				c.Assert(len(tt), qt.Equals, len(DefaultTypes)+1)
 				hg, found := tt.GetBySuffix("hg2")
-				require.True(t, found)
-				require.Equal(t, "hg", hg.mimeSuffix)
-				require.Equal(t, "hg2", hg.Suffix())
-				require.Equal(t, "_hg2", hg.FullSuffix())
-				require.Equal(t, "application/hugo+hg", hg.String(), name)
+				c.Assert(found, qt.Equals, true)
+				c.Assert(hg.mimeSuffix, qt.Equals, "hg")
+				c.Assert(hg.Suffix(), qt.Equals, "hg2")
+				c.Assert(hg.FullSuffix(), qt.Equals, "_hg2")
+				c.Assert(hg.String(), qt.Equals, "application/hugo+hg")
 
 				hg, found = tt.GetByType("application/hugo+hg")
-				require.True(t, found)
+				c.Assert(found, qt.Equals, true)
 
 			}},
 		{
@@ -190,15 +200,15 @@
 						"Suffixes": []string{"hgo2"}}}},
 			false,
 			func(t *testing.T, name string, tt Types) {
-				require.Len(t, tt, len(DefaultTypes)+1)
+				c.Assert(len(tt), qt.Equals, len(DefaultTypes)+1)
 				// Make sure we have not broken the default config.
 
 				_, found := tt.GetBySuffix("json")
-				require.True(t, found)
+				c.Assert(found, qt.Equals, true)
 
 				hugo, found := tt.GetBySuffix("hgo2")
-				require.True(t, found)
-				require.Equal(t, "text/hugo+hgo", hugo.String(), name)
+				c.Assert(found, qt.Equals, true)
+				c.Assert(hugo.String(), qt.Equals, "text/hugo+hgo")
 			}},
 	}
 
@@ -205,9 +215,9 @@
 	for _, test := range tests {
 		result, err := DecodeTypes(test.maps...)
 		if test.shouldError {
-			require.Error(t, err, test.name)
+			c.Assert(err, qt.Not(qt.IsNil))
 		} else {
-			require.NoError(t, err, test.name)
+			c.Assert(err, qt.IsNil)
 			test.assert(t, test.name, result)
 		}
 	}
--- a/metrics/metrics_test.go
+++ b/metrics/metrics_test.go
@@ -19,11 +19,11 @@
 
 	"github.com/gohugoio/hugo/resources/page"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestSimilarPercentage(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	sentence := "this is some words about nothing, Hugo!"
 	words := strings.Fields(sentence)
@@ -32,20 +32,20 @@
 	}
 	sentenceReversed := strings.Join(words, " ")
 
-	assert.Equal(100, howSimilar("Hugo Rules", "Hugo Rules"))
-	assert.Equal(50, howSimilar("Hugo Rules", "Hugo Rocks"))
-	assert.Equal(66, howSimilar("The Hugo Rules", "The Hugo Rocks"))
-	assert.Equal(66, howSimilar("The Hugo Rules", "The Hugo"))
-	assert.Equal(66, howSimilar("The Hugo", "The Hugo Rules"))
-	assert.Equal(0, howSimilar("Totally different", "Not Same"))
-	assert.Equal(14, howSimilar(sentence, sentenceReversed))
+	c.Assert(howSimilar("Hugo Rules", "Hugo Rules"), qt.Equals, 100)
+	c.Assert(howSimilar("Hugo Rules", "Hugo Rocks"), qt.Equals, 50)
+	c.Assert(howSimilar("The Hugo Rules", "The Hugo Rocks"), qt.Equals, 66)
+	c.Assert(howSimilar("The Hugo Rules", "The Hugo"), qt.Equals, 66)
+	c.Assert(howSimilar("The Hugo", "The Hugo Rules"), qt.Equals, 66)
+	c.Assert(howSimilar("Totally different", "Not Same"), qt.Equals, 0)
+	c.Assert(howSimilar(sentence, sentenceReversed), qt.Equals, 14)
 
 }
 
 func TestSimilarPercentageNonString(t *testing.T) {
-	assert := require.New(t)
-	assert.Equal(100, howSimilar(page.NopPage, page.NopPage))
-	assert.Equal(90, howSimilar(page.Pages{}, page.Pages{}))
+	c := qt.New(t)
+	c.Assert(howSimilar(page.NopPage, page.NopPage), qt.Equals, 100)
+	c.Assert(howSimilar(page.Pages{}, page.Pages{}), qt.Equals, 90)
 }
 
 func BenchmarkHowSimilar(b *testing.B) {
--- a/minifiers/minifiers_test.go
+++ b/minifiers/minifiers_test.go
@@ -20,12 +20,12 @@
 
 	"github.com/gohugoio/hugo/media"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/output"
-	"github.com/stretchr/testify/require"
 )
 
 func TestNew(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	m := New(media.DefaultTypes, output.DefaultFormats)
 
 	var rawJS string
@@ -66,14 +66,14 @@
 	} {
 		var b bytes.Buffer
 
-		assert.NoError(m.Minify(test.tp, &b, strings.NewReader(test.rawString)))
-		assert.Equal(test.expectedMinString, b.String())
+		c.Assert(m.Minify(test.tp, &b, strings.NewReader(test.rawString)), qt.IsNil)
+		c.Assert(b.String(), qt.Equals, test.expectedMinString)
 	}
 
 }
 
 func TestBugs(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	m := New(media.DefaultTypes, output.DefaultFormats)
 
 	for _, test := range []struct {
@@ -86,8 +86,8 @@
 	} {
 		var b bytes.Buffer
 
-		assert.NoError(m.Minify(test.tp, &b, strings.NewReader(test.rawString)))
-		assert.Equal(test.expectedMinString, b.String())
+		c.Assert(m.Minify(test.tp, &b, strings.NewReader(test.rawString)), qt.IsNil)
+		c.Assert(b.String(), qt.Equals, test.expectedMinString)
 	}
 
 }
--- a/modules/client_test.go
+++ b/modules/client_test.go
@@ -23,7 +23,7 @@
 
 	"github.com/gohugoio/hugo/hugofs"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestClient(t *testing.T) {
@@ -40,10 +40,10 @@
 	modConfig := DefaultModuleConfig
 	modConfig.Imports = []Import{Import{Path: "github.com/gohugoio/hugoTestModules1_darwin/modh2_2"}}
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	workingDir, clean, err := htesting.CreateTempDir(hugofs.Os, modName)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer clean()
 
 	client := NewClient(ClientConfig{
@@ -53,19 +53,19 @@
 	})
 
 	// Test Init
-	assert.NoError(client.Init(modPath))
+	c.Assert(client.Init(modPath), qt.IsNil)
 
 	// Test Collect
 	mc, err := client.Collect()
-	assert.NoError(err)
-	assert.Equal(4, len(mc.AllModules))
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(mc.AllModules), qt.Equals, 4)
 	for _, m := range mc.AllModules {
-		assert.NotNil(m)
+		c.Assert(m, qt.Not(qt.IsNil))
 	}
 
 	// Test Graph
 	var graphb bytes.Buffer
-	assert.NoError(client.Graph(&graphb))
+	c.Assert(client.Graph(&graphb), qt.IsNil)
 
 	expect := `github.com/gohugoio/tests/hugo-modules-basic-test github.com/gohugoio/hugoTestModules1_darwin/[email protected]
 github.com/gohugoio/hugoTestModules1_darwin/[email protected] github.com/gohugoio/hugoTestModules1_darwin/[email protected]
@@ -72,17 +72,17 @@
 github.com/gohugoio/hugoTestModules1_darwin/[email protected] github.com/gohugoio/hugoTestModules1_darwin/[email protected]
 `
 
-	assert.Equal(expect, graphb.String())
+	c.Assert(graphb.String(), qt.Equals, expect)
 
 	// Test Vendor
-	assert.NoError(client.Vendor())
+	c.Assert(client.Vendor(), qt.IsNil)
 	graphb.Reset()
-	assert.NoError(client.Graph(&graphb))
+	c.Assert(client.Graph(&graphb), qt.IsNil)
 	expectVendored := `github.com/gohugoio/tests/hugo-modules-basic-test github.com/gohugoio/hugoTestModules1_darwin/[email protected]+vendor
 github.com/gohugoio/tests/hugo-modules-basic-test github.com/gohugoio/hugoTestModules1_darwin/[email protected]+vendor
 github.com/gohugoio/tests/hugo-modules-basic-test github.com/gohugoio/hugoTestModules1_darwin/[email protected]+vendor
 `
-	assert.Equal(expectVendored, graphb.String())
+	c.Assert(graphb.String(), qt.Equals, expectVendored)
 
 	// Test the ignoreVendor setting
 	clientIgnoreVendor := NewClient(ClientConfig{
@@ -93,25 +93,25 @@
 	})
 
 	graphb.Reset()
-	assert.NoError(clientIgnoreVendor.Graph(&graphb))
-	assert.Equal(expect, graphb.String())
+	c.Assert(clientIgnoreVendor.Graph(&graphb), qt.IsNil)
+	c.Assert(graphb.String(), qt.Equals, expect)
 
 	// Test Tidy
-	assert.NoError(client.Tidy())
+	c.Assert(client.Tidy(), qt.IsNil)
 
 }
 
 func TestGetModlineSplitter(t *testing.T) {
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	gomodSplitter := getModlineSplitter(true)
 
-	assert.Equal([]string{"github.com/BurntSushi/toml", "v0.3.1"}, gomodSplitter("\tgithub.com/BurntSushi/toml v0.3.1"))
-	assert.Equal([]string{"github.com/cpuguy83/go-md2man", "v1.0.8"}, gomodSplitter("\tgithub.com/cpuguy83/go-md2man v1.0.8 // indirect"))
-	assert.Nil(gomodSplitter("require ("))
+	c.Assert(gomodSplitter("\tgithub.com/BurntSushi/toml v0.3.1"), qt.DeepEquals, []string{"github.com/BurntSushi/toml", "v0.3.1"})
+	c.Assert(gomodSplitter("\tgithub.com/cpuguy83/go-md2man v1.0.8 // indirect"), qt.DeepEquals, []string{"github.com/cpuguy83/go-md2man", "v1.0.8"})
+	c.Assert(gomodSplitter("require ("), qt.IsNil)
 
 	gosumSplitter := getModlineSplitter(false)
-	assert.Equal([]string{"github.com/BurntSushi/toml", "v0.3.1"}, gosumSplitter("github.com/BurntSushi/toml v0.3.1"))
+	c.Assert(gosumSplitter("github.com/BurntSushi/toml v0.3.1"), qt.DeepEquals, []string{"github.com/BurntSushi/toml", "v0.3.1"})
 
 }
--- a/modules/collect_test.go
+++ b/modules/collect_test.go
@@ -16,11 +16,11 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestPathKey(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	for _, test := range []struct {
 		in     string
@@ -32,7 +32,7 @@
 		{"github.com/foo/v3d", "github.com/foo/v3d"},
 		{"MyTheme", "mytheme"},
 	} {
-		assert.Equal(test.expect, pathKey(test.in))
+		c.Assert(pathKey(test.in), qt.Equals, test.expect)
 	}
 
 }
@@ -47,8 +47,8 @@
 
 	filtered := filterUnwantedMounts(mounts)
 
-	assert := require.New(t)
-	assert.Len(filtered, 2)
-	assert.Equal([]Mount{Mount{Source: "a", Target: "b", Lang: "en"}, Mount{Source: "b", Target: "c", Lang: "en"}}, filtered)
+	c := qt.New(t)
+	c.Assert(len(filtered), qt.Equals, 2)
+	c.Assert(filtered, qt.DeepEquals, []Mount{Mount{Source: "a", Target: "b", Lang: "en"}, Mount{Source: "b", Target: "c", Lang: "en"}})
 
 }
--- a/modules/config_test.go
+++ b/modules/config_test.go
@@ -14,7 +14,6 @@
 package modules
 
 import (
-	"fmt"
 	"testing"
 
 	"github.com/gohugoio/hugo/common/hugo"
@@ -21,13 +20,13 @@
 
 	"github.com/gohugoio/hugo/config"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestConfigHugoVersionIsValid(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		in     HugoVersion
 		expect bool
 	}{
@@ -36,12 +35,12 @@
 		{HugoVersion{Min: "0.33.0", Max: "0.55.0"}, false},
 		{HugoVersion{Min: "0.33.0", Max: "0.99.0"}, true},
 	} {
-		assert.Equal(test.expect, test.in.IsValid(), fmt.Sprintf("test %d", i))
+		c.Assert(test.in.IsValid(), qt.Equals, test.expect)
 	}
 }
 
 func TestDecodeConfig(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	tomlConfig := `
 [module]
 
@@ -65,35 +64,35 @@
 lang="en"
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	mcfg, err := DecodeConfig(cfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	v056 := hugo.VersionString("0.56.0")
 
 	hv := mcfg.HugoVersion
 
-	assert.Equal(-1, v056.Compare(hv.Min))
-	assert.Equal(1, v056.Compare(hv.Max))
-	assert.True(hv.Extended)
+	c.Assert(v056.Compare(hv.Min), qt.Equals, -1)
+	c.Assert(v056.Compare(hv.Max), qt.Equals, 1)
+	c.Assert(hv.Extended, qt.Equals, true)
 
 	if hugo.IsExtended {
-		assert.True(hv.IsValid())
+		c.Assert(hv.IsValid(), qt.Equals, true)
 	}
 
-	assert.Len(mcfg.Mounts, 1)
-	assert.Len(mcfg.Imports, 1)
+	c.Assert(len(mcfg.Mounts), qt.Equals, 1)
+	c.Assert(len(mcfg.Imports), qt.Equals, 1)
 	imp := mcfg.Imports[0]
 	imp.Path = "github.com/bep/mycomponent"
-	assert.Equal("src/markdown/blog", imp.Mounts[1].Source)
-	assert.Equal("content/blog", imp.Mounts[1].Target)
-	assert.Equal("en", imp.Mounts[1].Lang)
+	c.Assert(imp.Mounts[1].Source, qt.Equals, "src/markdown/blog")
+	c.Assert(imp.Mounts[1].Target, qt.Equals, "content/blog")
+	c.Assert(imp.Mounts[1].Lang, qt.Equals, "en")
 
 }
 
 func TestDecodeConfigBothOldAndNewProvided(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	tomlConfig := `
 
 theme = ["b", "c"]
@@ -104,29 +103,29 @@
 
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	modCfg, err := DecodeConfig(cfg)
-	assert.NoError(err)
-	assert.Len(modCfg.Imports, 3)
-	assert.Equal("a", modCfg.Imports[0].Path)
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(modCfg.Imports), qt.Equals, 3)
+	c.Assert(modCfg.Imports[0].Path, qt.Equals, "a")
 
 }
 
 // Test old style theme import.
 func TestDecodeConfigTheme(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	tomlConfig := `
 
 theme = ["a", "b"]
 `
 	cfg, err := config.FromConfigString(tomlConfig, "toml")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	mcfg, err := DecodeConfig(cfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Len(mcfg.Imports, 2)
-	assert.Equal("a", mcfg.Imports[0].Path)
-	assert.Equal("b", mcfg.Imports[1].Path)
+	c.Assert(len(mcfg.Imports), qt.Equals, 2)
+	c.Assert(mcfg.Imports[0].Path, qt.Equals, "a")
+	c.Assert(mcfg.Imports[1].Path, qt.Equals, "b")
 }
--- a/output/layout_base_test.go
+++ b/output/layout_base_test.go
@@ -18,10 +18,11 @@
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestLayoutBase(t *testing.T) {
+	c := qt.New(t)
 
 	var (
 		workingDir     = "/sites/mysite/"
@@ -117,7 +118,7 @@
 				MasterFilename:  "_default/single-baseof.json",
 			}},
 	} {
-		t.Run(this.name, func(t *testing.T) {
+		c.Run(this.name, func(c *qt.C) {
 
 			this.basePathMatchStrings = filepath.FromSlash(this.basePathMatchStrings)
 
@@ -152,8 +153,9 @@
 
 			id, err := CreateTemplateNames(this.d)
 
-			require.NoError(t, err)
-			require.Equal(t, this.expect, id, this.name)
+			c.Assert(err, qt.IsNil)
+			msg := qt.Commentf(this.name)
+			c.Assert(id, qt.Equals, this.expect, msg)
 
 		})
 	}
--- a/output/layout_test.go
+++ b/output/layout_test.go
@@ -21,10 +21,11 @@
 
 	"github.com/gohugoio/hugo/media"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestLayout(t *testing.T) {
+	c := qt.New(t)
 
 	noExtNoDelimMediaType := media.TextType
 	noExtNoDelimMediaType.Suffixes = nil
@@ -111,14 +112,14 @@
 		{"Reserved section, partials", LayoutDescriptor{Kind: "section", Section: "partials", Type: "partials"}, "", ampType,
 			[]string{"section/partials.amp.html"}, 12},
 	} {
-		t.Run(this.name, func(t *testing.T) {
+		c.Run(this.name, func(c *qt.C) {
 			l := NewLayoutHandler()
 
 			layouts, err := l.For(this.d, this.tp)
 
-			require.NoError(t, err)
-			require.NotNil(t, layouts)
-			require.True(t, len(layouts) >= len(this.expect), fmt.Sprint(layouts))
+			c.Assert(err, qt.IsNil)
+			c.Assert(layouts, qt.Not(qt.IsNil))
+			c.Assert(len(layouts) >= len(this.expect), qt.Equals, true)
 			// Not checking the complete list for now ...
 			got := layouts[:len(this.expect)]
 			if len(layouts) != this.expectCount || !reflect.DeepEqual(got, this.expect) {
@@ -136,12 +137,13 @@
 }
 
 func BenchmarkLayout(b *testing.B) {
+	c := qt.New(b)
 	descriptor := LayoutDescriptor{Kind: "taxonomyTerm", Section: "categories"}
 	l := NewLayoutHandler()
 
 	for i := 0; i < b.N; i++ {
 		layouts, err := l.For(descriptor, HTMLFormat)
-		require.NoError(b, err)
-		require.NotEmpty(b, layouts)
+		c.Assert(err, qt.IsNil)
+		c.Assert(layouts, qt.Not(qt.HasLen), 0)
 	}
 }
--- a/output/outputFormat_test.go
+++ b/output/outputFormat_test.go
@@ -14,88 +14,101 @@
 package output
 
 import (
-	"fmt"
 	"sort"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/media"
-	"github.com/stretchr/testify/require"
+	"github.com/google/go-cmp/cmp"
 )
 
+var eq = qt.CmpEquals(
+	cmp.Comparer(func(m1, m2 media.Type) bool {
+		return m1.Type() == m2.Type()
+	}),
+	cmp.Comparer(func(o1, o2 Format) bool {
+		return o1.Name == o2.Name
+	}),
+)
+
 func TestDefaultTypes(t *testing.T) {
-	require.Equal(t, "Calendar", CalendarFormat.Name)
-	require.Equal(t, media.CalendarType, CalendarFormat.MediaType)
-	require.Equal(t, "webcal://", CalendarFormat.Protocol)
-	require.Empty(t, CalendarFormat.Path)
-	require.True(t, CalendarFormat.IsPlainText)
-	require.False(t, CalendarFormat.IsHTML)
+	c := qt.New(t)
+	c.Assert(CalendarFormat.Name, qt.Equals, "Calendar")
+	c.Assert(CalendarFormat.MediaType, eq, media.CalendarType)
+	c.Assert(CalendarFormat.Protocol, qt.Equals, "webcal://")
+	c.Assert(CalendarFormat.Path, qt.HasLen, 0)
+	c.Assert(CalendarFormat.IsPlainText, qt.Equals, true)
+	c.Assert(CalendarFormat.IsHTML, qt.Equals, false)
 
-	require.Equal(t, "CSS", CSSFormat.Name)
-	require.Equal(t, media.CSSType, CSSFormat.MediaType)
-	require.Empty(t, CSSFormat.Path)
-	require.Empty(t, CSSFormat.Protocol) // Will inherit the BaseURL protocol.
-	require.True(t, CSSFormat.IsPlainText)
-	require.False(t, CSSFormat.IsHTML)
+	c.Assert(CSSFormat.Name, qt.Equals, "CSS")
+	c.Assert(CSSFormat.MediaType, eq, media.CSSType)
+	c.Assert(CSSFormat.Path, qt.HasLen, 0)
+	c.Assert(CSSFormat.Protocol, qt.HasLen, 0) // Will inherit the BaseURL protocol.
+	c.Assert(CSSFormat.IsPlainText, qt.Equals, true)
+	c.Assert(CSSFormat.IsHTML, qt.Equals, false)
 
-	require.Equal(t, "CSV", CSVFormat.Name)
-	require.Equal(t, media.CSVType, CSVFormat.MediaType)
-	require.Empty(t, CSVFormat.Path)
-	require.Empty(t, CSVFormat.Protocol)
-	require.True(t, CSVFormat.IsPlainText)
-	require.False(t, CSVFormat.IsHTML)
-	require.False(t, CSVFormat.Permalinkable)
+	c.Assert(CSVFormat.Name, qt.Equals, "CSV")
+	c.Assert(CSVFormat.MediaType, eq, media.CSVType)
+	c.Assert(CSVFormat.Path, qt.HasLen, 0)
+	c.Assert(CSVFormat.Protocol, qt.HasLen, 0)
+	c.Assert(CSVFormat.IsPlainText, qt.Equals, true)
+	c.Assert(CSVFormat.IsHTML, qt.Equals, false)
+	c.Assert(CSVFormat.Permalinkable, qt.Equals, false)
 
-	require.Equal(t, "HTML", HTMLFormat.Name)
-	require.Equal(t, media.HTMLType, HTMLFormat.MediaType)
-	require.Empty(t, HTMLFormat.Path)
-	require.Empty(t, HTMLFormat.Protocol)
-	require.False(t, HTMLFormat.IsPlainText)
-	require.True(t, HTMLFormat.IsHTML)
-	require.True(t, AMPFormat.Permalinkable)
+	c.Assert(HTMLFormat.Name, qt.Equals, "HTML")
+	c.Assert(HTMLFormat.MediaType, eq, media.HTMLType)
+	c.Assert(HTMLFormat.Path, qt.HasLen, 0)
+	c.Assert(HTMLFormat.Protocol, qt.HasLen, 0)
+	c.Assert(HTMLFormat.IsPlainText, qt.Equals, false)
+	c.Assert(HTMLFormat.IsHTML, qt.Equals, true)
+	c.Assert(AMPFormat.Permalinkable, qt.Equals, true)
 
-	require.Equal(t, "AMP", AMPFormat.Name)
-	require.Equal(t, media.HTMLType, AMPFormat.MediaType)
-	require.Equal(t, "amp", AMPFormat.Path)
-	require.Empty(t, AMPFormat.Protocol)
-	require.False(t, AMPFormat.IsPlainText)
-	require.True(t, AMPFormat.IsHTML)
-	require.True(t, AMPFormat.Permalinkable)
+	c.Assert(AMPFormat.Name, qt.Equals, "AMP")
+	c.Assert(AMPFormat.MediaType, eq, media.HTMLType)
+	c.Assert(AMPFormat.Path, qt.Equals, "amp")
+	c.Assert(AMPFormat.Protocol, qt.HasLen, 0)
+	c.Assert(AMPFormat.IsPlainText, qt.Equals, false)
+	c.Assert(AMPFormat.IsHTML, qt.Equals, true)
+	c.Assert(AMPFormat.Permalinkable, qt.Equals, true)
 
-	require.Equal(t, "RSS", RSSFormat.Name)
-	require.Equal(t, media.RSSType, RSSFormat.MediaType)
-	require.Empty(t, RSSFormat.Path)
-	require.False(t, RSSFormat.IsPlainText)
-	require.True(t, RSSFormat.NoUgly)
-	require.False(t, CalendarFormat.IsHTML)
+	c.Assert(RSSFormat.Name, qt.Equals, "RSS")
+	c.Assert(RSSFormat.MediaType, eq, media.RSSType)
+	c.Assert(RSSFormat.Path, qt.HasLen, 0)
+	c.Assert(RSSFormat.IsPlainText, qt.Equals, false)
+	c.Assert(RSSFormat.NoUgly, qt.Equals, true)
+	c.Assert(CalendarFormat.IsHTML, qt.Equals, false)
 
 }
 
 func TestGetFormatByName(t *testing.T) {
+	c := qt.New(t)
 	formats := Formats{AMPFormat, CalendarFormat}
 	tp, _ := formats.GetByName("AMp")
-	require.Equal(t, AMPFormat, tp)
+	c.Assert(tp, eq, AMPFormat)
 	_, found := formats.GetByName("HTML")
-	require.False(t, found)
+	c.Assert(found, qt.Equals, false)
 	_, found = formats.GetByName("FOO")
-	require.False(t, found)
+	c.Assert(found, qt.Equals, false)
 }
 
 func TestGetFormatByExt(t *testing.T) {
+	c := qt.New(t)
 	formats1 := Formats{AMPFormat, CalendarFormat}
 	formats2 := Formats{AMPFormat, HTMLFormat, CalendarFormat}
 	tp, _ := formats1.GetBySuffix("html")
-	require.Equal(t, AMPFormat, tp)
+	c.Assert(tp, eq, AMPFormat)
 	tp, _ = formats1.GetBySuffix("ics")
-	require.Equal(t, CalendarFormat, tp)
+	c.Assert(tp, eq, CalendarFormat)
 	_, found := formats1.GetBySuffix("not")
-	require.False(t, found)
+	c.Assert(found, qt.Equals, false)
 
 	// ambiguous
 	_, found = formats2.GetBySuffix("html")
-	require.False(t, found)
+	c.Assert(found, qt.Equals, false)
 }
 
 func TestGetFormatByFilename(t *testing.T) {
+	c := qt.New(t)
 	noExtNoDelimMediaType := media.TextType
 	noExtNoDelimMediaType.Delimiter = ""
 
@@ -116,25 +129,26 @@
 
 	formats := Formats{AMPFormat, HTMLFormat, noExtDelimFormat, noExt, CalendarFormat}
 	f, found := formats.FromFilename("my.amp.html")
-	require.True(t, found)
-	require.Equal(t, AMPFormat, f)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(f, eq, AMPFormat)
 	_, found = formats.FromFilename("my.ics")
-	require.True(t, found)
+	c.Assert(found, qt.Equals, true)
 	f, found = formats.FromFilename("my.html")
-	require.True(t, found)
-	require.Equal(t, HTMLFormat, f)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(f, eq, HTMLFormat)
 	f, found = formats.FromFilename("my.nem")
-	require.True(t, found)
-	require.Equal(t, noExtDelimFormat, f)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(f, eq, noExtDelimFormat)
 	f, found = formats.FromFilename("my.nex")
-	require.True(t, found)
-	require.Equal(t, noExt, f)
+	c.Assert(found, qt.Equals, true)
+	c.Assert(f, eq, noExt)
 	_, found = formats.FromFilename("my.css")
-	require.False(t, found)
+	c.Assert(found, qt.Equals, false)
 
 }
 
 func TestDecodeFormats(t *testing.T) {
+	c := qt.New(t)
 
 	mediaTypes := media.Types{media.JSONType, media.XMLType}
 
@@ -153,11 +167,12 @@
 						"isPlainText": "false"}}},
 			false,
 			func(t *testing.T, name string, f Formats) {
-				require.Len(t, f, len(DefaultFormats), name)
+				msg := qt.Commentf(name)
+				c.Assert(len(f), qt.Equals, len(DefaultFormats), msg)
 				json, _ := f.GetByName("JSON")
-				require.Equal(t, "myindex", json.BaseName)
-				require.Equal(t, media.JSONType, json.MediaType)
-				require.False(t, json.IsPlainText)
+				c.Assert(json.BaseName, qt.Equals, "myindex")
+				c.Assert(json.MediaType, eq, media.JSONType)
+				c.Assert(json.IsPlainText, qt.Equals, false)
 
 			}},
 		{
@@ -170,15 +185,15 @@
 					}}},
 			false,
 			func(t *testing.T, name string, f Formats) {
-				require.Len(t, f, len(DefaultFormats)+1, name)
+				c.Assert(len(f), qt.Equals, len(DefaultFormats)+1)
 				xml, found := f.GetByName("MYXMLFORMAT")
-				require.True(t, found)
-				require.Equal(t, "myxml", xml.BaseName, fmt.Sprint(xml))
-				require.Equal(t, media.XMLType, xml.MediaType)
+				c.Assert(found, qt.Equals, true)
+				c.Assert(xml.BaseName, qt.Equals, "myxml")
+				c.Assert(xml.MediaType, eq, media.XMLType)
 
 				// Verify that we haven't changed the DefaultFormats slice.
 				json, _ := f.GetByName("JSON")
-				require.Equal(t, "index", json.BaseName, name)
+				c.Assert(json.BaseName, qt.Equals, "index")
 
 			}},
 		{
@@ -208,20 +223,22 @@
 			},
 			false,
 			func(t *testing.T, name string, f Formats) {
-				require.Len(t, f, len(DefaultFormats)+1, name)
+				c.Assert(len(f), qt.Equals, len(DefaultFormats)+1)
 				xml, found := f.GetByName("MYOTHERXMLFORMAT")
-				require.True(t, found)
-				require.Equal(t, "myredefined", xml.BaseName, fmt.Sprint(xml))
-				require.Equal(t, media.XMLType, xml.MediaType)
+				c.Assert(found, qt.Equals, true)
+				c.Assert(xml.BaseName, qt.Equals, "myredefined")
+				c.Assert(xml.MediaType, eq, media.XMLType)
 			}},
 	}
 
 	for _, test := range tests {
 		result, err := DecodeFormats(mediaTypes, test.maps...)
+		msg := qt.Commentf(test.name)
+
 		if test.shouldError {
-			require.Error(t, err, test.name)
+			c.Assert(err, qt.Not(qt.IsNil), msg)
 		} else {
-			require.NoError(t, err, test.name)
+			c.Assert(err, qt.IsNil, msg)
 			test.assert(t, test.name, result)
 		}
 	}
@@ -228,9 +245,9 @@
 }
 
 func TestSort(t *testing.T) {
-	assert := require.New(t)
-	assert.Equal("HTML", DefaultFormats[0].Name)
-	assert.Equal("AMP", DefaultFormats[1].Name)
+	c := qt.New(t)
+	c.Assert(DefaultFormats[0].Name, qt.Equals, "HTML")
+	c.Assert(DefaultFormats[1].Name, qt.Equals, "AMP")
 
 	json := JSONFormat
 	json.Weight = 1
@@ -243,8 +260,8 @@
 
 	sort.Sort(formats)
 
-	assert.Equal("JSON", formats[0].Name)
-	assert.Equal("HTML", formats[1].Name)
-	assert.Equal("AMP", formats[2].Name)
+	c.Assert(formats[0].Name, qt.Equals, "JSON")
+	c.Assert(formats[1].Name, qt.Equals, "HTML")
+	c.Assert(formats[2].Name, qt.Equals, "AMP")
 
 }
--- a/parser/metadecoders/decoder_test.go
+++ b/parser/metadecoders/decoder_test.go
@@ -14,15 +14,14 @@
 package metadecoders
 
 import (
-	"fmt"
 	"reflect"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestUnmarshalToMap(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	expect := map[string]interface{}{"a": "b"}
 
@@ -44,19 +43,19 @@
 		{`a = b`, TOML, false},
 		{`a,b,c`, CSV, false}, // Use Unmarshal for CSV
 	} {
-		msg := fmt.Sprintf("%d: %s", i, test.format)
+		msg := qt.Commentf("%d: %s", i, test.format)
 		m, err := d.UnmarshalToMap([]byte(test.data), test.format)
 		if b, ok := test.expect.(bool); ok && !b {
-			assert.Error(err, msg)
+			c.Assert(err, qt.Not(qt.IsNil), msg)
 		} else {
-			assert.NoError(err, msg)
-			assert.Equal(test.expect, m, msg)
+			c.Assert(err, qt.IsNil, msg)
+			c.Assert(m, qt.DeepEquals, test.expect, msg)
 		}
 	}
 }
 
 func TestUnmarshalToInterface(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	expect := map[string]interface{}{"a": "b"}
 
@@ -77,13 +76,13 @@
 		// errors
 		{`a = "`, TOML, false},
 	} {
-		msg := fmt.Sprintf("%d: %s", i, test.format)
+		msg := qt.Commentf("%d: %s", i, test.format)
 		m, err := d.Unmarshal([]byte(test.data), test.format)
 		if b, ok := test.expect.(bool); ok && !b {
-			assert.Error(err, msg)
+			c.Assert(err, qt.Not(qt.IsNil), msg)
 		} else {
-			assert.NoError(err, msg)
-			assert.Equal(test.expect, m, msg)
+			c.Assert(err, qt.IsNil, msg)
+			c.Assert(m, qt.DeepEquals, test.expect, msg)
 		}
 
 	}
@@ -91,7 +90,7 @@
 }
 
 func TestUnmarshalStringTo(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	d := Default
 
@@ -110,13 +109,13 @@
 		{"[3,7,9]", []interface{}{}, []interface{}{3, 7, 9}},
 		{"[3.1,7.2,9.3]", []interface{}{}, []interface{}{3.1, 7.2, 9.3}},
 	} {
-		msg := fmt.Sprintf("%d: %T", i, test.to)
+		msg := qt.Commentf("%d: %T", i, test.to)
 		m, err := d.UnmarshalStringTo(test.data, test.to)
 		if b, ok := test.expect.(bool); ok && !b {
-			assert.Error(err, msg)
+			c.Assert(err, qt.Not(qt.IsNil), msg)
 		} else {
-			assert.NoError(err, msg)
-			assert.Equal(test.expect, m, msg)
+			c.Assert(err, qt.IsNil, msg)
+			c.Assert(m, qt.DeepEquals, test.expect, msg)
 		}
 
 	}
--- a/parser/metadecoders/format_test.go
+++ b/parser/metadecoders/format_test.go
@@ -14,7 +14,6 @@
 package metadecoders
 
 import (
-	"fmt"
 	"testing"
 
 	"github.com/gohugoio/hugo/media"
@@ -21,12 +20,12 @@
 
 	"github.com/gohugoio/hugo/parser/pageparser"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestFormatFromString(t *testing.T) {
-	assert := require.New(t)
-	for i, test := range []struct {
+	c := qt.New(t)
+	for _, test := range []struct {
 		s      string
 		expect Format
 	}{
@@ -39,13 +38,13 @@
 		{"org", ORG},
 		{"foo", ""},
 	} {
-		assert.Equal(test.expect, FormatFromString(test.s), fmt.Sprintf("t%d", i))
+		c.Assert(FormatFromString(test.s), qt.Equals, test.expect)
 	}
 }
 
 func TestFormatFromMediaType(t *testing.T) {
-	assert := require.New(t)
-	for i, test := range []struct {
+	c := qt.New(t)
+	for _, test := range []struct {
 		m      media.Type
 		expect Format
 	}{
@@ -54,13 +53,13 @@
 		{media.TOMLType, TOML},
 		{media.CalendarType, ""},
 	} {
-		assert.Equal(test.expect, FormatFromMediaType(test.m), fmt.Sprintf("t%d", i))
+		c.Assert(FormatFromMediaType(test.m), qt.Equals, test.expect)
 	}
 }
 
 func TestFormatFromFrontMatterType(t *testing.T) {
-	assert := require.New(t)
-	for i, test := range []struct {
+	c := qt.New(t)
+	for _, test := range []struct {
 		typ    pageparser.ItemType
 		expect Format
 	}{
@@ -70,13 +69,13 @@
 		{pageparser.TypeFrontMatterORG, ORG},
 		{pageparser.TypeIgnore, ""},
 	} {
-		assert.Equal(test.expect, FormatFromFrontMatterType(test.typ), fmt.Sprintf("t%d", i))
+		c.Assert(FormatFromFrontMatterType(test.typ), qt.Equals, test.expect)
 	}
 }
 
 func TestFormatFromContentString(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	for i, test := range []struct {
 		data   string
@@ -92,10 +91,10 @@
 		{`asdfasdf`, Format("")},
 		{``, Format("")},
 	} {
-		errMsg := fmt.Sprintf("[%d] %s", i, test.data)
+		errMsg := qt.Commentf("[%d] %s", i, test.data)
 
 		result := Default.FormatFromContentString(test.data)
 
-		assert.Equal(test.expect, result, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
--- a/parser/pageparser/pagelexer_test.go
+++ b/parser/pageparser/pagelexer_test.go
@@ -16,14 +16,14 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestMinIndex(t *testing.T) {
-	assert := require.New(t)
-	assert.Equal(1, minIndex(4, 1, 2, 3))
-	assert.Equal(0, minIndex(4, 0, -2, 2, 5))
-	assert.Equal(-1, minIndex())
-	assert.Equal(-1, minIndex(-2, -3))
+	c := qt.New(t)
+	c.Assert(minIndex(4, 1, 2, 3), qt.Equals, 1)
+	c.Assert(minIndex(4, 0, -2, 2, 5), qt.Equals, 0)
+	c.Assert(minIndex(), qt.Equals, -1)
+	c.Assert(minIndex(-2, -3), qt.Equals, -1)
 
 }
--- a/related/inverted_index_test.go
+++ b/related/inverted_index_test.go
@@ -19,7 +19,7 @@
 	"testing"
 	"time"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 type testDoc struct {
@@ -109,62 +109,62 @@
 	idx.Add(docs...)
 
 	t.Run("count", func(t *testing.T) {
-		assert := require.New(t)
-		assert.Len(idx.index, 2)
+		c := qt.New(t)
+		c.Assert(len(idx.index), qt.Equals, 2)
 		set1, found := idx.index["tags"]
-		assert.True(found)
+		c.Assert(found, qt.Equals, true)
 		// 6 tags
-		assert.Len(set1, 6)
+		c.Assert(len(set1), qt.Equals, 6)
 
 		set2, found := idx.index["keywords"]
-		assert.True(found)
-		assert.Len(set2, 2)
+		c.Assert(found, qt.Equals, true)
+		c.Assert(len(set2), qt.Equals, 2)
 
 	})
 
 	t.Run("search-tags", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		m, err := idx.search(newQueryElement("tags", StringsToKeywords("a", "b", "d", "z")...))
-		assert.NoError(err)
-		assert.Len(m, 2)
-		assert.Equal(docs[0], m[0])
-		assert.Equal(docs[1], m[1])
+		c.Assert(err, qt.IsNil)
+		c.Assert(len(m), qt.Equals, 2)
+		c.Assert(m[0], qt.Equals, docs[0])
+		c.Assert(m[1], qt.Equals, docs[1])
 	})
 
 	t.Run("search-tags-and-keywords", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		m, err := idx.search(
 			newQueryElement("tags", StringsToKeywords("a", "b", "z")...),
 			newQueryElement("keywords", StringsToKeywords("a", "b")...))
-		assert.NoError(err)
-		assert.Len(m, 3)
-		assert.Equal(docs[3], m[0])
-		assert.Equal(docs[2], m[1])
-		assert.Equal(docs[0], m[2])
+		c.Assert(err, qt.IsNil)
+		c.Assert(len(m), qt.Equals, 3)
+		c.Assert(m[0], qt.Equals, docs[3])
+		c.Assert(m[1], qt.Equals, docs[2])
+		c.Assert(m[2], qt.Equals, docs[0])
 	})
 
 	t.Run("searchdoc-all", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		doc := newTestDoc("tags", "a").addKeywords("keywords", "a")
 		m, err := idx.SearchDoc(doc)
-		assert.NoError(err)
-		assert.Len(m, 2)
-		assert.Equal(docs[3], m[0])
-		assert.Equal(docs[2], m[1])
+		c.Assert(err, qt.IsNil)
+		c.Assert(len(m), qt.Equals, 2)
+		c.Assert(m[0], qt.Equals, docs[3])
+		c.Assert(m[1], qt.Equals, docs[2])
 	})
 
 	t.Run("searchdoc-tags", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		doc := newTestDoc("tags", "a", "b", "d", "z").addKeywords("keywords", "a", "b")
 		m, err := idx.SearchDoc(doc, "tags")
-		assert.NoError(err)
-		assert.Len(m, 2)
-		assert.Equal(docs[0], m[0])
-		assert.Equal(docs[1], m[1])
+		c.Assert(err, qt.IsNil)
+		c.Assert(len(m), qt.Equals, 2)
+		c.Assert(m[0], qt.Equals, docs[0])
+		c.Assert(m[1], qt.Equals, docs[1])
 	})
 
 	t.Run("searchdoc-keywords-date", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		doc := newTestDoc("tags", "a", "b", "d", "z").addKeywords("keywords", "a", "b")
 		// This will get a date newer than the others.
 		newDoc := newTestDoc("keywords", "a", "b")
@@ -171,13 +171,13 @@
 		idx.Add(newDoc)
 
 		m, err := idx.SearchDoc(doc, "keywords")
-		assert.NoError(err)
-		assert.Len(m, 2)
-		assert.Equal(docs[3], m[0])
+		c.Assert(err, qt.IsNil)
+		c.Assert(len(m), qt.Equals, 2)
+		c.Assert(m[0], qt.Equals, docs[3])
 	})
 
 	t.Run("searchdoc-keywords-same-date", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		idx := NewInvertedIndex(config)
 
 		date := time.Now()
@@ -192,10 +192,10 @@
 		}
 
 		m, err := idx.SearchDoc(doc, "keywords")
-		assert.NoError(err)
-		assert.Len(m, 10)
+		c.Assert(err, qt.IsNil)
+		c.Assert(len(m), qt.Equals, 10)
 		for i := 0; i < 10; i++ {
-			assert.Equal(fmt.Sprintf("doc%d", i), m[i].Name())
+			c.Assert(m[i].Name(), qt.Equals, fmt.Sprintf("doc%d", i))
 		}
 	})
 
--- a/releaser/git_test.go
+++ b/releaser/git_test.go
@@ -16,19 +16,20 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestGitInfos(t *testing.T) {
+	c := qt.New(t)
 	skipIfCI(t)
 	infos, err := getGitInfos("v0.20", "hugo", "", false)
 
-	require.NoError(t, err)
-	require.True(t, len(infos) > 0)
-
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(infos) > 0, qt.Equals, true)
 }
 
 func TestIssuesRe(t *testing.T) {
+	c := qt.New(t)
 
 	body := `
 This is a commit message.
@@ -41,28 +42,30 @@
 
 	issues := extractIssues(body)
 
-	require.Len(t, issues, 4)
-	require.Equal(t, 123, issues[0])
-	require.Equal(t, 543, issues[2])
+	c.Assert(len(issues), qt.Equals, 4)
+	c.Assert(issues[0], qt.Equals, 123)
+	c.Assert(issues[2], qt.Equals, 543)
 
 }
 
 func TestGitVersionTagBefore(t *testing.T) {
 	skipIfCI(t)
+	c := qt.New(t)
 	v1, err := gitVersionTagBefore("v0.18")
-	require.NoError(t, err)
-	require.Equal(t, "v0.17", v1)
+	c.Assert(err, qt.IsNil)
+	c.Assert(v1, qt.Equals, "v0.17")
 }
 
 func TestTagExists(t *testing.T) {
 	skipIfCI(t)
+	c := qt.New(t)
 	b1, err := tagExists("v0.18")
-	require.NoError(t, err)
-	require.True(t, b1)
+	c.Assert(err, qt.IsNil)
+	c.Assert(b1, qt.Equals, true)
 
 	b2, err := tagExists("adfagdsfg")
-	require.NoError(t, err)
-	require.False(t, b2)
+	c.Assert(err, qt.IsNil)
+	c.Assert(b2, qt.Equals, false)
 
 }
 
--- a/releaser/github_test.go
+++ b/releaser/github_test.go
@@ -18,22 +18,24 @@
 	"os"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestGitHubLookupCommit(t *testing.T) {
 	skipIfNoToken(t)
+	c := qt.New(t)
 	client := newGitHubAPI("hugo")
 	commit, err := client.fetchCommit("793554108763c0984f1a1b1a6ee5744b560d78d0")
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 	fmt.Println(commit)
 }
 
 func TestFetchRepo(t *testing.T) {
 	skipIfNoToken(t)
+	c := qt.New(t)
 	client := newGitHubAPI("hugo")
 	repo, err := client.fetchRepo()
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 	fmt.Println(">>", len(repo.Contributors))
 }
 
--- a/releaser/releasenotes_writer_test.go
+++ b/releaser/releasenotes_writer_test.go
@@ -22,7 +22,7 @@
 	"os"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func _TestReleaseNotesWriter(t *testing.T) {
@@ -30,14 +30,15 @@
 		// Travis has an ancient git with no --invert-grep: https://github.com/travis-ci/travis-ci/issues/6328
 		t.Skip("Skip git test on CI to make Travis happy.")
 	}
+	c := qt.New(t)
 
 	var b bytes.Buffer
 
 	// TODO(bep) consider to query GitHub directly for the gitlog with author info, probably faster.
 	infos, err := getGitInfosBefore("HEAD", "v0.20", "hugo", "", false)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
-	require.NoError(t, writeReleaseNotes("0.21", infos, infos, &b))
+	c.Assert(writeReleaseNotes("0.21", infos, infos, &b), qt.IsNil)
 
 	fmt.Println(b.String())
 
--- a/resources/image_test.go
+++ b/resources/image_test.go
@@ -20,11 +20,13 @@
 	"strconv"
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
 	"github.com/disintegration/imaging"
 
 	"sync"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestParseImageConfig(t *testing.T) {
@@ -59,107 +61,107 @@
 
 func TestImageTransformBasic(t *testing.T) {
 
-	assert := require.New(t)
+	c := qt.New(t)
 
-	image := fetchSunset(assert)
+	image := fetchSunset(c)
 	fileCache := image.spec.FileCaches.ImageCache().Fs
 
-	assert.Equal("/a/sunset.jpg", image.RelPermalink())
-	assert.Equal("image", image.ResourceType())
+	c.Assert(image.RelPermalink(), qt.Equals, "/a/sunset.jpg")
+	c.Assert(image.ResourceType(), qt.Equals, "image")
 
 	resized, err := image.Resize("300x200")
-	assert.NoError(err)
-	assert.True(image != resized)
-	assert.True(image.genericResource != resized.genericResource)
-	assert.True(image.sourceFilename != resized.sourceFilename)
+	c.Assert(err, qt.IsNil)
+	c.Assert(image != resized, qt.Equals, true)
+	c.Assert(image.genericResource != resized.genericResource, qt.Equals, true)
+	c.Assert(image.sourceFilename != resized.sourceFilename, qt.Equals, true)
 
 	resized0x, err := image.Resize("x200")
-	assert.NoError(err)
-	assert.Equal(320, resized0x.Width())
-	assert.Equal(200, resized0x.Height())
+	c.Assert(err, qt.IsNil)
+	c.Assert(resized0x.Width(), qt.Equals, 320)
+	c.Assert(resized0x.Height(), qt.Equals, 200)
 
-	assertFileCache(assert, fileCache, resized0x.RelPermalink(), 320, 200)
+	assertFileCache(c, fileCache, resized0x.RelPermalink(), 320, 200)
 
 	resizedx0, err := image.Resize("200x")
-	assert.NoError(err)
-	assert.Equal(200, resizedx0.Width())
-	assert.Equal(125, resizedx0.Height())
-	assertFileCache(assert, fileCache, resizedx0.RelPermalink(), 200, 125)
+	c.Assert(err, qt.IsNil)
+	c.Assert(resizedx0.Width(), qt.Equals, 200)
+	c.Assert(resizedx0.Height(), qt.Equals, 125)
+	assertFileCache(c, fileCache, resizedx0.RelPermalink(), 200, 125)
 
 	resizedAndRotated, err := image.Resize("x200 r90")
-	assert.NoError(err)
-	assert.Equal(125, resizedAndRotated.Width())
-	assert.Equal(200, resizedAndRotated.Height())
-	assertFileCache(assert, fileCache, resizedAndRotated.RelPermalink(), 125, 200)
+	c.Assert(err, qt.IsNil)
+	c.Assert(resizedAndRotated.Width(), qt.Equals, 125)
+	c.Assert(resizedAndRotated.Height(), qt.Equals, 200)
+	assertFileCache(c, fileCache, resizedAndRotated.RelPermalink(), 125, 200)
 
-	assert.Equal("/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_300x200_resize_q68_linear.jpg", resized.RelPermalink())
-	assert.Equal(300, resized.Width())
-	assert.Equal(200, resized.Height())
+	c.Assert(resized.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_300x200_resize_q68_linear.jpg")
+	c.Assert(resized.Width(), qt.Equals, 300)
+	c.Assert(resized.Height(), qt.Equals, 200)
 
 	fitted, err := resized.Fit("50x50")
-	assert.NoError(err)
-	assert.Equal("/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_625708021e2bb281c9f1002f88e4753f.jpg", fitted.RelPermalink())
-	assert.Equal(50, fitted.Width())
-	assert.Equal(33, fitted.Height())
+	c.Assert(err, qt.IsNil)
+	c.Assert(fitted.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_625708021e2bb281c9f1002f88e4753f.jpg")
+	c.Assert(fitted.Width(), qt.Equals, 50)
+	c.Assert(fitted.Height(), qt.Equals, 33)
 
 	// Check the MD5 key threshold
 	fittedAgain, _ := fitted.Fit("10x20")
 	fittedAgain, err = fittedAgain.Fit("10x20")
-	assert.NoError(err)
-	assert.Equal("/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_3f65ba24dc2b7fba0f56d7f104519157.jpg", fittedAgain.RelPermalink())
-	assert.Equal(10, fittedAgain.Width())
-	assert.Equal(6, fittedAgain.Height())
+	c.Assert(err, qt.IsNil)
+	c.Assert(fittedAgain.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_3f65ba24dc2b7fba0f56d7f104519157.jpg")
+	c.Assert(fittedAgain.Width(), qt.Equals, 10)
+	c.Assert(fittedAgain.Height(), qt.Equals, 6)
 
 	filled, err := image.Fill("200x100 bottomLeft")
-	assert.NoError(err)
-	assert.Equal("/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x100_fill_q68_linear_bottomleft.jpg", filled.RelPermalink())
-	assert.Equal(200, filled.Width())
-	assert.Equal(100, filled.Height())
-	assertFileCache(assert, fileCache, filled.RelPermalink(), 200, 100)
+	c.Assert(err, qt.IsNil)
+	c.Assert(filled.RelPermalink(), qt.Equals, "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x100_fill_q68_linear_bottomleft.jpg")
+	c.Assert(filled.Width(), qt.Equals, 200)
+	c.Assert(filled.Height(), qt.Equals, 100)
+	assertFileCache(c, fileCache, filled.RelPermalink(), 200, 100)
 
 	smart, err := image.Fill("200x100 smart")
-	assert.NoError(err)
-	assert.Equal(fmt.Sprintf("/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x100_fill_q68_linear_smart%d.jpg", smartCropVersionNumber), smart.RelPermalink())
-	assert.Equal(200, smart.Width())
-	assert.Equal(100, smart.Height())
-	assertFileCache(assert, fileCache, smart.RelPermalink(), 200, 100)
+	c.Assert(err, qt.IsNil)
+	c.Assert(smart.RelPermalink(), qt.Equals, fmt.Sprintf("/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_200x100_fill_q68_linear_smart%d.jpg", smartCropVersionNumber))
+	c.Assert(smart.Width(), qt.Equals, 200)
+	c.Assert(smart.Height(), qt.Equals, 100)
+	assertFileCache(c, fileCache, smart.RelPermalink(), 200, 100)
 
 	// Check cache
 	filledAgain, err := image.Fill("200x100 bottomLeft")
-	assert.NoError(err)
-	assert.True(filled == filledAgain)
-	assert.True(filled.sourceFilename == filledAgain.sourceFilename)
-	assertFileCache(assert, fileCache, filledAgain.RelPermalink(), 200, 100)
+	c.Assert(err, qt.IsNil)
+	c.Assert(filled == filledAgain, qt.Equals, true)
+	c.Assert(filled.sourceFilename == filledAgain.sourceFilename, qt.Equals, true)
+	assertFileCache(c, fileCache, filledAgain.RelPermalink(), 200, 100)
 
 }
 
 // https://github.com/gohugoio/hugo/issues/4261
 func TestImageTransformLongFilename(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
-	image := fetchImage(assert, "1234567890qwertyuiopasdfghjklzxcvbnm5to6eeeeee7via8eleph.jpg")
-	assert.NotNil(image)
+	image := fetchImage(c, "1234567890qwertyuiopasdfghjklzxcvbnm5to6eeeeee7via8eleph.jpg")
+	c.Assert(image, qt.Not(qt.IsNil))
 
 	resized, err := image.Resize("200x")
-	assert.NoError(err)
-	assert.NotNil(resized)
-	assert.Equal(200, resized.Width())
-	assert.Equal("/a/_hu59e56ffff1bc1d8d122b1403d34e039f_90587_65b757a6e14debeae720fe8831f0a9bc.jpg", resized.RelPermalink())
+	c.Assert(err, qt.IsNil)
+	c.Assert(resized, qt.Not(qt.IsNil))
+	c.Assert(resized.Width(), qt.Equals, 200)
+	c.Assert(resized.RelPermalink(), qt.Equals, "/a/_hu59e56ffff1bc1d8d122b1403d34e039f_90587_65b757a6e14debeae720fe8831f0a9bc.jpg")
 	resized, err = resized.Resize("100x")
-	assert.NoError(err)
-	assert.NotNil(resized)
-	assert.Equal(100, resized.Width())
-	assert.Equal("/a/_hu59e56ffff1bc1d8d122b1403d34e039f_90587_c876768085288f41211f768147ba2647.jpg", resized.RelPermalink())
+	c.Assert(err, qt.IsNil)
+	c.Assert(resized, qt.Not(qt.IsNil))
+	c.Assert(resized.Width(), qt.Equals, 100)
+	c.Assert(resized.RelPermalink(), qt.Equals, "/a/_hu59e56ffff1bc1d8d122b1403d34e039f_90587_c876768085288f41211f768147ba2647.jpg")
 }
 
 // Issue 6137
 func TestImageTransformUppercaseExt(t *testing.T) {
-	assert := require.New(t)
-	image := fetchImage(assert, "sunrise.JPG")
+	c := qt.New(t)
+	image := fetchImage(c, "sunrise.JPG")
 	resized, err := image.Resize("200x")
-	assert.NoError(err)
-	assert.NotNil(resized)
-	assert.Equal(200, resized.Width())
+	c.Assert(err, qt.IsNil)
+	c.Assert(resized, qt.Not(qt.IsNil))
+	c.Assert(resized.Width(), qt.Equals, 200)
 }
 
 // https://github.com/gohugoio/hugo/issues/5730
@@ -172,22 +174,22 @@
 
 		t.Run(name, func(t *testing.T) {
 
-			assert := require.New(t)
-			spec := newTestResourceOsFs(assert)
+			c := qt.New(t)
+			spec := newTestResourceOsFs(c)
 
 			check1 := func(img *Image) {
 				resizedLink := "/a/sunset_hu59e56ffff1bc1d8d122b1403d34e039f_90587_100x50_resize_q75_box.jpg"
-				assert.Equal(resizedLink, img.RelPermalink())
-				assertImageFile(assert, spec.PublishFs, resizedLink, 100, 50)
+				c.Assert(img.RelPermalink(), qt.Equals, resizedLink)
+				assertImageFile(c, spec.PublishFs, resizedLink, 100, 50)
 			}
 
 			check2 := func(img *Image) {
-				assert.Equal("/a/sunset.jpg", img.RelPermalink())
-				assertImageFile(assert, spec.PublishFs, "a/sunset.jpg", 900, 562)
+				c.Assert(img.RelPermalink(), qt.Equals, "/a/sunset.jpg")
+				assertImageFile(c, spec.PublishFs, "a/sunset.jpg", 900, 562)
 			}
 
-			orignal := fetchImageForSpec(spec, assert, "sunset.jpg")
-			assert.NotNil(orignal)
+			orignal := fetchImageForSpec(spec, c, "sunset.jpg")
+			c.Assert(orignal, qt.Not(qt.IsNil))
 
 			if checkOriginalFirst {
 				check2(orignal)
@@ -194,7 +196,7 @@
 			}
 
 			resized, err := orignal.Resize("100x50")
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 
 			check1(resized)
 
@@ -210,11 +212,11 @@
 
 	var wg sync.WaitGroup
 
-	assert := require.New(t)
+	c := qt.New(t)
 
-	spec := newTestResourceOsFs(assert)
+	spec := newTestResourceOsFs(c)
 
-	image := fetchImageForSpec(spec, assert, "sunset.jpg")
+	image := fetchImageForSpec(spec, c, "sunset.jpg")
 
 	for i := 0; i < 4; i++ {
 		wg.Add(1)
@@ -252,7 +254,7 @@
 }
 
 func TestDecodeImaging(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	m := map[string]interface{}{
 		"quality":        42,
 		"resampleFilter": "NearestNeighbor",
@@ -261,46 +263,46 @@
 
 	imaging, err := decodeImaging(m)
 
-	assert.NoError(err)
-	assert.Equal(42, imaging.Quality)
-	assert.Equal("nearestneighbor", imaging.ResampleFilter)
-	assert.Equal("topleft", imaging.Anchor)
+	c.Assert(err, qt.IsNil)
+	c.Assert(imaging.Quality, qt.Equals, 42)
+	c.Assert(imaging.ResampleFilter, qt.Equals, "nearestneighbor")
+	c.Assert(imaging.Anchor, qt.Equals, "topleft")
 
 	m = map[string]interface{}{}
 
 	imaging, err = decodeImaging(m)
-	assert.NoError(err)
-	assert.Equal(defaultJPEGQuality, imaging.Quality)
-	assert.Equal("box", imaging.ResampleFilter)
-	assert.Equal("smart", imaging.Anchor)
+	c.Assert(err, qt.IsNil)
+	c.Assert(imaging.Quality, qt.Equals, defaultJPEGQuality)
+	c.Assert(imaging.ResampleFilter, qt.Equals, "box")
+	c.Assert(imaging.Anchor, qt.Equals, "smart")
 
 	_, err = decodeImaging(map[string]interface{}{
 		"quality": 123,
 	})
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	_, err = decodeImaging(map[string]interface{}{
 		"resampleFilter": "asdf",
 	})
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	_, err = decodeImaging(map[string]interface{}{
 		"anchor": "asdf",
 	})
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	imaging, err = decodeImaging(map[string]interface{}{
 		"anchor": "Smart",
 	})
-	assert.NoError(err)
-	assert.Equal("smart", imaging.Anchor)
+	c.Assert(err, qt.IsNil)
+	c.Assert(imaging.Anchor, qt.Equals, "smart")
 
 }
 
 func TestImageWithMetadata(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
-	image := fetchSunset(assert)
+	image := fetchSunset(c)
 
 	var meta = []map[string]interface{}{
 		{
@@ -310,89 +312,89 @@
 		},
 	}
 
-	assert.NoError(AssignMetadata(meta, image))
-	assert.Equal("Sunset #1", image.Name())
+	c.Assert(AssignMetadata(meta, image), qt.IsNil)
+	c.Assert(image.Name(), qt.Equals, "Sunset #1")
 
 	resized, err := image.Resize("200x")
-	assert.NoError(err)
-	assert.Equal("Sunset #1", resized.Name())
+	c.Assert(err, qt.IsNil)
+	c.Assert(resized.Name(), qt.Equals, "Sunset #1")
 
 }
 
 func TestImageResize8BitPNG(t *testing.T) {
 
-	assert := require.New(t)
+	c := qt.New(t)
 
-	image := fetchImage(assert, "gohugoio.png")
+	image := fetchImage(c, "gohugoio.png")
 
-	assert.Equal(imaging.PNG, image.format)
-	assert.Equal("/a/gohugoio.png", image.RelPermalink())
-	assert.Equal("image", image.ResourceType())
+	c.Assert(image.format, qt.Equals, imaging.PNG)
+	c.Assert(image.RelPermalink(), qt.Equals, "/a/gohugoio.png")
+	c.Assert(image.ResourceType(), qt.Equals, "image")
 
 	resized, err := image.Resize("800x")
-	assert.NoError(err)
-	assert.Equal(imaging.PNG, resized.format)
-	assert.Equal("/a/gohugoio_hu0e1b9e4a4be4d6f86c7b37b9ccce3fbc_73886_800x0_resize_linear_2.png", resized.RelPermalink())
-	assert.Equal(800, resized.Width())
+	c.Assert(err, qt.IsNil)
+	c.Assert(resized.format, qt.Equals, imaging.PNG)
+	c.Assert(resized.RelPermalink(), qt.Equals, "/a/gohugoio_hu0e1b9e4a4be4d6f86c7b37b9ccce3fbc_73886_800x0_resize_linear_2.png")
+	c.Assert(resized.Width(), qt.Equals, 800)
 
 }
 
 func TestImageResizeInSubPath(t *testing.T) {
 
-	assert := require.New(t)
+	c := qt.New(t)
 
-	image := fetchImage(assert, "sub/gohugoio2.png")
+	image := fetchImage(c, "sub/gohugoio2.png")
 	fileCache := image.spec.FileCaches.ImageCache().Fs
 
-	assert.Equal(imaging.PNG, image.format)
-	assert.Equal("/a/sub/gohugoio2.png", image.RelPermalink())
-	assert.Equal("image", image.ResourceType())
+	c.Assert(image.format, qt.Equals, imaging.PNG)
+	c.Assert(image.RelPermalink(), qt.Equals, "/a/sub/gohugoio2.png")
+	c.Assert(image.ResourceType(), qt.Equals, "image")
 
 	resized, err := image.Resize("101x101")
-	assert.NoError(err)
-	assert.Equal(imaging.PNG, resized.format)
-	assert.Equal("/a/sub/gohugoio2_hu0e1b9e4a4be4d6f86c7b37b9ccce3fbc_73886_101x101_resize_linear_2.png", resized.RelPermalink())
-	assert.Equal(101, resized.Width())
+	c.Assert(err, qt.IsNil)
+	c.Assert(resized.format, qt.Equals, imaging.PNG)
+	c.Assert(resized.RelPermalink(), qt.Equals, "/a/sub/gohugoio2_hu0e1b9e4a4be4d6f86c7b37b9ccce3fbc_73886_101x101_resize_linear_2.png")
+	c.Assert(resized.Width(), qt.Equals, 101)
 
-	assertFileCache(assert, fileCache, resized.RelPermalink(), 101, 101)
+	assertFileCache(c, fileCache, resized.RelPermalink(), 101, 101)
 	publishedImageFilename := filepath.Clean(resized.RelPermalink())
-	assertImageFile(assert, image.spec.BaseFs.PublishFs, publishedImageFilename, 101, 101)
-	assert.NoError(image.spec.BaseFs.PublishFs.Remove(publishedImageFilename))
+	assertImageFile(c, image.spec.BaseFs.PublishFs, publishedImageFilename, 101, 101)
+	c.Assert(image.spec.BaseFs.PublishFs.Remove(publishedImageFilename), qt.IsNil)
 
 	// Cleare mem cache to simulate reading from the file cache.
 	resized.spec.imageCache.clear()
 
 	resizedAgain, err := image.Resize("101x101")
-	assert.NoError(err)
-	assert.Equal("/a/sub/gohugoio2_hu0e1b9e4a4be4d6f86c7b37b9ccce3fbc_73886_101x101_resize_linear_2.png", resizedAgain.RelPermalink())
-	assert.Equal(101, resizedAgain.Width())
-	assertFileCache(assert, fileCache, resizedAgain.RelPermalink(), 101, 101)
-	assertImageFile(assert, image.spec.BaseFs.PublishFs, publishedImageFilename, 101, 101)
+	c.Assert(err, qt.IsNil)
+	c.Assert(resizedAgain.RelPermalink(), qt.Equals, "/a/sub/gohugoio2_hu0e1b9e4a4be4d6f86c7b37b9ccce3fbc_73886_101x101_resize_linear_2.png")
+	c.Assert(resizedAgain.Width(), qt.Equals, 101)
+	assertFileCache(c, fileCache, resizedAgain.RelPermalink(), 101, 101)
+	assertImageFile(c, image.spec.BaseFs.PublishFs, publishedImageFilename, 101, 101)
 
 }
 
 func TestSVGImage(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
-	svg := fetchResourceForSpec(spec, assert, "circle.svg")
-	assert.NotNil(svg)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
+	svg := fetchResourceForSpec(spec, c, "circle.svg")
+	c.Assert(svg, qt.Not(qt.IsNil))
 }
 
 func TestSVGImageContent(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
-	svg := fetchResourceForSpec(spec, assert, "circle.svg")
-	assert.NotNil(svg)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
+	svg := fetchResourceForSpec(spec, c, "circle.svg")
+	c.Assert(svg, qt.Not(qt.IsNil))
 
 	content, err := svg.Content()
-	assert.NoError(err)
-	assert.IsType("", content)
-	assert.Contains(content.(string), `<svg height="100" width="100">`)
+	c.Assert(err, qt.IsNil)
+	c.Assert(content, hqt.IsSameType, "")
+	c.Assert(content.(string), qt.Contains, `<svg height="100" width="100">`)
 }
 
 func BenchmarkResizeParallel(b *testing.B) {
-	assert := require.New(b)
-	img := fetchSunset(assert)
+	c := qt.New(b)
+	img := fetchSunset(c)
 
 	b.RunParallel(func(pb *testing.PB) {
 		for pb.Next() {
--- a/resources/page/page_data_test.go
+++ b/resources/page/page_data_test.go
@@ -19,15 +19,15 @@
 
 	"text/template"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestPageData(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	data := make(Data)
 
-	assert.Nil(data.Pages())
+	c.Assert(data.Pages(), qt.IsNil)
 
 	pages := Pages{
 		&testPage{title: "a1"},
@@ -36,22 +36,22 @@
 
 	data["pages"] = pages
 
-	assert.Equal(pages, data.Pages())
+	c.Assert(data.Pages(), eq, pages)
 
 	data["pages"] = func() Pages {
 		return pages
 	}
 
-	assert.Equal(pages, data.Pages())
+	c.Assert(data.Pages(), eq, pages)
 
 	templ, err := template.New("").Parse(`Pages: {{ .Pages }}`)
 
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	var buff bytes.Buffer
 
-	assert.NoError(templ.Execute(&buff, data))
+	c.Assert(templ.Execute(&buff, data), qt.IsNil)
 
-	assert.Contains(buff.String(), "Pages(2)")
+	c.Assert(buff.String(), qt.Contains, "Pages(2)")
 
 }
--- a/resources/page/page_kinds_test.go
+++ b/resources/page/page_kinds_test.go
@@ -16,22 +16,23 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestKind(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	// Add tests for these constants to make sure they don't change
-	require.Equal(t, "page", KindPage)
-	require.Equal(t, "home", KindHome)
-	require.Equal(t, "section", KindSection)
-	require.Equal(t, "taxonomy", KindTaxonomy)
-	require.Equal(t, "taxonomyTerm", KindTaxonomyTerm)
+	c.Assert(KindPage, qt.Equals, "page")
+	c.Assert(KindHome, qt.Equals, "home")
+	c.Assert(KindSection, qt.Equals, "section")
+	c.Assert(KindTaxonomy, qt.Equals, "taxonomy")
+	c.Assert(KindTaxonomyTerm, qt.Equals, "taxonomyTerm")
 
-	require.Equal(t, KindTaxonomyTerm, GetKind("TAXONOMYTERM"))
-	require.Equal(t, KindTaxonomy, GetKind("Taxonomy"))
-	require.Equal(t, KindPage, GetKind("Page"))
-	require.Equal(t, KindHome, GetKind("Home"))
-	require.Equal(t, KindSection, GetKind("SEction"))
+	c.Assert(GetKind("TAXONOMYTERM"), qt.Equals, KindTaxonomyTerm)
+	c.Assert(GetKind("Taxonomy"), qt.Equals, KindTaxonomy)
+	c.Assert(GetKind("Page"), qt.Equals, KindPage)
+	c.Assert(GetKind("Home"), qt.Equals, KindHome)
+	c.Assert(GetKind("SEction"), qt.Equals, KindSection)
 
 }
--- a/resources/page/pagegroup_test.go
+++ b/resources/page/pagegroup_test.go
@@ -18,8 +18,8 @@
 	"strings"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/cast"
-	"github.com/stretchr/testify/require"
 )
 
 type pageGroupTestObject struct {
@@ -204,7 +204,7 @@
 }
 
 func TestGroupByParamCalledWithCapitalLetterString(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	testStr := "TestString"
 	p := newTestPage()
 	p.params["custom_param"] = testStr
@@ -212,8 +212,8 @@
 
 	groups, err := pages.GroupByParam("custom_param")
 
-	assert.NoError(err)
-	assert.Equal(testStr, groups[0].Key)
+	c.Assert(err, qt.IsNil)
+	c.Assert(groups[0].Key, qt.Equals, testStr)
 
 }
 
--- a/resources/page/pagemeta/page_frontmatter_test.go
+++ b/resources/page/pagemeta/page_frontmatter_test.go
@@ -14,7 +14,6 @@
 package pagemeta
 
 import (
-	"fmt"
 	"strings"
 	"testing"
 	"time"
@@ -22,7 +21,7 @@
 	"github.com/gohugoio/hugo/resources/resource"
 	"github.com/spf13/viper"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestDateAndSlugFromBaseFilename(t *testing.T) {
@@ -29,7 +28,7 @@
 
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tests := []struct {
 		name string
@@ -50,15 +49,14 @@
 		{"asdfasdf.md", "0001-01-01", ""},
 	}
 
-	for i, test := range tests {
+	for _, test := range tests {
 		expecteFDate, err := time.Parse("2006-01-02", test.date)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
-		errMsg := fmt.Sprintf("Test %d", i)
 		gotDate, gotSlug := dateAndSlugFromBaseFilename(test.name)
 
-		assert.Equal(expecteFDate, gotDate, errMsg)
-		assert.Equal(test.slug, gotSlug, errMsg)
+		c.Assert(gotDate, qt.Equals, expecteFDate)
+		c.Assert(gotSlug, qt.Equals, test.slug)
 
 	}
 }
@@ -73,7 +71,7 @@
 }
 
 func TestFrontMatterNewConfig(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	cfg := viper.New()
 
@@ -85,20 +83,20 @@
 	})
 
 	fc, err := newFrontmatterConfig(cfg)
-	assert.NoError(err)
-	assert.Equal([]string{"publishdate", "pubdate", "published", "lastmod", "modified"}, fc.date)
-	assert.Equal([]string{"publishdate", "pubdate", "published"}, fc.lastmod)
-	assert.Equal([]string{"lastmod", "modified"}, fc.expiryDate)
-	assert.Equal([]string{"date"}, fc.publishDate)
+	c.Assert(err, qt.IsNil)
+	c.Assert(fc.date, qt.DeepEquals, []string{"publishdate", "pubdate", "published", "lastmod", "modified"})
+	c.Assert(fc.lastmod, qt.DeepEquals, []string{"publishdate", "pubdate", "published"})
+	c.Assert(fc.expiryDate, qt.DeepEquals, []string{"lastmod", "modified"})
+	c.Assert(fc.publishDate, qt.DeepEquals, []string{"date"})
 
 	// Default
 	cfg = viper.New()
 	fc, err = newFrontmatterConfig(cfg)
-	assert.NoError(err)
-	assert.Equal([]string{"date", "publishdate", "pubdate", "published", "lastmod", "modified"}, fc.date)
-	assert.Equal([]string{":git", "lastmod", "modified", "date", "publishdate", "pubdate", "published"}, fc.lastmod)
-	assert.Equal([]string{"expirydate", "unpublishdate"}, fc.expiryDate)
-	assert.Equal([]string{"publishdate", "pubdate", "published", "date"}, fc.publishDate)
+	c.Assert(err, qt.IsNil)
+	c.Assert(fc.date, qt.DeepEquals, []string{"date", "publishdate", "pubdate", "published", "lastmod", "modified"})
+	c.Assert(fc.lastmod, qt.DeepEquals, []string{":git", "lastmod", "modified", "date", "publishdate", "pubdate", "published"})
+	c.Assert(fc.expiryDate, qt.DeepEquals, []string{"expirydate", "unpublishdate"})
+	c.Assert(fc.publishDate, qt.DeepEquals, []string{"publishdate", "pubdate", "published", "date"})
 
 	// :default keyword
 	cfg.Set("frontmatter", map[string]interface{}{
@@ -108,16 +106,16 @@
 		"publishDate": []string{"d4", ":default"},
 	})
 	fc, err = newFrontmatterConfig(cfg)
-	assert.NoError(err)
-	assert.Equal([]string{"d1", "date", "publishdate", "pubdate", "published", "lastmod", "modified"}, fc.date)
-	assert.Equal([]string{"d2", ":git", "lastmod", "modified", "date", "publishdate", "pubdate", "published"}, fc.lastmod)
-	assert.Equal([]string{"d3", "expirydate", "unpublishdate"}, fc.expiryDate)
-	assert.Equal([]string{"d4", "publishdate", "pubdate", "published", "date"}, fc.publishDate)
+	c.Assert(err, qt.IsNil)
+	c.Assert(fc.date, qt.DeepEquals, []string{"d1", "date", "publishdate", "pubdate", "published", "lastmod", "modified"})
+	c.Assert(fc.lastmod, qt.DeepEquals, []string{"d2", ":git", "lastmod", "modified", "date", "publishdate", "pubdate", "published"})
+	c.Assert(fc.expiryDate, qt.DeepEquals, []string{"d3", "expirydate", "unpublishdate"})
+	c.Assert(fc.publishDate, qt.DeepEquals, []string{"d4", "publishdate", "pubdate", "published", "date"})
 
 }
 
 func TestFrontMatterDatesHandlers(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	for _, handlerID := range []string{":filename", ":fileModTime", ":git"} {
 
@@ -128,7 +126,7 @@
 		})
 
 		handler, err := NewFrontmatterHandler(nil, cfg)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		d1, _ := time.Parse("2006-01-02", "2018-02-01")
 		d2, _ := time.Parse("2006-01-02", "2018-02-02")
@@ -143,15 +141,15 @@
 			d.GitAuthorDate = d1
 		}
 		d.Frontmatter["date"] = d2
-		assert.NoError(handler.HandleDates(d))
-		assert.Equal(d1, d.Dates.FDate)
-		assert.Equal(d2, d.Params["date"])
+		c.Assert(handler.HandleDates(d), qt.IsNil)
+		c.Assert(d.Dates.FDate, qt.Equals, d1)
+		c.Assert(d.Params["date"], qt.Equals, d2)
 
 		d = newTestFd()
 		d.Frontmatter["date"] = d2
-		assert.NoError(handler.HandleDates(d))
-		assert.Equal(d2, d.Dates.FDate)
-		assert.Equal(d2, d.Params["date"])
+		c.Assert(handler.HandleDates(d), qt.IsNil)
+		c.Assert(d.Dates.FDate, qt.Equals, d2)
+		c.Assert(d.Params["date"], qt.Equals, d2)
 
 	}
 }
@@ -159,7 +157,7 @@
 func TestFrontMatterDatesCustomConfig(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	cfg := viper.New()
 	cfg.Set("frontmatter", map[string]interface{}{
@@ -169,10 +167,10 @@
 	})
 
 	handler, err := NewFrontmatterHandler(nil, cfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	testDate, err := time.Parse("2006-01-02", "2018-02-01")
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	d := newTestFd()
 	d.Frontmatter["mydate"] = testDate
@@ -185,22 +183,22 @@
 	testDate = testDate.Add(24 * time.Hour)
 	d.Frontmatter["expirydate"] = testDate
 
-	assert.NoError(handler.HandleDates(d))
+	c.Assert(handler.HandleDates(d), qt.IsNil)
 
-	assert.Equal(1, d.Dates.FDate.Day())
-	assert.Equal(4, d.Dates.FLastmod.Day())
-	assert.Equal(4, d.Dates.FPublishDate.Day())
-	assert.Equal(5, d.Dates.FExpiryDate.Day())
+	c.Assert(d.Dates.FDate.Day(), qt.Equals, 1)
+	c.Assert(d.Dates.FLastmod.Day(), qt.Equals, 4)
+	c.Assert(d.Dates.FPublishDate.Day(), qt.Equals, 4)
+	c.Assert(d.Dates.FExpiryDate.Day(), qt.Equals, 5)
 
-	assert.Equal(d.Dates.FDate, d.Params["date"])
-	assert.Equal(d.Dates.FDate, d.Params["mydate"])
-	assert.Equal(d.Dates.FPublishDate, d.Params["publishdate"])
-	assert.Equal(d.Dates.FExpiryDate, d.Params["expirydate"])
+	c.Assert(d.Params["date"], qt.Equals, d.Dates.FDate)
+	c.Assert(d.Params["mydate"], qt.Equals, d.Dates.FDate)
+	c.Assert(d.Params["publishdate"], qt.Equals, d.Dates.FPublishDate)
+	c.Assert(d.Params["expirydate"], qt.Equals, d.Dates.FExpiryDate)
 
-	assert.False(handler.IsDateKey("date")) // This looks odd, but is configured like this.
-	assert.True(handler.IsDateKey("mydate"))
-	assert.True(handler.IsDateKey("publishdate"))
-	assert.True(handler.IsDateKey("pubdate"))
+	c.Assert(handler.IsDateKey("date"), qt.Equals, false) // This looks odd, but is configured like this.
+	c.Assert(handler.IsDateKey("mydate"), qt.Equals, true)
+	c.Assert(handler.IsDateKey("publishdate"), qt.Equals, true)
+	c.Assert(handler.IsDateKey("pubdate"), qt.Equals, true)
 
 }
 
@@ -207,7 +205,7 @@
 func TestFrontMatterDatesDefaultKeyword(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	cfg := viper.New()
 
@@ -217,7 +215,7 @@
 	})
 
 	handler, err := NewFrontmatterHandler(nil, cfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	testDate, _ := time.Parse("2006-01-02", "2018-02-01")
 	d := newTestFd()
@@ -226,20 +224,20 @@
 	d.Frontmatter["mypubdate"] = testDate.Add(2 * 24 * time.Hour)
 	d.Frontmatter["publishdate"] = testDate.Add(3 * 24 * time.Hour)
 
-	assert.NoError(handler.HandleDates(d))
+	c.Assert(handler.HandleDates(d), qt.IsNil)
 
-	assert.Equal(1, d.Dates.FDate.Day())
-	assert.Equal(2, d.Dates.FLastmod.Day())
-	assert.Equal(4, d.Dates.FPublishDate.Day())
-	assert.True(d.Dates.FExpiryDate.IsZero())
+	c.Assert(d.Dates.FDate.Day(), qt.Equals, 1)
+	c.Assert(d.Dates.FLastmod.Day(), qt.Equals, 2)
+	c.Assert(d.Dates.FPublishDate.Day(), qt.Equals, 4)
+	c.Assert(d.Dates.FExpiryDate.IsZero(), qt.Equals, true)
 
 }
 
 func TestExpandDefaultValues(t *testing.T) {
-	assert := require.New(t)
-	assert.Equal([]string{"a", "b", "c", "d"}, expandDefaultValues([]string{"a", ":default", "d"}, []string{"b", "c"}))
-	assert.Equal([]string{"a", "b", "c"}, expandDefaultValues([]string{"a", "b", "c"}, []string{"a", "b", "c"}))
-	assert.Equal([]string{"b", "c", "a", "b", "c", "d"}, expandDefaultValues([]string{":default", "a", ":default", "d"}, []string{"b", "c"}))
+	c := qt.New(t)
+	c.Assert(expandDefaultValues([]string{"a", ":default", "d"}, []string{"b", "c"}), qt.DeepEquals, []string{"a", "b", "c", "d"})
+	c.Assert(expandDefaultValues([]string{"a", "b", "c"}, []string{"a", "b", "c"}), qt.DeepEquals, []string{"a", "b", "c"})
+	c.Assert(expandDefaultValues([]string{":default", "a", ":default", "d"}, []string{"b", "c"}), qt.DeepEquals, []string{"b", "c", "a", "b", "c", "d"})
 
 }
 
@@ -246,7 +244,7 @@
 func TestFrontMatterDateFieldHandler(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	handlers := new(frontmatterFieldHandlers)
 
@@ -256,7 +254,7 @@
 	h := handlers.newDateFieldHandler("date", func(d *FrontMatterDescriptor, t time.Time) { d.Dates.FDate = t })
 
 	handled, err := h(fd)
-	assert.True(handled)
-	assert.NoError(err)
-	assert.Equal(d, fd.Dates.FDate)
+	c.Assert(handled, qt.Equals, true)
+	c.Assert(err, qt.IsNil)
+	c.Assert(fd.Dates.FDate, qt.Equals, d)
 }
--- a/resources/page/pages_cache_test.go
+++ b/resources/page/pages_cache_test.go
@@ -19,11 +19,12 @@
 	"sync/atomic"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestPageCache(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	c1 := newPageCache()
 
 	changeFirst := func(p Pages) {
@@ -50,21 +51,21 @@
 			defer wg.Done()
 			for k, pages := range testPageSets {
 				l1.Lock()
-				p, c := c1.get("k1", nil, pages)
-				assert.Equal(t, !atomic.CompareAndSwapUint64(&o1, uint64(k), uint64(k+1)), c)
+				p, ca := c1.get("k1", nil, pages)
+				c.Assert(ca, qt.Equals, !atomic.CompareAndSwapUint64(&o1, uint64(k), uint64(k+1)))
 				l1.Unlock()
 				p2, c2 := c1.get("k1", nil, p)
-				assert.True(t, c2)
-				assert.True(t, pagesEqual(p, p2))
-				assert.True(t, pagesEqual(p, pages))
-				assert.NotNil(t, p)
+				c.Assert(c2, qt.Equals, true)
+				c.Assert(pagesEqual(p, p2), qt.Equals, true)
+				c.Assert(pagesEqual(p, pages), qt.Equals, true)
+				c.Assert(p, qt.Not(qt.IsNil))
 
 				l2.Lock()
 				p3, c3 := c1.get("k2", changeFirst, pages)
-				assert.Equal(t, !atomic.CompareAndSwapUint64(&o2, uint64(k), uint64(k+1)), c3)
+				c.Assert(c3, qt.Equals, !atomic.CompareAndSwapUint64(&o2, uint64(k), uint64(k+1)))
 				l2.Unlock()
-				assert.NotNil(t, p3)
-				assert.Equal(t, p3[0].(*testPage).description, "changed")
+				c.Assert(p3, qt.Not(qt.IsNil))
+				c.Assert("changed", qt.Equals, p3[0].(*testPage).description)
 			}
 		}()
 	}
--- a/resources/page/pages_prev_next_test.go
+++ b/resources/page/pages_prev_next_test.go
@@ -16,8 +16,8 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/spf13/cast"
-	"github.com/stretchr/testify/assert"
 )
 
 type pagePNTestObject struct {
@@ -36,18 +36,20 @@
 
 func TestPrev(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	pages := preparePageGroupTestPages(t)
-	assert.Equal(t, pages.Prev(pages[0]), pages[4])
-	assert.Equal(t, pages.Prev(pages[1]), pages[0])
-	assert.Equal(t, pages.Prev(pages[4]), pages[3])
+	c.Assert(pages[4], qt.Equals, pages.Prev(pages[0]))
+	c.Assert(pages[0], qt.Equals, pages.Prev(pages[1]))
+	c.Assert(pages[3], qt.Equals, pages.Prev(pages[4]))
 }
 
 func TestNext(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	pages := preparePageGroupTestPages(t)
-	assert.Equal(t, pages.Next(pages[0]), pages[1])
-	assert.Equal(t, pages.Next(pages[1]), pages[2])
-	assert.Equal(t, pages.Next(pages[4]), pages[0])
+	c.Assert(pages[1], qt.Equals, pages.Next(pages[0]))
+	c.Assert(pages[2], qt.Equals, pages.Next(pages[1]))
+	c.Assert(pages[0], qt.Equals, pages.Next(pages[4]))
 }
 
 func prepareWeightedPagesPrevNext(t *testing.T) WeightedPages {
@@ -68,16 +70,18 @@
 
 func TestWeightedPagesPrev(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	w := prepareWeightedPagesPrevNext(t)
-	assert.Equal(t, w.Prev(w[0].Page), w[4].Page)
-	assert.Equal(t, w.Prev(w[1].Page), w[0].Page)
-	assert.Equal(t, w.Prev(w[4].Page), w[3].Page)
+	c.Assert(w[4].Page, qt.Equals, w.Prev(w[0].Page))
+	c.Assert(w[0].Page, qt.Equals, w.Prev(w[1].Page))
+	c.Assert(w[3].Page, qt.Equals, w.Prev(w[4].Page))
 }
 
 func TestWeightedPagesNext(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	w := prepareWeightedPagesPrevNext(t)
-	assert.Equal(t, w.Next(w[0].Page), w[1].Page)
-	assert.Equal(t, w.Next(w[1].Page), w[2].Page)
-	assert.Equal(t, w.Next(w[4].Page), w[0].Page)
+	c.Assert(w[1].Page, qt.Equals, w.Next(w[0].Page))
+	c.Assert(w[2].Page, qt.Equals, w.Next(w[1].Page))
+	c.Assert(w[0].Page, qt.Equals, w.Next(w[4].Page))
 }
--- a/resources/page/pages_related_test.go
+++ b/resources/page/pages_related_test.go
@@ -19,11 +19,11 @@
 
 	"github.com/gohugoio/hugo/common/types"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestRelated(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	t.Parallel()
 
@@ -53,28 +53,28 @@
 
 	result, err := pages.RelatedTo(types.NewKeyValuesStrings("keywords", "hugo", "rocks"))
 
-	assert.NoError(err)
-	assert.Len(result, 2)
-	assert.Equal("Page 2", result[0].Title())
-	assert.Equal("Page 1", result[1].Title())
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(result), qt.Equals, 2)
+	c.Assert(result[0].Title(), qt.Equals, "Page 2")
+	c.Assert(result[1].Title(), qt.Equals, "Page 1")
 
 	result, err = pages.Related(pages[0])
-	assert.NoError(err)
-	assert.Len(result, 2)
-	assert.Equal("Page 2", result[0].Title())
-	assert.Equal("Page 3", result[1].Title())
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(result), qt.Equals, 2)
+	c.Assert(result[0].Title(), qt.Equals, "Page 2")
+	c.Assert(result[1].Title(), qt.Equals, "Page 3")
 
 	result, err = pages.RelatedIndices(pages[0], "keywords")
-	assert.NoError(err)
-	assert.Len(result, 2)
-	assert.Equal("Page 2", result[0].Title())
-	assert.Equal("Page 3", result[1].Title())
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(result), qt.Equals, 2)
+	c.Assert(result[0].Title(), qt.Equals, "Page 2")
+	c.Assert(result[1].Title(), qt.Equals, "Page 3")
 
 	result, err = pages.RelatedTo(types.NewKeyValuesStrings("keywords", "bep", "rocks"))
-	assert.NoError(err)
-	assert.Len(result, 2)
-	assert.Equal("Page 2", result[0].Title())
-	assert.Equal("Page 3", result[1].Title())
+	c.Assert(err, qt.IsNil)
+	c.Assert(len(result), qt.Equals, 2)
+	c.Assert(result[0].Title(), qt.Equals, "Page 2")
+	c.Assert(result[1].Title(), qt.Equals, "Page 3")
 }
 
 func mustParseDate(s string) time.Time {
--- a/resources/page/pages_sort_test.go
+++ b/resources/page/pages_sort_test.go
@@ -18,14 +18,22 @@
 	"testing"
 	"time"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+	"github.com/gohugoio/hugo/source"
+
 	"github.com/gohugoio/hugo/resources/resource"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
+var eq = qt.CmpEquals(hqt.DeepAllowUnexported(
+	&testPage{},
+	&source.FileInfo{},
+))
+
 func TestDefaultSort(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	d1 := time.Now()
 	d2 := d1.Add(-1 * time.Hour)
 	d3 := d1.Add(-2 * time.Hour)
@@ -37,31 +45,31 @@
 	setSortVals([4]time.Time{d1, d2, d3, d4}, [4]string{"b", "a", "c", "d"}, [4]int{4, 3, 2, 1}, p)
 	SortByDefault(p)
 
-	assert.Equal(t, 1, p[0].Weight())
+	c.Assert(p[0].Weight(), qt.Equals, 1)
 
 	// Consider zero weight, issue #2673
 	setSortVals([4]time.Time{d1, d2, d3, d4}, [4]string{"b", "a", "d", "c"}, [4]int{0, 0, 0, 1}, p)
 	SortByDefault(p)
 
-	assert.Equal(t, 1, p[0].Weight())
+	c.Assert(p[0].Weight(), qt.Equals, 1)
 
 	// next by date
 	setSortVals([4]time.Time{d3, d4, d1, d2}, [4]string{"a", "b", "c", "d"}, [4]int{1, 1, 1, 1}, p)
 	SortByDefault(p)
-	assert.Equal(t, d1, p[0].Date())
+	c.Assert(p[0].Date(), qt.Equals, d1)
 
 	// finally by link title
 	setSortVals([4]time.Time{d3, d3, d3, d3}, [4]string{"b", "c", "a", "d"}, [4]int{1, 1, 1, 1}, p)
 	SortByDefault(p)
-	assert.Equal(t, "al", p[0].LinkTitle())
-	assert.Equal(t, "bl", p[1].LinkTitle())
-	assert.Equal(t, "cl", p[2].LinkTitle())
+	c.Assert(p[0].LinkTitle(), qt.Equals, "al")
+	c.Assert(p[1].LinkTitle(), qt.Equals, "bl")
+	c.Assert(p[2].LinkTitle(), qt.Equals, "cl")
 }
 
 // https://github.com/gohugoio/hugo/issues/4953
 func TestSortByLinkTitle(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 	pages := createSortTestPages(6)
 
 	for i, p := range pages {
@@ -81,11 +89,10 @@
 	bylt := pages.ByLinkTitle()
 
 	for i, p := range bylt {
-		msg := fmt.Sprintf("test: %d", i)
 		if i < 3 {
-			assert.Equal(fmt.Sprintf("linkTitle%d", i+3), p.LinkTitle(), msg)
+			c.Assert(p.LinkTitle(), qt.Equals, fmt.Sprintf("linkTitle%d", i+3))
 		} else {
-			assert.Equal(fmt.Sprintf("title%d", i-3), p.LinkTitle(), msg)
+			c.Assert(p.LinkTitle(), qt.Equals, fmt.Sprintf("title%d", i-3))
 		}
 	}
 }
@@ -124,30 +131,33 @@
 
 func TestLimit(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	p := createSortTestPages(10)
 	firstFive := p.Limit(5)
-	assert.Equal(t, 5, len(firstFive))
+	c.Assert(len(firstFive), qt.Equals, 5)
 	for i := 0; i < 5; i++ {
-		assert.Equal(t, p[i], firstFive[i])
+		c.Assert(firstFive[i], qt.Equals, p[i])
 	}
-	assert.Equal(t, p, p.Limit(10))
-	assert.Equal(t, p, p.Limit(11))
+	c.Assert(p.Limit(10), eq, p)
+	c.Assert(p.Limit(11), eq, p)
 }
 
 func TestPageSortReverse(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	p1 := createSortTestPages(10)
-	assert.Equal(t, 0, p1[0].(*testPage).fuzzyWordCount)
-	assert.Equal(t, 9, p1[9].(*testPage).fuzzyWordCount)
+	c.Assert(p1[0].(*testPage).fuzzyWordCount, qt.Equals, 0)
+	c.Assert(p1[9].(*testPage).fuzzyWordCount, qt.Equals, 9)
 	p2 := p1.Reverse()
-	assert.Equal(t, 9, p2[0].(*testPage).fuzzyWordCount)
-	assert.Equal(t, 0, p2[9].(*testPage).fuzzyWordCount)
+	c.Assert(p2[0].(*testPage).fuzzyWordCount, qt.Equals, 9)
+	c.Assert(p2[9].(*testPage).fuzzyWordCount, qt.Equals, 0)
 	// cached
-	assert.True(t, pagesEqual(p2, p1.Reverse()))
+	c.Assert(pagesEqual(p2, p1.Reverse()), qt.Equals, true)
 }
 
 func TestPageSortByParam(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	var k interface{} = "arbitrarily.nested"
 
 	unsorted := createSortTestPages(10)
@@ -158,10 +168,10 @@
 	lastSetValue, _ := unsorted[8].Param(k)
 	unsetValue, _ := unsorted[9].Param(k)
 
-	assert.Equal(t, "xyz100", firstSetValue)
-	assert.Equal(t, "xyz99", secondSetValue)
-	assert.Equal(t, "xyz92", lastSetValue)
-	assert.Equal(t, nil, unsetValue)
+	c.Assert(firstSetValue, qt.Equals, "xyz100")
+	c.Assert(secondSetValue, qt.Equals, "xyz99")
+	c.Assert(lastSetValue, qt.Equals, "xyz92")
+	c.Assert(unsetValue, qt.Equals, nil)
 
 	sorted := unsorted.ByParam("arbitrarily.nested")
 	firstSetSortedValue, _ := sorted[0].Param(k)
@@ -169,14 +179,16 @@
 	lastSetSortedValue, _ := sorted[8].Param(k)
 	unsetSortedValue, _ := sorted[9].Param(k)
 
-	assert.Equal(t, firstSetValue, firstSetSortedValue)
-	assert.Equal(t, secondSetValue, lastSetSortedValue)
-	assert.Equal(t, lastSetValue, secondSetSortedValue)
-	assert.Equal(t, unsetValue, unsetSortedValue)
+	c.Assert(firstSetSortedValue, qt.Equals, firstSetValue)
+	c.Assert(lastSetSortedValue, qt.Equals, secondSetValue)
+	c.Assert(secondSetSortedValue, qt.Equals, lastSetValue)
+	c.Assert(unsetSortedValue, qt.Equals, unsetValue)
 }
 
 func TestPageSortByParamNumeric(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
+
 	var k interface{} = "arbitrarily.nested"
 
 	n := 10
@@ -200,10 +212,10 @@
 	lastSetValue, _ := unsorted[8].Param(k)
 	unsetValue, _ := unsorted[9].Param(k)
 
-	assert.Equal(t, 100, firstSetValue)
-	assert.Equal(t, 99, secondSetValue)
-	assert.Equal(t, 92, lastSetValue)
-	assert.Equal(t, nil, unsetValue)
+	c.Assert(firstSetValue, qt.Equals, 100)
+	c.Assert(secondSetValue, qt.Equals, 99)
+	c.Assert(lastSetValue, qt.Equals, 92)
+	c.Assert(unsetValue, qt.Equals, nil)
 
 	sorted := unsorted.ByParam("arbitrarily.nested")
 	firstSetSortedValue, _ := sorted[0].Param(k)
@@ -211,10 +223,10 @@
 	lastSetSortedValue, _ := sorted[8].Param(k)
 	unsetSortedValue, _ := sorted[9].Param(k)
 
-	assert.Equal(t, 92, firstSetSortedValue)
-	assert.Equal(t, 93, secondSetSortedValue)
-	assert.Equal(t, 100, lastSetSortedValue)
-	assert.Equal(t, unsetValue, unsetSortedValue)
+	c.Assert(firstSetSortedValue, qt.Equals, 92)
+	c.Assert(secondSetSortedValue, qt.Equals, 93)
+	c.Assert(lastSetSortedValue, qt.Equals, 100)
+	c.Assert(unsetSortedValue, qt.Equals, unsetValue)
 }
 
 func BenchmarkSortByWeightAndReverse(b *testing.B) {
--- a/resources/page/pages_test.go
+++ b/resources/page/pages_test.go
@@ -16,7 +16,7 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestProbablyEq(t *testing.T) {
@@ -27,28 +27,28 @@
 	pages123 := Pages{p1, p2, p3}
 
 	t.Run("Pages", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
-		assert.True(pages12.ProbablyEq(pages12))
-		assert.False(pages123.ProbablyEq(pages12))
-		assert.False(pages12.ProbablyEq(pages21))
+		c.Assert(pages12.ProbablyEq(pages12), qt.Equals, true)
+		c.Assert(pages123.ProbablyEq(pages12), qt.Equals, false)
+		c.Assert(pages12.ProbablyEq(pages21), qt.Equals, false)
 	})
 
 	t.Run("PageGroup", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
-		assert.True(PageGroup{Key: "a", Pages: pages12}.ProbablyEq(PageGroup{Key: "a", Pages: pages12}))
-		assert.False(PageGroup{Key: "a", Pages: pages12}.ProbablyEq(PageGroup{Key: "b", Pages: pages12}))
+		c.Assert(PageGroup{Key: "a", Pages: pages12}.ProbablyEq(PageGroup{Key: "a", Pages: pages12}), qt.Equals, true)
+		c.Assert(PageGroup{Key: "a", Pages: pages12}.ProbablyEq(PageGroup{Key: "b", Pages: pages12}), qt.Equals, false)
 
 	})
 
 	t.Run("PagesGroup", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
 		pg1, pg2 := PageGroup{Key: "a", Pages: pages12}, PageGroup{Key: "b", Pages: pages123}
 
-		assert.True(PagesGroup{pg1, pg2}.ProbablyEq(PagesGroup{pg1, pg2}))
-		assert.False(PagesGroup{pg1, pg2}.ProbablyEq(PagesGroup{pg2, pg1}))
+		c.Assert(PagesGroup{pg1, pg2}.ProbablyEq(PagesGroup{pg1, pg2}), qt.Equals, true)
+		c.Assert(PagesGroup{pg1, pg2}.ProbablyEq(PagesGroup{pg2, pg1}), qt.Equals, false)
 
 	})
 
@@ -55,7 +55,7 @@
 }
 
 func TestToPages(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	p1, p2 := &testPage{title: "p1"}, &testPage{title: "p2"}
 	pages12 := Pages{p1, p2}
@@ -62,15 +62,15 @@
 
 	mustToPages := func(in interface{}) Pages {
 		p, err := ToPages(in)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		return p
 	}
 
-	assert.Equal(Pages{}, mustToPages(nil))
-	assert.Equal(pages12, mustToPages(pages12))
-	assert.Equal(pages12, mustToPages([]Page{p1, p2}))
-	assert.Equal(pages12, mustToPages([]interface{}{p1, p2}))
+	c.Assert(mustToPages(nil), eq, Pages{})
+	c.Assert(mustToPages(pages12), eq, pages12)
+	c.Assert(mustToPages([]Page{p1, p2}), eq, pages12)
+	c.Assert(mustToPages([]interface{}{p1, p2}), eq, pages12)
 
 	_, err := ToPages("not a page")
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 }
--- a/resources/page/pagination_test.go
+++ b/resources/page/pagination_test.go
@@ -20,43 +20,44 @@
 
 	"github.com/spf13/viper"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/output"
-	"github.com/stretchr/testify/require"
 )
 
 func TestSplitPages(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	pages := createTestPages(21)
 	chunks := splitPages(pages, 5)
-	require.Equal(t, 5, len(chunks))
+	c.Assert(len(chunks), qt.Equals, 5)
 
 	for i := 0; i < 4; i++ {
-		require.Equal(t, 5, chunks[i].Len())
+		c.Assert(chunks[i].Len(), qt.Equals, 5)
 	}
 
 	lastChunk := chunks[4]
-	require.Equal(t, 1, lastChunk.Len())
+	c.Assert(lastChunk.Len(), qt.Equals, 1)
 
 }
 
 func TestSplitPageGroups(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	pages := createTestPages(21)
 	groups, _ := pages.GroupBy("Weight", "desc")
 	chunks := splitPageGroups(groups, 5)
-	require.Equal(t, 5, len(chunks))
+	c.Assert(len(chunks), qt.Equals, 5)
 
 	firstChunk := chunks[0]
 
 	// alternate weight 5 and 10
 	if groups, ok := firstChunk.(PagesGroup); ok {
-		require.Equal(t, 5, groups.Len())
+		c.Assert(groups.Len(), qt.Equals, 5)
 		for _, pg := range groups {
 			// first group 10 in weight
-			require.Equal(t, 10, pg.Key)
+			c.Assert(pg.Key, qt.Equals, 10)
 			for _, p := range pg.Pages {
-				require.True(t, p.FuzzyWordCount()%2 == 0) // magic test
+				c.Assert(p.FuzzyWordCount()%2 == 0, qt.Equals, true) // magic test
 			}
 		}
 	} else {
@@ -66,12 +67,12 @@
 	lastChunk := chunks[4]
 
 	if groups, ok := lastChunk.(PagesGroup); ok {
-		require.Equal(t, 1, groups.Len())
+		c.Assert(groups.Len(), qt.Equals, 1)
 		for _, pg := range groups {
 			// last should have 5 in weight
-			require.Equal(t, 5, pg.Key)
+			c.Assert(pg.Key, qt.Equals, 5)
 			for _, p := range pg.Pages {
-				require.True(t, p.FuzzyWordCount()%2 != 0) // magic test
+				c.Assert(p.FuzzyWordCount()%2 != 0, qt.Equals, true) // magic test
 			}
 		}
 	} else {
@@ -82,6 +83,7 @@
 
 func TestPager(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	pages := createTestPages(21)
 	groups, _ := pages.GroupBy("Weight", "desc")
 
@@ -90,64 +92,65 @@
 	}
 
 	_, err := newPaginatorFromPages(pages, -1, urlFactory)
-	require.NotNil(t, err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	_, err = newPaginatorFromPageGroups(groups, -1, urlFactory)
-	require.NotNil(t, err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	pag, err := newPaginatorFromPages(pages, 5, urlFactory)
-	require.Nil(t, err)
+	c.Assert(err, qt.IsNil)
 	doTestPages(t, pag)
 	first := pag.Pagers()[0].First()
-	require.Equal(t, "Pager 1", first.String())
-	require.NotEmpty(t, first.Pages())
-	require.Empty(t, first.PageGroups())
+	c.Assert(first.String(), qt.Equals, "Pager 1")
+	c.Assert(first.Pages(), qt.Not(qt.HasLen), 0)
+	c.Assert(first.PageGroups(), qt.HasLen, 0)
 
 	pag, err = newPaginatorFromPageGroups(groups, 5, urlFactory)
-	require.Nil(t, err)
+	c.Assert(err, qt.IsNil)
 	doTestPages(t, pag)
 	first = pag.Pagers()[0].First()
-	require.NotEmpty(t, first.PageGroups())
-	require.Empty(t, first.Pages())
+	c.Assert(first.PageGroups(), qt.Not(qt.HasLen), 0)
+	c.Assert(first.Pages(), qt.HasLen, 0)
 
 }
 
 func doTestPages(t *testing.T, paginator *Paginator) {
-
+	c := qt.New(t)
 	paginatorPages := paginator.Pagers()
 
-	require.Equal(t, 5, len(paginatorPages))
-	require.Equal(t, 21, paginator.TotalNumberOfElements())
-	require.Equal(t, 5, paginator.PageSize())
-	require.Equal(t, 5, paginator.TotalPages())
+	c.Assert(len(paginatorPages), qt.Equals, 5)
+	c.Assert(paginator.TotalNumberOfElements(), qt.Equals, 21)
+	c.Assert(paginator.PageSize(), qt.Equals, 5)
+	c.Assert(paginator.TotalPages(), qt.Equals, 5)
 
 	first := paginatorPages[0]
-	require.Equal(t, template.HTML("page/1/"), first.URL())
-	require.Equal(t, first, first.First())
-	require.True(t, first.HasNext())
-	require.Equal(t, paginatorPages[1], first.Next())
-	require.False(t, first.HasPrev())
-	require.Nil(t, first.Prev())
-	require.Equal(t, 5, first.NumberOfElements())
-	require.Equal(t, 1, first.PageNumber())
+	c.Assert(first.URL(), qt.Equals, template.HTML("page/1/"))
+	c.Assert(first.First(), qt.Equals, first)
+	c.Assert(first.HasNext(), qt.Equals, true)
+	c.Assert(first.Next(), qt.Equals, paginatorPages[1])
+	c.Assert(first.HasPrev(), qt.Equals, false)
+	c.Assert(first.Prev(), qt.IsNil)
+	c.Assert(first.NumberOfElements(), qt.Equals, 5)
+	c.Assert(first.PageNumber(), qt.Equals, 1)
 
 	third := paginatorPages[2]
-	require.True(t, third.HasNext())
-	require.True(t, third.HasPrev())
-	require.Equal(t, paginatorPages[1], third.Prev())
+	c.Assert(third.HasNext(), qt.Equals, true)
+	c.Assert(third.HasPrev(), qt.Equals, true)
+	c.Assert(third.Prev(), qt.Equals, paginatorPages[1])
 
 	last := paginatorPages[4]
-	require.Equal(t, template.HTML("page/5/"), last.URL())
-	require.Equal(t, last, last.Last())
-	require.False(t, last.HasNext())
-	require.Nil(t, last.Next())
-	require.True(t, last.HasPrev())
-	require.Equal(t, 1, last.NumberOfElements())
-	require.Equal(t, 5, last.PageNumber())
+	c.Assert(last.URL(), qt.Equals, template.HTML("page/5/"))
+	c.Assert(last.Last(), qt.Equals, last)
+	c.Assert(last.HasNext(), qt.Equals, false)
+	c.Assert(last.Next(), qt.IsNil)
+	c.Assert(last.HasPrev(), qt.Equals, true)
+	c.Assert(last.NumberOfElements(), qt.Equals, 1)
+	c.Assert(last.PageNumber(), qt.Equals, 5)
 }
 
 func TestPagerNoPages(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	pages := createTestPages(0)
 	groups, _ := pages.GroupBy("Weight", "desc")
 
@@ -159,49 +162,50 @@
 	doTestPagerNoPages(t, paginator)
 
 	first := paginator.Pagers()[0].First()
-	require.Empty(t, first.PageGroups())
-	require.Empty(t, first.Pages())
+	c.Assert(first.PageGroups(), qt.HasLen, 0)
+	c.Assert(first.Pages(), qt.HasLen, 0)
 
 	paginator, _ = newPaginatorFromPageGroups(groups, 5, urlFactory)
 	doTestPagerNoPages(t, paginator)
 
 	first = paginator.Pagers()[0].First()
-	require.Empty(t, first.PageGroups())
-	require.Empty(t, first.Pages())
+	c.Assert(first.PageGroups(), qt.HasLen, 0)
+	c.Assert(first.Pages(), qt.HasLen, 0)
 
 }
 
 func doTestPagerNoPages(t *testing.T, paginator *Paginator) {
 	paginatorPages := paginator.Pagers()
+	c := qt.New(t)
+	c.Assert(len(paginatorPages), qt.Equals, 1)
+	c.Assert(paginator.TotalNumberOfElements(), qt.Equals, 0)
+	c.Assert(paginator.PageSize(), qt.Equals, 5)
+	c.Assert(paginator.TotalPages(), qt.Equals, 0)
 
-	require.Equal(t, 1, len(paginatorPages))
-	require.Equal(t, 0, paginator.TotalNumberOfElements())
-	require.Equal(t, 5, paginator.PageSize())
-	require.Equal(t, 0, paginator.TotalPages())
-
 	// pageOne should be nothing but the first
 	pageOne := paginatorPages[0]
-	require.NotNil(t, pageOne.First())
-	require.False(t, pageOne.HasNext())
-	require.False(t, pageOne.HasPrev())
-	require.Nil(t, pageOne.Next())
-	require.Equal(t, 1, len(pageOne.Pagers()))
-	require.Equal(t, 0, pageOne.Pages().Len())
-	require.Equal(t, 0, pageOne.NumberOfElements())
-	require.Equal(t, 0, pageOne.TotalNumberOfElements())
-	require.Equal(t, 0, pageOne.TotalPages())
-	require.Equal(t, 1, pageOne.PageNumber())
-	require.Equal(t, 5, pageOne.PageSize())
+	c.Assert(pageOne.First(), qt.Not(qt.IsNil))
+	c.Assert(pageOne.HasNext(), qt.Equals, false)
+	c.Assert(pageOne.HasPrev(), qt.Equals, false)
+	c.Assert(pageOne.Next(), qt.IsNil)
+	c.Assert(len(pageOne.Pagers()), qt.Equals, 1)
+	c.Assert(pageOne.Pages().Len(), qt.Equals, 0)
+	c.Assert(pageOne.NumberOfElements(), qt.Equals, 0)
+	c.Assert(pageOne.TotalNumberOfElements(), qt.Equals, 0)
+	c.Assert(pageOne.TotalPages(), qt.Equals, 0)
+	c.Assert(pageOne.PageNumber(), qt.Equals, 1)
+	c.Assert(pageOne.PageSize(), qt.Equals, 5)
 
 }
 
 func TestPaginationURLFactory(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	cfg := viper.New()
 	cfg.Set("paginatePath", "zoo")
 
 	for _, uglyURLs := range []bool{false, true} {
-		t.Run(fmt.Sprintf("uglyURLs=%t", uglyURLs), func(t *testing.T) {
+		c.Run(fmt.Sprintf("uglyURLs=%t", uglyURLs), func(c *qt.C) {
 
 			tests := []struct {
 				name         string
@@ -231,9 +235,9 @@
 				got := factory(test.page)
 
 				if uglyURLs {
-					require.Equal(t, test.expectedUgly, got)
+					c.Assert(got, qt.Equals, test.expectedUgly)
 				} else {
-					require.Equal(t, test.expected, got)
+					c.Assert(got, qt.Equals, test.expected)
 				}
 
 			}
@@ -279,6 +283,7 @@
 
 func TestPaginationPage(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	urlFactory := func(page int) string {
 		return fmt.Sprintf("page/%d/", page)
 	}
@@ -298,10 +303,10 @@
 	page21, _ := f2.page(1)
 	page2Nil, _ := f2.page(3)
 
-	require.Equal(t, 3, page11.FuzzyWordCount())
-	require.Nil(t, page1Nil)
+	c.Assert(page11.FuzzyWordCount(), qt.Equals, 3)
+	c.Assert(page1Nil, qt.IsNil)
 
-	require.NotNil(t, page21)
-	require.Equal(t, 3, page21.FuzzyWordCount())
-	require.Nil(t, page2Nil)
+	c.Assert(page21, qt.Not(qt.IsNil))
+	c.Assert(page21.FuzzyWordCount(), qt.Equals, 3)
+	c.Assert(page2Nil, qt.IsNil)
 }
--- a/resources/page/permalinks_test.go
+++ b/resources/page/permalinks_test.go
@@ -19,7 +19,7 @@
 	"testing"
 	"time"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 // testdataPermalinks is used by a couple of tests; the expandsTo content is
@@ -47,7 +47,7 @@
 func TestPermalinkExpansion(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	page := newTestPageWithFile("/test-page/index.md")
 	page.title = "Spf13 Vim 3.0 Release and new website"
@@ -56,10 +56,7 @@
 	page.section = "blue"
 	page.slug = "The Slug"
 
-	for i, item := range testdataPermalinks {
-
-		msg := fmt.Sprintf("Test %d", i)
-
+	for _, item := range testdataPermalinks {
 		if !item.valid {
 			continue
 		}
@@ -72,11 +69,11 @@
 		ps.Cfg.Set("permalinks", permalinksConfig)
 
 		expander, err := NewPermalinkExpander(ps)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		expanded, err := expander.Expand("posts", page)
-		assert.NoError(err)
-		assert.Equal(item.expandsTo, expanded, msg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(expanded, qt.Equals, item.expandsTo)
 
 	}
 }
@@ -84,7 +81,7 @@
 func TestPermalinkExpansionMultiSection(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	page := newTestPage()
 	page.title = "Page Title"
@@ -102,15 +99,15 @@
 	ps.Cfg.Set("permalinks", permalinksConfig)
 
 	expander, err := NewPermalinkExpander(ps)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	expanded, err := expander.Expand("posts", page)
-	assert.NoError(err)
-	assert.Equal("/the-slug", expanded)
+	c.Assert(err, qt.IsNil)
+	c.Assert(expanded, qt.Equals, "/the-slug")
 
 	expanded, err = expander.Expand("blog", page)
-	assert.NoError(err)
-	assert.Equal("/blue/2012", expanded)
+	c.Assert(err, qt.IsNil)
+	c.Assert(expanded, qt.Equals, "/blue/2012")
 
 }
 
@@ -117,7 +114,7 @@
 func TestPermalinkExpansionConcurrent(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	permalinksConfig := map[string]string{
 		"posts": "/:slug/",
@@ -127,7 +124,7 @@
 	ps.Cfg.Set("permalinks", permalinksConfig)
 
 	expander, err := NewPermalinkExpander(ps)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	var wg sync.WaitGroup
 
@@ -139,8 +136,8 @@
 			for j := 1; j < 20; j++ {
 				page.slug = fmt.Sprintf("slug%d", i+j)
 				expanded, err := expander.Expand("posts", page)
-				assert.NoError(err)
-				assert.Equal(fmt.Sprintf("/%s/", page.slug), expanded)
+				c.Assert(err, qt.IsNil)
+				c.Assert(expanded, qt.Equals, fmt.Sprintf("/%s/", page.slug))
 			}
 		}(i)
 	}
--- a/resources/resource_metadata_test.go
+++ b/resources/resource_metadata_test.go
@@ -19,12 +19,12 @@
 	"github.com/gohugoio/hugo/media"
 	"github.com/gohugoio/hugo/resources/resource"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestAssignMetadata(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
 
 	var foo1, foo2, foo3, logo1, logo2, logo3 resource.Resource
 	var resources resource.Resources
@@ -40,9 +40,9 @@
 				"src":   "*",
 			},
 		}, func(err error) {
-			assert.Equal("My Resource", logo1.Title())
-			assert.Equal("My Name", logo1.Name())
-			assert.Equal("My Name", foo2.Name())
+			c.Assert(logo1.Title(), qt.Equals, "My Resource")
+			c.Assert(logo1.Name(), qt.Equals, "My Name")
+			c.Assert(foo2.Name(), qt.Equals, "My Name")
 
 		}},
 		{[]map[string]interface{}{
@@ -56,12 +56,12 @@
 				"src":   "*",
 			},
 		}, func(err error) {
-			assert.Equal("My Logo", logo1.Title())
-			assert.Equal("My Logo", logo2.Title())
-			assert.Equal("My Name", logo1.Name())
-			assert.Equal("My Name", foo2.Name())
-			assert.Equal("My Name", foo3.Name())
-			assert.Equal("My Resource", foo3.Title())
+			c.Assert(logo1.Title(), qt.Equals, "My Logo")
+			c.Assert(logo2.Title(), qt.Equals, "My Logo")
+			c.Assert(logo1.Name(), qt.Equals, "My Name")
+			c.Assert(foo2.Name(), qt.Equals, "My Name")
+			c.Assert(foo3.Name(), qt.Equals, "My Name")
+			c.Assert(foo3.Title(), qt.Equals, "My Resource")
 
 		}},
 		{[]map[string]interface{}{
@@ -82,9 +82,9 @@
 				},
 			},
 		}, func(err error) {
-			assert.NoError(err)
-			assert.Equal("My Logo", logo1.Title())
-			assert.Equal("My Resource", foo3.Title())
+			c.Assert(err, qt.IsNil)
+			c.Assert(logo1.Title(), qt.Equals, "My Logo")
+			c.Assert(foo3.Title(), qt.Equals, "My Resource")
 			_, p1 := logo2.Params()["param1"]
 			_, p2 := foo2.Params()["param2"]
 			_, p1_2 := foo2.Params()["param1"]
@@ -93,15 +93,15 @@
 			icon1 := logo2.Params()["icon"]
 			icon2 := foo2.Params()["icon"]
 
-			assert.True(p1)
-			assert.True(p2)
+			c.Assert(p1, qt.Equals, true)
+			c.Assert(p2, qt.Equals, true)
 
 			// Check merge
-			assert.True(p2_2)
-			assert.False(p1_2)
+			c.Assert(p2_2, qt.Equals, true)
+			c.Assert(p1_2, qt.Equals, false)
 
-			assert.Equal("logo", icon1)
-			assert.Equal("resource", icon2)
+			c.Assert(icon1, qt.Equals, "logo")
+			c.Assert(icon2, qt.Equals, "resource")
 
 		}},
 		{[]map[string]interface{}{
@@ -115,17 +115,17 @@
 				"src":   "*",
 			},
 		}, func(err error) {
-			assert.NoError(err)
-			assert.Equal("Resource #2", logo2.Title())
-			assert.Equal("Logo Name #1", logo2.Name())
-			assert.Equal("Resource #4", logo1.Title())
-			assert.Equal("Logo Name #2", logo1.Name())
-			assert.Equal("Resource #1", foo2.Title())
-			assert.Equal("Resource #3", foo1.Title())
-			assert.Equal("Name #2", foo1.Name())
-			assert.Equal("Resource #5", foo3.Title())
+			c.Assert(err, qt.IsNil)
+			c.Assert(logo2.Title(), qt.Equals, "Resource #2")
+			c.Assert(logo2.Name(), qt.Equals, "Logo Name #1")
+			c.Assert(logo1.Title(), qt.Equals, "Resource #4")
+			c.Assert(logo1.Name(), qt.Equals, "Logo Name #2")
+			c.Assert(foo2.Title(), qt.Equals, "Resource #1")
+			c.Assert(foo1.Title(), qt.Equals, "Resource #3")
+			c.Assert(foo1.Name(), qt.Equals, "Name #2")
+			c.Assert(foo3.Title(), qt.Equals, "Resource #5")
 
-			assert.Equal(logo2, resources.GetMatch("logo name #1*"))
+			c.Assert(resources.GetMatch("logo name #1*"), qt.Equals, logo2)
 
 		}},
 		{[]map[string]interface{}{
@@ -139,13 +139,13 @@
 				"src":   "logo*",
 			},
 		}, func(err error) {
-			assert.NoError(err)
-			assert.Equal("Third Logo #1", logo3.Title())
-			assert.Equal("Name #3", logo3.Name())
-			assert.Equal("Other Logo #1", logo2.Title())
-			assert.Equal("Name #1", logo2.Name())
-			assert.Equal("Other Logo #2", logo1.Title())
-			assert.Equal("Name #2", logo1.Name())
+			c.Assert(err, qt.IsNil)
+			c.Assert(logo3.Title(), qt.Equals, "Third Logo #1")
+			c.Assert(logo3.Name(), qt.Equals, "Name #3")
+			c.Assert(logo2.Title(), qt.Equals, "Other Logo #1")
+			c.Assert(logo2.Name(), qt.Equals, "Name #1")
+			c.Assert(logo1.Title(), qt.Equals, "Other Logo #2")
+			c.Assert(logo1.Name(), qt.Equals, "Name #2")
 
 		}},
 		{[]map[string]interface{}{
@@ -159,13 +159,13 @@
 				"src":   "logo*",
 			},
 		}, func(err error) {
-			assert.NoError(err)
-			assert.Equal("Third Logo", logo3.Title())
-			assert.Equal("Name #3", logo3.Name())
-			assert.Equal("Other Logo #1", logo2.Title())
-			assert.Equal("Name #1", logo2.Name())
-			assert.Equal("Other Logo #2", logo1.Title())
-			assert.Equal("Name #2", logo1.Name())
+			c.Assert(err, qt.IsNil)
+			c.Assert(logo3.Title(), qt.Equals, "Third Logo")
+			c.Assert(logo3.Name(), qt.Equals, "Name #3")
+			c.Assert(logo2.Title(), qt.Equals, "Other Logo #1")
+			c.Assert(logo2.Name(), qt.Equals, "Name #1")
+			c.Assert(logo1.Title(), qt.Equals, "Other Logo #2")
+			c.Assert(logo1.Name(), qt.Equals, "Name #2")
 
 		}},
 		{[]map[string]interface{}{
@@ -179,13 +179,13 @@
 				"src":   "logo*",
 			},
 		}, func(err error) {
-			assert.NoError(err)
-			assert.Equal("Logo #3", logo3.Title())
-			assert.Equal("third-logo", logo3.Name())
-			assert.Equal("Logo #1", logo2.Title())
-			assert.Equal("Name #1", logo2.Name())
-			assert.Equal("Logo #2", logo1.Title())
-			assert.Equal("Name #2", logo1.Name())
+			c.Assert(err, qt.IsNil)
+			c.Assert(logo3.Title(), qt.Equals, "Logo #3")
+			c.Assert(logo3.Name(), qt.Equals, "third-logo")
+			c.Assert(logo2.Title(), qt.Equals, "Logo #1")
+			c.Assert(logo2.Name(), qt.Equals, "Name #1")
+			c.Assert(logo1.Title(), qt.Equals, "Logo #2")
+			c.Assert(logo1.Name(), qt.Equals, "Name #2")
 
 		}},
 		{[]map[string]interface{}{
@@ -194,7 +194,7 @@
 			},
 		}, func(err error) {
 			// Missing src
-			assert.Error(err)
+			c.Assert(err, qt.Not(qt.IsNil))
 
 		}},
 		{[]map[string]interface{}{
@@ -204,7 +204,7 @@
 			},
 		}, func(err error) {
 			// Invalid pattern
-			assert.Error(err)
+			c.Assert(err, qt.Not(qt.IsNil))
 
 		}},
 	} {
--- a/resources/resource_test.go
+++ b/resources/resource_test.go
@@ -27,38 +27,38 @@
 
 	"github.com/gohugoio/hugo/media"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestGenericResource(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
 
 	r := spec.newGenericResource(nil, nil, nil, "/a/foo.css", "foo.css", media.CSSType)
 
-	assert.Equal("https://example.com/foo.css", r.Permalink())
-	assert.Equal("/foo.css", r.RelPermalink())
-	assert.Equal("css", r.ResourceType())
+	c.Assert(r.Permalink(), qt.Equals, "https://example.com/foo.css")
+	c.Assert(r.RelPermalink(), qt.Equals, "/foo.css")
+	c.Assert(r.ResourceType(), qt.Equals, "css")
 
 }
 
 func TestGenericResourceWithLinkFacory(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
 
 	factory := newTargetPaths("/foo")
 
 	r := spec.newGenericResource(nil, factory, nil, "/a/foo.css", "foo.css", media.CSSType)
 
-	assert.Equal("https://example.com/foo/foo.css", r.Permalink())
-	assert.Equal("/foo/foo.css", r.RelPermalink())
-	assert.Equal("foo.css", r.Key())
-	assert.Equal("css", r.ResourceType())
+	c.Assert(r.Permalink(), qt.Equals, "https://example.com/foo/foo.css")
+	c.Assert(r.RelPermalink(), qt.Equals, "/foo/foo.css")
+	c.Assert(r.Key(), qt.Equals, "foo.css")
+	c.Assert(r.ResourceType(), qt.Equals, "css")
 }
 
 func TestNewResourceFromFilename(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
 
 	writeSource(t, spec.Fs, "content/a/b/logo.png", "image")
 	writeSource(t, spec.Fs, "content/a/b/data.json", "json")
@@ -67,26 +67,26 @@
 
 	r, err := spec.New(ResourceSourceDescriptor{Fs: bfs, SourceFilename: "a/b/logo.png"})
 
-	assert.NoError(err)
-	assert.NotNil(r)
-	assert.Equal("image", r.ResourceType())
-	assert.Equal("/a/b/logo.png", r.RelPermalink())
-	assert.Equal("https://example.com/a/b/logo.png", r.Permalink())
+	c.Assert(err, qt.IsNil)
+	c.Assert(r, qt.Not(qt.IsNil))
+	c.Assert(r.ResourceType(), qt.Equals, "image")
+	c.Assert(r.RelPermalink(), qt.Equals, "/a/b/logo.png")
+	c.Assert(r.Permalink(), qt.Equals, "https://example.com/a/b/logo.png")
 
 	r, err = spec.New(ResourceSourceDescriptor{Fs: bfs, SourceFilename: "a/b/data.json"})
 
-	assert.NoError(err)
-	assert.NotNil(r)
-	assert.Equal("json", r.ResourceType())
+	c.Assert(err, qt.IsNil)
+	c.Assert(r, qt.Not(qt.IsNil))
+	c.Assert(r.ResourceType(), qt.Equals, "json")
 
 	cloned := r.(resource.Cloner).WithNewBase("aceof")
-	assert.Equal(r.ResourceType(), cloned.ResourceType())
-	assert.Equal("/aceof/a/b/data.json", cloned.RelPermalink())
+	c.Assert(cloned.ResourceType(), qt.Equals, r.ResourceType())
+	c.Assert(cloned.RelPermalink(), qt.Equals, "/aceof/a/b/data.json")
 }
 
 func TestNewResourceFromFilenameSubPathInBaseURL(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpecForBaseURL(assert, "https://example.com/docs")
+	c := qt.New(t)
+	spec := newTestResourceSpecForBaseURL(c, "https://example.com/docs")
 
 	writeSource(t, spec.Fs, "content/a/b/logo.png", "image")
 	bfs := afero.NewBasePathFs(spec.Fs.Source, "content")
@@ -94,13 +94,13 @@
 	fmt.Println()
 	r, err := spec.New(ResourceSourceDescriptor{Fs: bfs, SourceFilename: filepath.FromSlash("a/b/logo.png")})
 
-	assert.NoError(err)
-	assert.NotNil(r)
-	assert.Equal("image", r.ResourceType())
-	assert.Equal("/docs/a/b/logo.png", r.RelPermalink())
-	assert.Equal("https://example.com/docs/a/b/logo.png", r.Permalink())
+	c.Assert(err, qt.IsNil)
+	c.Assert(r, qt.Not(qt.IsNil))
+	c.Assert(r.ResourceType(), qt.Equals, "image")
+	c.Assert(r.RelPermalink(), qt.Equals, "/docs/a/b/logo.png")
+	c.Assert(r.Permalink(), qt.Equals, "https://example.com/docs/a/b/logo.png")
 	img := r.(*Image)
-	assert.Equal(filepath.FromSlash("/a/b/logo.png"), img.targetFilenames()[0])
+	c.Assert(img.targetFilenames()[0], qt.Equals, filepath.FromSlash("/a/b/logo.png"))
 
 }
 
@@ -107,8 +107,8 @@
 var pngType, _ = media.FromStringAndExt("image/png", "png")
 
 func TestResourcesByType(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
 	resources := resource.Resources{
 		spec.newGenericResource(nil, nil, nil, "/a/foo1.css", "foo1.css", media.CSSType),
 		spec.newGenericResource(nil, nil, nil, "/a/logo.png", "logo.css", pngType),
@@ -115,14 +115,14 @@
 		spec.newGenericResource(nil, nil, nil, "/a/foo2.css", "foo2.css", media.CSSType),
 		spec.newGenericResource(nil, nil, nil, "/a/foo3.css", "foo3.css", media.CSSType)}
 
-	assert.Len(resources.ByType("css"), 3)
-	assert.Len(resources.ByType("image"), 1)
+	c.Assert(len(resources.ByType("css")), qt.Equals, 3)
+	c.Assert(len(resources.ByType("image")), qt.Equals, 1)
 
 }
 
 func TestResourcesGetByPrefix(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
 	resources := resource.Resources{
 		spec.newGenericResource(nil, nil, nil, "/a/foo1.css", "foo1.css", media.CSSType),
 		spec.newGenericResource(nil, nil, nil, "/a/logo1.png", "logo1.png", pngType),
@@ -130,28 +130,28 @@
 		spec.newGenericResource(nil, nil, nil, "/b/foo2.css", "foo2.css", media.CSSType),
 		spec.newGenericResource(nil, nil, nil, "/b/foo3.css", "foo3.css", media.CSSType)}
 
-	assert.Nil(resources.GetMatch("asdf*"))
-	assert.Equal("/logo1.png", resources.GetMatch("logo*").RelPermalink())
-	assert.Equal("/logo1.png", resources.GetMatch("loGo*").RelPermalink())
-	assert.Equal("/Logo2.png", resources.GetMatch("logo2*").RelPermalink())
-	assert.Equal("/foo2.css", resources.GetMatch("foo2*").RelPermalink())
-	assert.Equal("/foo1.css", resources.GetMatch("foo1*").RelPermalink())
-	assert.Equal("/foo1.css", resources.GetMatch("foo1*").RelPermalink())
-	assert.Nil(resources.GetMatch("asdfasdf*"))
+	c.Assert(resources.GetMatch("asdf*"), qt.IsNil)
+	c.Assert(resources.GetMatch("logo*").RelPermalink(), qt.Equals, "/logo1.png")
+	c.Assert(resources.GetMatch("loGo*").RelPermalink(), qt.Equals, "/logo1.png")
+	c.Assert(resources.GetMatch("logo2*").RelPermalink(), qt.Equals, "/Logo2.png")
+	c.Assert(resources.GetMatch("foo2*").RelPermalink(), qt.Equals, "/foo2.css")
+	c.Assert(resources.GetMatch("foo1*").RelPermalink(), qt.Equals, "/foo1.css")
+	c.Assert(resources.GetMatch("foo1*").RelPermalink(), qt.Equals, "/foo1.css")
+	c.Assert(resources.GetMatch("asdfasdf*"), qt.IsNil)
 
-	assert.Equal(2, len(resources.Match("logo*")))
-	assert.Equal(1, len(resources.Match("logo2*")))
+	c.Assert(len(resources.Match("logo*")), qt.Equals, 2)
+	c.Assert(len(resources.Match("logo2*")), qt.Equals, 1)
 
 	logo := resources.GetMatch("logo*")
-	assert.NotNil(logo.Params())
-	assert.Equal("logo1.png", logo.Name())
-	assert.Equal("logo1.png", logo.Title())
+	c.Assert(logo.Params(), qt.Not(qt.IsNil))
+	c.Assert(logo.Name(), qt.Equals, "logo1.png")
+	c.Assert(logo.Title(), qt.Equals, "logo1.png")
 
 }
 
 func TestResourcesGetMatch(t *testing.T) {
-	assert := require.New(t)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(t)
+	spec := newTestResourceSpec(c)
 	resources := resource.Resources{
 		spec.newGenericResource(nil, nil, nil, "/a/foo1.css", "foo1.css", media.CSSType),
 		spec.newGenericResource(nil, nil, nil, "/a/logo1.png", "logo1.png", pngType),
@@ -163,35 +163,35 @@
 		spec.newGenericResource(nil, nil, nil, "/b/c/d/foo6.css", "c/d/foo6.css", media.CSSType),
 	}
 
-	assert.Equal("/logo1.png", resources.GetMatch("logo*").RelPermalink())
-	assert.Equal("/logo1.png", resources.GetMatch("loGo*").RelPermalink())
-	assert.Equal("/Logo2.png", resources.GetMatch("logo2*").RelPermalink())
-	assert.Equal("/foo2.css", resources.GetMatch("foo2*").RelPermalink())
-	assert.Equal("/foo1.css", resources.GetMatch("foo1*").RelPermalink())
-	assert.Equal("/foo1.css", resources.GetMatch("foo1*").RelPermalink())
-	assert.Equal("/c/foo4.css", resources.GetMatch("*/foo*").RelPermalink())
+	c.Assert(resources.GetMatch("logo*").RelPermalink(), qt.Equals, "/logo1.png")
+	c.Assert(resources.GetMatch("loGo*").RelPermalink(), qt.Equals, "/logo1.png")
+	c.Assert(resources.GetMatch("logo2*").RelPermalink(), qt.Equals, "/Logo2.png")
+	c.Assert(resources.GetMatch("foo2*").RelPermalink(), qt.Equals, "/foo2.css")
+	c.Assert(resources.GetMatch("foo1*").RelPermalink(), qt.Equals, "/foo1.css")
+	c.Assert(resources.GetMatch("foo1*").RelPermalink(), qt.Equals, "/foo1.css")
+	c.Assert(resources.GetMatch("*/foo*").RelPermalink(), qt.Equals, "/c/foo4.css")
 
-	assert.Nil(resources.GetMatch("asdfasdf"))
+	c.Assert(resources.GetMatch("asdfasdf"), qt.IsNil)
 
-	assert.Equal(2, len(resources.Match("Logo*")))
-	assert.Equal(1, len(resources.Match("logo2*")))
-	assert.Equal(2, len(resources.Match("c/*")))
+	c.Assert(len(resources.Match("Logo*")), qt.Equals, 2)
+	c.Assert(len(resources.Match("logo2*")), qt.Equals, 1)
+	c.Assert(len(resources.Match("c/*")), qt.Equals, 2)
 
-	assert.Equal(6, len(resources.Match("**.css")))
-	assert.Equal(3, len(resources.Match("**/*.css")))
-	assert.Equal(1, len(resources.Match("c/**/*.css")))
+	c.Assert(len(resources.Match("**.css")), qt.Equals, 6)
+	c.Assert(len(resources.Match("**/*.css")), qt.Equals, 3)
+	c.Assert(len(resources.Match("c/**/*.css")), qt.Equals, 1)
 
 	// Matches only CSS files in c/
-	assert.Equal(3, len(resources.Match("c/**.css")))
+	c.Assert(len(resources.Match("c/**.css")), qt.Equals, 3)
 
 	// Matches all CSS files below c/ (including in c/d/)
-	assert.Equal(3, len(resources.Match("c/**.css")))
+	c.Assert(len(resources.Match("c/**.css")), qt.Equals, 3)
 
 	// Patterns beginning with a slash will not match anything.
 	// We could maybe consider trimming that slash, but let's be explicit about this.
 	// (it is possible for users to do a rename)
 	// This is analogous to standing in a directory and doing "ls *.*".
-	assert.Equal(0, len(resources.Match("/c/**.css")))
+	c.Assert(len(resources.Match("/c/**.css")), qt.Equals, 0)
 
 }
 
@@ -212,8 +212,8 @@
 // I don't expect Hugo users to "stumble upon" this problem, so this is more to satisfy
 // my own curiosity.
 func BenchmarkResourcesMatchA100(b *testing.B) {
-	assert := require.New(b)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(b)
+	spec := newTestResourceSpec(c)
 	a100 := strings.Repeat("a", 100)
 	pattern := "a*a*a*a*a*a*a*a*b"
 
@@ -227,8 +227,8 @@
 }
 
 func benchResources(b *testing.B) resource.Resources {
-	assert := require.New(b)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(b)
+	spec := newTestResourceSpec(c)
 	var resources resource.Resources
 
 	for i := 0; i < 30; i++ {
@@ -251,8 +251,8 @@
 }
 
 func BenchmarkAssignMetadata(b *testing.B) {
-	assert := require.New(b)
-	spec := newTestResourceSpec(assert)
+	c := qt.New(b)
+	spec := newTestResourceSpec(c)
 
 	for i := 0; i < b.N; i++ {
 		b.StopTimer()
--- a/resources/resource_transformers/integrity/integrity_test.go
+++ b/resources/resource_transformers/integrity/integrity_test.go
@@ -16,7 +16,7 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestHashFromAlgo(t *testing.T) {
@@ -33,14 +33,14 @@
 	} {
 
 		t.Run(algo.name, func(t *testing.T) {
-			assert := require.New(t)
+			c := qt.New(t)
 			h, err := newHash(algo.name)
 			if algo.bits > 0 {
-				assert.NoError(err)
-				assert.Equal(algo.bits/8, h.Size())
+				c.Assert(err, qt.IsNil)
+				c.Assert(h.Size(), qt.Equals, algo.bits/8)
 			} else {
-				assert.Error(err)
-				assert.Contains(err.Error(), "use either md5, sha256, sha384 or sha512")
+				c.Assert(err, qt.Not(qt.IsNil))
+				c.Assert(err.Error(), qt.Contains, "use either md5, sha256, sha384 or sha512")
 			}
 
 		})
--- a/resources/resource_transformers/postcss/postcss_test.go
+++ b/resources/resource_transformers/postcss/postcss_test.go
@@ -16,24 +16,24 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 // Issue 6166
 func TestDecodeOptions(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	opts1, err := DecodeOptions(map[string]interface{}{
 		"no-map": true,
 	})
 
-	assert.NoError(err)
-	assert.True(opts1.NoMap)
+	c.Assert(err, qt.IsNil)
+	c.Assert(opts1.NoMap, qt.Equals, true)
 
 	opts2, err := DecodeOptions(map[string]interface{}{
 		"noMap": true,
 	})
 
-	assert.NoError(err)
-	assert.True(opts2.NoMap)
+	c.Assert(err, qt.IsNil)
+	c.Assert(opts2.NoMap, qt.Equals, true)
 
 }
--- a/resources/testhelpers_test.go
+++ b/resources/testhelpers_test.go
@@ -4,6 +4,8 @@
 	"path/filepath"
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
 	"image"
 	"io"
 	"io/ioutil"
@@ -14,6 +16,7 @@
 	"github.com/gohugoio/hugo/langs"
 	"github.com/gohugoio/hugo/modules"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/cache/filecache"
 	"github.com/gohugoio/hugo/helpers"
 	"github.com/gohugoio/hugo/hugofs"
@@ -23,11 +26,10 @@
 	"github.com/gohugoio/hugo/resources/resource"
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
-func newTestResourceSpec(assert *require.Assertions) *Spec {
-	return newTestResourceSpecForBaseURL(assert, "https://example.com/")
+func newTestResourceSpec(c *qt.C) *Spec {
+	return newTestResourceSpecForBaseURL(c, "https://example.com/")
 }
 
 func createTestCfg() *viper.Viper {
@@ -52,7 +54,7 @@
 
 }
 
-func newTestResourceSpecForBaseURL(assert *require.Assertions, baseURL string) *Spec {
+func newTestResourceSpecForBaseURL(c *qt.C, baseURL string) *Spec {
 	cfg := createTestCfg()
 	cfg.Set("baseURL", baseURL)
 
@@ -67,13 +69,13 @@
 	fs := hugofs.NewMem(cfg)
 
 	s, err := helpers.NewPathSpec(fs, cfg, nil)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	filecaches, err := filecache.NewCaches(s)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	spec, err := NewSpec(s, filecaches, nil, output.DefaultFormats, media.DefaultTypes)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	return spec
 }
 
@@ -86,7 +88,7 @@
 	}
 }
 
-func newTestResourceOsFs(assert *require.Assertions) *Spec {
+func newTestResourceOsFs(c *qt.C) *Spec {
 	cfg := createTestCfg()
 	cfg.Set("baseURL", "https://example.com")
 
@@ -104,66 +106,66 @@
 	fs.Destination = &afero.MemMapFs{}
 
 	s, err := helpers.NewPathSpec(fs, cfg, nil)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	filecaches, err := filecache.NewCaches(s)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	spec, err := NewSpec(s, filecaches, nil, output.DefaultFormats, media.DefaultTypes)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	return spec
 
 }
 
-func fetchSunset(assert *require.Assertions) *Image {
-	return fetchImage(assert, "sunset.jpg")
+func fetchSunset(c *qt.C) *Image {
+	return fetchImage(c, "sunset.jpg")
 }
 
-func fetchImage(assert *require.Assertions, name string) *Image {
-	spec := newTestResourceSpec(assert)
-	return fetchImageForSpec(spec, assert, name)
+func fetchImage(c *qt.C, name string) *Image {
+	spec := newTestResourceSpec(c)
+	return fetchImageForSpec(spec, c, name)
 }
 
-func fetchImageForSpec(spec *Spec, assert *require.Assertions, name string) *Image {
-	r := fetchResourceForSpec(spec, assert, name)
-	assert.IsType(&Image{}, r)
+func fetchImageForSpec(spec *Spec, c *qt.C, name string) *Image {
+	r := fetchResourceForSpec(spec, c, name)
+	c.Assert(r, hqt.IsSameType, &Image{})
 	return r.(*Image)
 }
 
-func fetchResourceForSpec(spec *Spec, assert *require.Assertions, name string) resource.ContentResource {
+func fetchResourceForSpec(spec *Spec, c *qt.C, name string) resource.ContentResource {
 	src, err := os.Open(filepath.FromSlash("testdata/" + name))
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	out, err := helpers.OpenFileForWriting(spec.Fs.Source, name)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	_, err = io.Copy(out, src)
 	out.Close()
 	src.Close()
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	factory := newTargetPaths("/a")
 
 	r, err := spec.New(ResourceSourceDescriptor{Fs: spec.Fs.Source, TargetPaths: factory, LazyPublish: true, SourceFilename: name})
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	return r.(resource.ContentResource)
 }
 
-func assertImageFile(assert *require.Assertions, fs afero.Fs, filename string, width, height int) {
+func assertImageFile(c *qt.C, fs afero.Fs, filename string, width, height int) {
 	filename = filepath.Clean(filename)
 	f, err := fs.Open(filename)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	defer f.Close()
 
 	config, _, err := image.DecodeConfig(f)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
-	assert.Equal(width, config.Width)
-	assert.Equal(height, config.Height)
+	c.Assert(config.Width, qt.Equals, width)
+	c.Assert(config.Height, qt.Equals, height)
 }
 
-func assertFileCache(assert *require.Assertions, fs afero.Fs, filename string, width, height int) {
-	assertImageFile(assert, fs, filepath.Clean(filename), width, height)
+func assertFileCache(c *qt.C, fs afero.Fs, filename string, width, height int) {
+	assertImageFile(c, fs, filepath.Clean(filename), width, height)
 }
 
 func writeSource(t testing.TB, fs *hugofs.Fs, filename, content string) {
--- a/resources/transform_test.go
+++ b/resources/transform_test.go
@@ -16,7 +16,7 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 type testStruct struct {
@@ -31,6 +31,6 @@
 	// We really need this key to be portable across OSes.
 	key := NewResourceTransformationKey("testing",
 		testStruct{Name: "test", V1: int64(10), V2: int32(20), V3: 30, V4: uint64(40)})
-	assert := require.New(t)
-	assert.Equal(key.key(), "testing_518996646957295636")
+	c := qt.New(t)
+	c.Assert("testing_518996646957295636", qt.Equals, key.key())
 }
--- a/source/content_directory_test.go
+++ b/source/content_directory_test.go
@@ -19,12 +19,12 @@
 
 	"github.com/gohugoio/hugo/helpers"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/hugofs"
-	"github.com/stretchr/testify/require"
 )
 
 func TestIgnoreDotFilesAndDirectories(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tests := []struct {
 		path                string
@@ -55,7 +55,7 @@
 		v.Set("ignoreFiles", test.ignoreFilesRegexpes)
 		fs := hugofs.NewMem(v)
 		ps, err := helpers.NewPathSpec(fs, v, nil)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		s := NewSourceSpec(ps, fs.Source)
 
--- a/source/fileInfo_test.go
+++ b/source/fileInfo_test.go
@@ -18,11 +18,11 @@
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestFileInfo(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	s := newTestSourceSpec()
 
@@ -32,29 +32,29 @@
 		assert   func(f *FileInfo)
 	}{
 		{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/page.md"), func(f *FileInfo) {
-			assert.Equal(filepath.FromSlash("/a/b/page.md"), f.Filename())
-			assert.Equal(filepath.FromSlash("b/"), f.Dir())
-			assert.Equal(filepath.FromSlash("b/page.md"), f.Path())
-			assert.Equal("b", f.Section())
-			assert.Equal(filepath.FromSlash("page"), f.TranslationBaseName())
-			assert.Equal(filepath.FromSlash("page"), f.BaseFileName())
+			c.Assert(f.Filename(), qt.Equals, filepath.FromSlash("/a/b/page.md"))
+			c.Assert(f.Dir(), qt.Equals, filepath.FromSlash("b/"))
+			c.Assert(f.Path(), qt.Equals, filepath.FromSlash("b/page.md"))
+			c.Assert(f.Section(), qt.Equals, "b")
+			c.Assert(f.TranslationBaseName(), qt.Equals, filepath.FromSlash("page"))
+			c.Assert(f.BaseFileName(), qt.Equals, filepath.FromSlash("page"))
 
 		}},
 		{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/c/d/page.md"), func(f *FileInfo) {
-			assert.Equal("b", f.Section())
+			c.Assert(f.Section(), qt.Equals, "b")
 
 		}},
 		{filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/page.en.MD"), func(f *FileInfo) {
-			assert.Equal("b", f.Section())
-			assert.Equal(filepath.FromSlash("b/page.en.MD"), f.Path())
-			assert.Equal(filepath.FromSlash("page"), f.TranslationBaseName())
-			assert.Equal(filepath.FromSlash("page.en"), f.BaseFileName())
+			c.Assert(f.Section(), qt.Equals, "b")
+			c.Assert(f.Path(), qt.Equals, filepath.FromSlash("b/page.en.MD"))
+			c.Assert(f.TranslationBaseName(), qt.Equals, filepath.FromSlash("page"))
+			c.Assert(f.BaseFileName(), qt.Equals, filepath.FromSlash("page.en"))
 
 		}},
 	} {
 		path := strings.TrimPrefix(this.filename, this.base)
 		f, err := s.NewFileInfoFrom(path, this.filename)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		this.assert(f)
 	}
 
--- a/source/filesystem_test.go
+++ b/source/filesystem_test.go
@@ -25,19 +25,19 @@
 
 	"github.com/spf13/afero"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/helpers"
 	"github.com/gohugoio/hugo/hugofs"
-	"github.com/stretchr/testify/require"
 
 	"github.com/spf13/viper"
 )
 
 func TestEmptySourceFilesystem(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	ss := newTestSourceSpec()
 	src := ss.NewFilesystem("")
 	files, err := src.Files()
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	if len(files) != 0 {
 		t.Errorf("new filesystem should contain 0 files.")
 	}
@@ -49,7 +49,7 @@
 		return
 	}
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	paths := []struct {
 		NFC string
@@ -64,11 +64,11 @@
 
 	for i, path := range paths {
 		base := fmt.Sprintf("base%d", i)
-		assert.NoError(afero.WriteFile(ss.Fs.Source, filepath.Join(base, path.NFD), []byte("some data"), 0777))
+		c.Assert(afero.WriteFile(ss.Fs.Source, filepath.Join(base, path.NFD), []byte("some data"), 0777), qt.IsNil)
 		src := ss.NewFilesystem(base)
 		_ = src.add(path.NFD, fi)
 		files, err := src.Files()
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		f := files[0]
 		if f.BaseFileName() != path.NFC {
 			t.Fatalf("file %q name in NFD form should be normalized (%s)", f.BaseFileName(), path.NFC)
--- a/tpl/cast/cast_test.go
+++ b/tpl/cast/cast_test.go
@@ -14,16 +14,15 @@
 package cast
 
 import (
-	"fmt"
 	"html/template"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestToInt(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
@@ -40,23 +39,23 @@
 		{"a", false},
 		{t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.v)
+		errMsg := qt.Commentf("[%d] %v", i, test.v)
 
 		result, err := ns.ToInt(test.v)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestToString(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New()
 
 	for i, test := range []struct {
@@ -68,23 +67,23 @@
 		{"a", "a"},
 		{t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.v)
+		errMsg := qt.Commentf("[%d] %v", i, test.v)
 
 		result, err := ns.ToString(test.v)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestToFloat(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New()
 
 	for i, test := range []struct {
@@ -105,16 +104,16 @@
 		{2, 2.0},
 		{t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.v)
+		errMsg := qt.Commentf("[%d] %v", i, test.v)
 
 		result, err := ns.ToFloat(test.v)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
--- a/tpl/cast/init_test.go
+++ b/tpl/cast/init_test.go
@@ -16,12 +16,15 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +36,7 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
+
 }
--- a/tpl/collections/append_test.go
+++ b/tpl/collections/append_test.go
@@ -14,17 +14,17 @@
 package collections
 
 import (
-	"fmt"
 	"reflect"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
-	"github.com/stretchr/testify/require"
 )
 
 // Also see tests in common/collection.
 func TestAppend(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -45,7 +45,7 @@
 			false},
 	} {
 
-		errMsg := fmt.Sprintf("[%d]", i)
+		errMsg := qt.Commentf("[%d]", i)
 
 		args := append(test.addend, test.start)
 
@@ -52,11 +52,11 @@
 		result, err := ns.Append(args...)
 
 		if b, ok := test.expected.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
 
 		if !reflect.DeepEqual(test.expected, result) {
 			t.Fatalf("%s got\n%T: %v\nexpected\n%T: %v", errMsg, result, result, test.expected, test.expected)
--- a/tpl/collections/apply_test.go
+++ b/tpl/collections/apply_test.go
@@ -18,9 +18,9 @@
 
 	"fmt"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl"
-	"github.com/stretchr/testify/require"
 )
 
 type templateFinder int
@@ -41,6 +41,7 @@
 
 func TestApply(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{Tmpl: new(templateFinder)})
 
@@ -47,18 +48,18 @@
 	strings := []interface{}{"a\n", "b\n"}
 
 	result, err := ns.Apply(strings, "print", "a", "b", "c")
-	require.NoError(t, err)
-	require.Equal(t, []interface{}{"abc", "abc"}, result, "testing variadic")
+	c.Assert(err, qt.IsNil)
+	c.Assert(result, qt.DeepEquals, []interface{}{"abc", "abc"})
 
 	_, err = ns.Apply(strings, "apply", ".")
-	require.Error(t, err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	var nilErr *error
 	_, err = ns.Apply(nilErr, "chomp", ".")
-	require.Error(t, err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	_, err = ns.Apply(strings, "dobedobedo", ".")
-	require.Error(t, err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	_, err = ns.Apply(strings, "foo.Chomp", "c\n")
 	if err == nil {
--- a/tpl/collections/collections_test.go
+++ b/tpl/collections/collections_test.go
@@ -22,6 +22,7 @@
 	"testing"
 	"time"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/loggers"
 	"github.com/gohugoio/hugo/config"
 	"github.com/gohugoio/hugo/deps"
@@ -29,8 +30,6 @@
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/gohugoio/hugo/langs"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 type tstNoStringer struct{}
@@ -37,6 +36,7 @@
 
 func TestAfter(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -58,17 +58,17 @@
 		{1, t, false},
 		{1, (*string)(nil), false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.After(test.index, test.seq)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		require.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.DeepEquals, test.expect, errMsg)
 	}
 }
 
@@ -92,7 +92,7 @@
 
 func TestGroup(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
@@ -111,22 +111,23 @@
 		{"a", nil, false},
 		{nil, []*tstGrouper{{}, {}}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.Group(test.key, test.items)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		require.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestDelimit(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -161,7 +162,7 @@
 		{map[int]string{3: "10", 2: "20", 1: "30", 4: "40", 5: "50"}, "--", "--and--", "30--20--10--40--and--50"},
 		{map[float64]string{3.5: "10", 2.5: "20", 1.5: "30", 4.5: "40", 5.5: "50"}, "--", "--and--", "30--20--10--40--and--50"},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		var result template.HTML
 		var err error
@@ -172,13 +173,14 @@
 			result, err = ns.Delimit(test.seq, test.delimiter, test.last)
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestDictionary(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -192,22 +194,23 @@
 		{[]interface{}{5, "b"}, false},
 		{[]interface{}{"a", "b", "c"}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.values)
+		errMsg := qt.Commentf("[%d] %v", i, test.values)
 
 		result, err := ns.Dictionary(test.values...)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.DeepEquals, test.expect, errMsg)
 	}
 }
 
 func TestEchoParam(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -229,16 +232,17 @@
 		{map[string]interface{}{"foo": nil}, "foo", ""},
 		{(*[]string)(nil), "bar", ""},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result := ns.EchoParam(test.a, test.key)
 
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestFirst(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -260,23 +264,23 @@
 		{1, t, false},
 		{1, (*string)(nil), false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.First(test.limit, test.seq)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.DeepEquals, test.expect, errMsg)
 	}
 }
 
 func TestIn(t *testing.T) {
 	t.Parallel()
-	assert := require.New(t)
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -311,16 +315,16 @@
 		{pagesVals{p3v, p2v, p3v, p2v}, p4v, false},
 	} {
 
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.In(test.l1, test.l2)
-		assert.NoError(err)
-		assert.Equal(test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 
 	// Slices are not comparable
 	_, err := ns.In([]string{"a", "b"}, []string{"a", "b"})
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 }
 
 type testPage struct {
@@ -348,6 +352,7 @@
 
 func TestIntersect(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -420,16 +425,16 @@
 		{[]int{1, 1}, [][]int{{1, 2}, {1, 2}, {1, 3}}, false},
 	} {
 
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.Intersect(test.l1, test.l2)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		assert.NoError(t, err, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
 		if !reflect.DeepEqual(result, test.expect) {
 			t.Fatalf("[%d] Got\n%v expected\n%v", i, result, test.expect)
 		}
@@ -438,7 +443,7 @@
 
 func TestIsSet(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := newTestNs()
 
 	for i, test := range []struct {
@@ -460,7 +465,7 @@
 		{nil, "nil", false, false},
 		{[]interface{}{1, 2, 3, 5}, TstX{}, false, true},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.IsSet(test.a, test.key)
 		if test.isErr {
@@ -467,13 +472,14 @@
 			continue
 		}
 
-		assert.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestLast(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -495,23 +501,23 @@
 		{1, t, false},
 		{1, (*string)(nil), false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.Last(test.limit, test.seq)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.DeepEquals, test.expect, errMsg)
 	}
 }
 
 func TestQuerify(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
@@ -524,23 +530,23 @@
 		{[]interface{}{5, "b"}, false},
 		{[]interface{}{"a", "b", "c"}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.params)
+		errMsg := qt.Commentf("[%d] %v", i, test.params)
 
 		result, err := ns.Querify(test.params...)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestSeq(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
@@ -568,23 +574,23 @@
 		{[]interface{}{tstNoStringer{}}, false},
 		{nil, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.Seq(test.args...)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.DeepEquals, test.expect, errMsg)
 	}
 }
 
 func TestShuffle(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
@@ -604,27 +610,27 @@
 		{t, false},
 		{(*string)(nil), false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.Shuffle(test.seq)
 
 		if !test.success {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
 
 		resultv := reflect.ValueOf(result)
 		seqv := reflect.ValueOf(test.seq)
 
-		assert.Equal(t, resultv.Len(), seqv.Len(), errMsg)
+		c.Assert(seqv.Len(), qt.Equals, resultv.Len(), errMsg)
 	}
 }
 
 func TestShuffleRandomising(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 
 	// Note that this test can fail with false negative result if the shuffle
@@ -641,7 +647,7 @@
 		result, err := ns.Shuffle(test.seq)
 		resultv := reflect.ValueOf(result)
 
-		require.NoError(t, err)
+		c.Assert(err, qt.IsNil)
 
 		allSame := true
 		for i, v := range test.seq {
@@ -648,7 +654,7 @@
 			allSame = allSame && (resultv.Index(i).Interface() == v)
 		}
 
-		assert.False(t, allSame, "Expected sequence to be shuffled but was in the same order")
+		c.Assert(allSame, qt.Equals, false)
 	}
 }
 
@@ -655,7 +661,7 @@
 // Also see tests in commons/collection.
 func TestSlice(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
@@ -668,18 +674,18 @@
 		{[]interface{}{5, "b"}, []interface{}{5, "b"}},
 		{[]interface{}{tstNoStringer{}}, []tstNoStringer{{}}},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.args)
+		errMsg := qt.Commentf("[%d] %v", i, test.args)
 
 		result := ns.Slice(test.args...)
 
-		assert.Equal(t, test.expected, result, errMsg)
+		c.Assert(result, qt.DeepEquals, test.expected, errMsg)
 	}
 
-	assert.Len(t, ns.Slice(), 0)
 }
 
 func TestUnion(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -752,15 +758,15 @@
 		{[][]int{{1, 1}, {1, 2}}, [][]int{{2, 1}, {2, 2}}, false, true},
 	} {
 
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.Union(test.l1, test.l2)
 		if test.isErr {
-			assert.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		assert.NoError(t, err, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
 		if !reflect.DeepEqual(result, test.expect) {
 			t.Fatalf("[%d] Got\n%v expected\n%v", i, result, test.expect)
 		}
@@ -769,7 +775,7 @@
 
 func TestUniq(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 	for i, test := range []struct {
 		l      interface{}
@@ -798,16 +804,16 @@
 		{1, 1, true},
 		{"foo", "fo", true},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.Uniq(test.l)
 		if test.isErr {
-			assert.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		assert.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.DeepEquals, test.expect, errMsg)
 	}
 }
 
--- a/tpl/collections/complement_test.go
+++ b/tpl/collections/complement_test.go
@@ -14,13 +14,12 @@
 package collections
 
 import (
-	"fmt"
 	"reflect"
 	"testing"
 
 	"github.com/gohugoio/hugo/deps"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 type StructWithSlice struct {
@@ -33,7 +32,7 @@
 func TestComplement(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -69,7 +68,7 @@
 		{[]interface{}{[][]string{{"c", "d"}}}, []interface{}{[]string{"c", "d"}, []string{"a", "b"}}, false},
 	} {
 
-		errMsg := fmt.Sprintf("[%d]", i)
+		errMsg := qt.Commentf("[%d]", i)
 
 		args := append(test.t, test.s)
 
@@ -76,11 +75,11 @@
 		result, err := ns.Complement(args...)
 
 		if b, ok := test.expected.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
 
 		if !reflect.DeepEqual(test.expected, result) {
 			t.Fatalf("%s got\n%T: %v\nexpected\n%T: %v", errMsg, result, result, test.expected, test.expected)
@@ -88,8 +87,8 @@
 	}
 
 	_, err := ns.Complement()
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 	_, err = ns.Complement([]string{"a", "b"})
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 }
--- a/tpl/collections/index_test.go
+++ b/tpl/collections/index_test.go
@@ -14,17 +14,15 @@
 package collections
 
 import (
-	"fmt"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 func TestIndex(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 
 	for i, test := range []struct {
@@ -45,16 +43,16 @@
 		{[]int{0, 1}, []interface{}{nil}, nil, true},
 		{tstNoStringer{}, []interface{}{0}, nil, true},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
+		errMsg := qt.Commentf("[%d] %v", i, test)
 
 		result, err := ns.Index(test.item, test.indices...)
 
 		if test.isErr {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.DeepEquals, test.expect, errMsg)
 	}
 }
--- a/tpl/collections/init_test.go
+++ b/tpl/collections/init_test.go
@@ -16,12 +16,15 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +36,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/collections/merge_test.go
+++ b/tpl/collections/merge_test.go
@@ -25,8 +25,8 @@
 
 	"github.com/gohugoio/hugo/parser/metadecoders"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
-	"github.com/stretchr/testify/require"
 )
 
 func TestMerge(t *testing.T) {
@@ -69,9 +69,9 @@
 
 		t.Run(test.name, func(t *testing.T) {
 			t.Parallel()
-			errMsg := fmt.Sprintf("[%d] %v", i, test)
+			errMsg := qt.Commentf("[%d] %v", i, test)
 
-			assert := require.New(t)
+			c := qt.New(t)
 
 			srcStr, dstStr := fmt.Sprint(test.src), fmt.Sprint(test.dst)
 
@@ -78,18 +78,18 @@
 			result, err := ns.Merge(test.src, test.dst)
 
 			if test.isErr {
-				assert.Error(err, errMsg)
+				c.Assert(err, qt.Not(qt.IsNil), errMsg)
 				return
 			}
 
-			assert.NoError(err, errMsg)
-			assert.Equal(test.expect, result, errMsg)
+			c.Assert(err, qt.IsNil)
+			c.Assert(result, qt.DeepEquals, test.expect, errMsg)
 
 			// map sort in fmt was fixed in go 1.12.
 			if !strings.HasPrefix(runtime.Version(), "go1.11") {
 				// Verify that the original maps are preserved.
-				assert.Equal(srcStr, fmt.Sprint(test.src))
-				assert.Equal(dstStr, fmt.Sprint(test.dst))
+				c.Assert(fmt.Sprint(test.src), qt.Equals, srcStr)
+				c.Assert(fmt.Sprint(test.dst), qt.Equals, dstStr)
 			}
 
 		})
@@ -97,7 +97,7 @@
 }
 
 func TestMergeDataFormats(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	ns := New(&deps.Deps{})
 
 	toml1 := `
@@ -119,33 +119,38 @@
 `
 
 	meta1, err := metadecoders.Default.UnmarshalToMap([]byte(toml1), metadecoders.TOML)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 	meta2, err := metadecoders.Default.UnmarshalToMap([]byte(toml2), metadecoders.TOML)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	for _, format := range []metadecoders.Format{metadecoders.JSON, metadecoders.YAML, metadecoders.TOML} {
 
 		var dataStr1, dataStr2 bytes.Buffer
 		err = parser.InterfaceToConfig(meta1, format, &dataStr1)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		err = parser.InterfaceToConfig(meta2, format, &dataStr2)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		dst, err := metadecoders.Default.UnmarshalToMap(dataStr1.Bytes(), format)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 		src, err := metadecoders.Default.UnmarshalToMap(dataStr2.Bytes(), format)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		merged, err := ns.Merge(src, dst)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
-		assert.Equal(map[string]interface{}{"V1": "v1_1", "V2": "v2_2", "V2s": map[string]interface{}{"V21": "v21_1", "V22": "v22_2"}}, merged)
+		c.Assert(
+			merged,
+			qt.DeepEquals,
+			map[string]interface{}{
+				"V1": "v1_1", "V2": "v2_2",
+				"V2s": map[string]interface{}{"V21": "v21_1", "V22": "v22_2"}})
 	}
 
 }
 
 func TestCaseInsensitiveMapLookup(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	m1 := reflect.ValueOf(map[string]interface{}{
 		"a": 1,
@@ -160,14 +165,14 @@
 	var found bool
 
 	a, found := caseInsensitiveLookup(m1, reflect.ValueOf("A"))
-	assert.True(found)
-	assert.Equal(1, a.Interface())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(a.Interface(), qt.Equals, 1)
 
 	b, found := caseInsensitiveLookup(m1, reflect.ValueOf("b"))
-	assert.True(found)
-	assert.Equal(2, b.Interface())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(b.Interface(), qt.Equals, 2)
 
 	two, found := caseInsensitiveLookup(m2, reflect.ValueOf(2))
-	assert.True(found)
-	assert.Equal(2, two.Interface())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(two.Interface(), qt.Equals, 2)
 }
--- a/tpl/collections/symdiff_test.go
+++ b/tpl/collections/symdiff_test.go
@@ -14,19 +14,18 @@
 package collections
 
 import (
-	"fmt"
 	"reflect"
 	"testing"
 
 	"github.com/gohugoio/hugo/deps"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestSymDiff(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -56,16 +55,16 @@
 		{[]int{1, 2, 3}, []string{"3", "4"}, false},
 	} {
 
-		errMsg := fmt.Sprintf("[%d]", i)
+		errMsg := qt.Commentf("[%d]", i)
 
 		result, err := ns.SymDiff(test.s2, test.s1)
 
 		if b, ok := test.expected.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
 
 		if !reflect.DeepEqual(test.expected, result) {
 			t.Fatalf("%s got\n%T: %v\nexpected\n%T: %v", errMsg, result, result, test.expected, test.expected)
@@ -73,8 +72,8 @@
 	}
 
 	_, err := ns.Complement()
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 	_, err = ns.Complement([]string{"a", "b"})
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 }
--- a/tpl/compare/compare_test.go
+++ b/tpl/compare/compare_test.go
@@ -14,7 +14,6 @@
 package compare
 
 import (
-	"fmt"
 	"path"
 	"reflect"
 	"runtime"
@@ -21,10 +20,11 @@
 	"testing"
 	"time"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/hugo"
 	"github.com/spf13/cast"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 type T struct {
@@ -80,6 +80,7 @@
 
 func TestDefaultFunc(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	then := time.Now()
 	now := time.Now()
@@ -127,12 +128,15 @@
 		{then, now, now},
 		{then, time.Time{}, then},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
+		eq := qt.CmpEquals(hqt.DeepAllowUnexported(test.dflt))
+
+		errMsg := qt.Commentf("[%d] %v", i, test)
+
 		result, err := ns.Default(test.dflt, test.given)
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, result, test.expect, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, eq, test.expect, errMsg)
 	}
 }
 
@@ -234,11 +238,11 @@
 }
 
 func TestCase(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	n := New(true)
 
-	assert.True(n.Lt("az", "Za"))
-	assert.True(n.Gt("ab", "Ab"))
+	c.Assert(n.Lt("az", "Za"), qt.Equals, true)
+	c.Assert(n.Gt("ab", "Ab"), qt.Equals, true)
 }
 
 func TestTimeUnix(t *testing.T) {
@@ -265,10 +269,10 @@
 }
 
 func TestConditional(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 	n := New(false)
 	a, b := "a", "b"
 
-	assert.Equal(a, n.Conditional(true, a, b))
-	assert.Equal(b, n.Conditional(false, a, b))
+	c.Assert(n.Conditional(true, a, b), qt.Equals, a)
+	c.Assert(n.Conditional(false, a, b), qt.Equals, b)
 }
--- a/tpl/compare/init_test.go
+++ b/tpl/compare/init_test.go
@@ -16,12 +16,14 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +35,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/compare/truth_test.go
+++ b/tpl/compare/truth_test.go
@@ -18,8 +18,8 @@
 	"testing"
 	"time"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/hreflect"
-	"github.com/stretchr/testify/require"
 )
 
 func TestTruth(t *testing.T) {
@@ -46,15 +46,15 @@
 	})
 
 	t.Run("Not", func(t *testing.T) {
-		assert := require.New(t)
-		assert.True(n.Not(falsev))
-		assert.False(n.Not(truthv))
+		c := qt.New(t)
+		c.Assert(n.Not(falsev), qt.Equals, true)
+		c.Assert(n.Not(truthv), qt.Equals, false)
 	})
 
 	t.Run("getIf", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		assertTruth(t, n.getIf(reflect.ValueOf(nil)), false)
 		s := reflect.ValueOf("Hugo")
-		assert.Equal(s, n.getIf(s))
+		c.Assert(n.getIf(s), qt.Equals, s)
 	})
 }
--- a/tpl/crypto/crypto_test.go
+++ b/tpl/crypto/crypto_test.go
@@ -14,15 +14,14 @@
 package crypto
 
 import (
-	"fmt"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestMD5(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
@@ -34,23 +33,23 @@
 		{"Lorem ipsum dolor", "06ce65ac476fc656bea3fca5d02cfd81"},
 		{t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.in)
+		errMsg := qt.Commentf("[%d] %v", i, test.in)
 
 		result, err := ns.MD5(test.in)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestSHA1(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New()
 
 	for i, test := range []struct {
@@ -61,23 +60,23 @@
 		{"Lorem ipsum dolor", "45f75b844be4d17b3394c6701768daf39419c99b"},
 		{t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.in)
+		errMsg := qt.Commentf("[%d] %v", i, test.in)
 
 		result, err := ns.SHA1(test.in)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
 
 func TestSHA256(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New()
 
 	for i, test := range []struct {
@@ -88,16 +87,16 @@
 		{"Lorem ipsum dolor", "9b3e1beb7053e0f900a674dd1c99aca3355e1275e1b03d3cb1bc977f5154e196"},
 		{t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.in)
+		errMsg := qt.Commentf("[%d] %v", i, test.in)
 
 		result, err := ns.SHA256(test.in)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil), errMsg)
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil, errMsg)
+		c.Assert(result, qt.Equals, test.expect, errMsg)
 	}
 }
--- a/tpl/crypto/init_test.go
+++ b/tpl/crypto/init_test.go
@@ -16,12 +16,14 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +35,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/data/data_test.go
+++ b/tpl/data/data_test.go
@@ -14,7 +14,6 @@
 package data
 
 import (
-	"fmt"
 	"net/http"
 	"net/http/httptest"
 	"path/filepath"
@@ -21,12 +20,12 @@
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestGetCSV(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	for i, test := range []struct {
 		sep     string
@@ -74,7 +73,7 @@
 			false,
 		},
 	} {
-		msg := fmt.Sprintf("Test %d", i)
+		msg := qt.Commentf("Test %d", i)
 
 		ns := newTestNs()
 
@@ -100,7 +99,7 @@
 		// Setup local test file for schema-less URLs
 		if !strings.Contains(test.url, ":") && !strings.HasPrefix(test.url, "fail/") {
 			f, err := ns.deps.Fs.Source.Create(filepath.Join(ns.deps.Cfg.GetString("workingDir"), test.url))
-			require.NoError(t, err, msg)
+			c.Assert(err, qt.IsNil, msg)
 			f.WriteString(test.content)
 			f.Close()
 		}
@@ -109,22 +108,23 @@
 		got, err := ns.GetCSV(test.sep, test.url)
 
 		if _, ok := test.expect.(bool); ok {
-			require.Equal(t, 1, int(ns.deps.Log.ErrorCounter.Count()))
-			//require.Error(t, err, msg)
-			require.Nil(t, got)
+			c.Assert(int(ns.deps.Log.ErrorCounter.Count()), qt.Equals, 1)
+			//c.Assert(err, msg, qt.Not(qt.IsNil))
+			c.Assert(got, qt.IsNil)
 			continue
 		}
 
-		require.NoError(t, err, msg)
-		require.Equal(t, 0, int(ns.deps.Log.ErrorCounter.Count()))
-		require.NotNil(t, got, msg)
+		c.Assert(err, qt.IsNil, msg)
+		c.Assert(int(ns.deps.Log.ErrorCounter.Count()), qt.Equals, 0)
+		c.Assert(got, qt.Not(qt.IsNil), msg)
+		c.Assert(got, qt.DeepEquals, test.expect, msg)
 
-		assert.EqualValues(t, test.expect, got, msg)
 	}
 }
 
 func TestGetJSON(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	for i, test := range []struct {
 		url     string
@@ -159,7 +159,7 @@
 		},
 	} {
 
-		msg := fmt.Sprintf("Test %d", i)
+		msg := qt.Commentf("Test %d", i)
 		ns := newTestNs()
 
 		// Setup HTTP test server
@@ -184,7 +184,7 @@
 		// Setup local test file for schema-less URLs
 		if !strings.Contains(test.url, ":") && !strings.HasPrefix(test.url, "fail/") {
 			f, err := ns.deps.Fs.Source.Create(filepath.Join(ns.deps.Cfg.GetString("workingDir"), test.url))
-			require.NoError(t, err, msg)
+			c.Assert(err, qt.IsNil, msg)
 			f.WriteString(test.content)
 			f.Close()
 		}
@@ -193,20 +193,20 @@
 		got, _ := ns.GetJSON(test.url)
 
 		if _, ok := test.expect.(bool); ok {
-			require.Equal(t, 1, int(ns.deps.Log.ErrorCounter.Count()))
-			//require.Error(t, err, msg)
+			c.Assert(int(ns.deps.Log.ErrorCounter.Count()), qt.Equals, 1)
+			//c.Assert(err, msg, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.Equal(t, 0, int(ns.deps.Log.ErrorCounter.Count()), msg)
-		require.NotNil(t, got, msg)
-
-		assert.EqualValues(t, test.expect, got, msg)
+		c.Assert(int(ns.deps.Log.ErrorCounter.Count()), qt.Equals, 0, msg)
+		c.Assert(got, qt.Not(qt.IsNil), msg)
+		c.Assert(got, qt.DeepEquals, test.expect)
 	}
 }
 
 func TestParseCSV(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	for i, test := range []struct {
 		csv []byte
@@ -221,14 +221,14 @@
 		{[]byte("a|b|c\nd|e|f|g"), "|", "abcdefg", true},
 		{[]byte("z|y|c\nd|e|f"), "|", "zycdef", false},
 	} {
-		msg := fmt.Sprintf("Test %d: %v", i, test)
+		msg := qt.Commentf("Test %d: %v", i, test)
 
 		csv, err := parseCSV(test.csv, test.sep)
 		if test.err {
-			assert.Error(t, err, msg)
+			c.Assert(err, qt.Not(qt.IsNil), msg)
 			continue
 		}
-		require.NoError(t, err, msg)
+		c.Assert(err, qt.IsNil, msg)
 
 		act := ""
 		for _, v := range csv {
@@ -235,7 +235,7 @@
 			act = act + strings.Join(v, "")
 		}
 
-		assert.Equal(t, test.exp, act, msg)
+		c.Assert(act, qt.Equals, test.exp, msg)
 	}
 }
 
--- a/tpl/data/init_test.go
+++ b/tpl/data/init_test.go
@@ -16,13 +16,15 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/langs"
 	"github.com/gohugoio/hugo/tpl/internal"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -38,6 +40,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/data/resources_test.go
+++ b/tpl/data/resources_test.go
@@ -15,7 +15,6 @@
 
 import (
 	"bytes"
-	"fmt"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
@@ -27,6 +26,7 @@
 
 	"github.com/gohugoio/hugo/helpers"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/cache/filecache"
 	"github.com/gohugoio/hugo/common/loggers"
 	"github.com/gohugoio/hugo/config"
@@ -35,8 +35,6 @@
 	"github.com/gohugoio/hugo/langs"
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 func TestScpGetLocal(t *testing.T) {
@@ -88,6 +86,7 @@
 
 func TestScpGetRemote(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 	fs := new(afero.MemMapFs)
 	cache := filecache.NewCache(fs, 100, "")
 
@@ -102,10 +101,10 @@
 	}
 
 	for _, test := range tests {
-		msg := fmt.Sprintf("%v", test)
+		msg := qt.Commentf("%v", test)
 
 		req, err := http.NewRequest("GET", test.path, nil)
-		require.NoError(t, err, msg)
+		c.Assert(err, qt.IsNil, msg)
 
 		srv, cl := getTestServer(func(w http.ResponseWriter, r *http.Request) {
 			w.Write(test.content)
@@ -115,17 +114,17 @@
 		ns := newTestNs()
 		ns.client = cl
 
-		var c []byte
+		var cb []byte
 		f := func(b []byte) (bool, error) {
-			c = b
+			cb = b
 			return false, nil
 		}
 
 		err = ns.getRemote(cache, f, req)
-		require.NoError(t, err, msg)
-		assert.Equal(t, string(test.content), string(c))
+		c.Assert(err, qt.IsNil, msg)
+		c.Assert(string(cb), qt.Equals, string(test.content))
 
-		assert.Equal(t, string(test.content), string(c))
+		c.Assert(string(cb), qt.Equals, string(test.content))
 
 	}
 }
@@ -132,6 +131,7 @@
 
 func TestScpGetRemoteParallel(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	content := []byte(`T€st Content 123`)
 	srv, cl := getTestServer(func(w http.ResponseWriter, r *http.Request) {
@@ -142,7 +142,7 @@
 
 	url := "http://Foo.Bar/foo_Bar-Foo"
 	req, err := http.NewRequest("GET", url, nil)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	for _, ignoreCache := range []bool{false} {
 		cfg := viper.New()
@@ -159,16 +159,16 @@
 			go func(gor int) {
 				defer wg.Done()
 				for j := 0; j < 10; j++ {
-					var c []byte
+					var cb []byte
 					f := func(b []byte) (bool, error) {
-						c = b
+						cb = b
 						return false, nil
 					}
 					err := ns.getRemote(ns.cacheGetJSON, f, req)
 
-					assert.NoError(t, err)
-					if string(content) != string(c) {
-						t.Errorf("expected\n%q\ngot\n%q", content, c)
+					c.Assert(err, qt.IsNil)
+					if string(content) != string(cb) {
+						t.Errorf("expected\n%q\ngot\n%q", content, cb)
 					}
 
 					time.Sleep(23 * time.Millisecond)
--- a/tpl/encoding/encoding_test.go
+++ b/tpl/encoding/encoding_test.go
@@ -14,13 +14,11 @@
 package encoding
 
 import (
-	"fmt"
 	"html/template"
 	"math"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 type tstNoStringer struct{}
@@ -27,10 +25,11 @@
 
 func TestBase64Decode(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		v      interface{}
 		expect interface{}
 	}{
@@ -38,26 +37,26 @@
 		// errors
 		{t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.v)
 
 		result, err := ns.Base64Decode(test.v)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestBase64Encode(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		v      interface{}
 		expect interface{}
 	}{
@@ -65,26 +64,25 @@
 		// errors
 		{t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.v)
 
 		result, err := ns.Base64Encode(test.v)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestJsonify(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		v      interface{}
 		expect interface{}
 	}{
@@ -94,16 +92,15 @@
 		// errors
 		{math.NaN(), false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.v)
 
 		result, err := ns.Jsonify(test.v)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
--- a/tpl/encoding/init_test.go
+++ b/tpl/encoding/init_test.go
@@ -16,12 +16,14 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +35,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/fmt/init_test.go
+++ b/tpl/fmt/init_test.go
@@ -16,13 +16,16 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/loggers"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -34,6 +37,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/hugo/init_test.go
+++ b/tpl/hugo/init_test.go
@@ -16,14 +16,17 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/resources/page"
 	"github.com/gohugoio/hugo/tpl/internal"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 	v := viper.New()
@@ -38,6 +41,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, s.Hugo(), ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, s.Hugo())
 }
--- a/tpl/images/images_test.go
+++ b/tpl/images/images_test.go
@@ -15,7 +15,6 @@
 
 import (
 	"bytes"
-	"fmt"
 	"image"
 	"image/color"
 	"image/png"
@@ -22,13 +21,12 @@
 	"path/filepath"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/afero"
 	"github.com/spf13/cast"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 type tstNoStringer struct{}
@@ -82,6 +80,7 @@
 
 func TestNSConfig(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	v := viper.New()
 	v.Set("workingDir", "/a/b")
@@ -88,26 +87,25 @@
 
 	ns := New(&deps.Deps{Fs: hugofs.NewMem(v)})
 
-	for i, test := range configTests {
-		errMsg := fmt.Sprintf("[%d] %s", i, test.path)
+	for _, test := range configTests {
 
 		// check for expected errors early to avoid writing files
 		if b, ok := test.expect.(bool); ok && !b {
 			_, err := ns.Config(test.path)
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
 		// cast path to string for afero.WriteFile
 		sp, err := cast.ToStringE(test.path)
-		require.NoError(t, err, errMsg)
+		c.Assert(err, qt.IsNil)
 		afero.WriteFile(ns.deps.Fs.Source, filepath.Join(v.GetString("workingDir"), sp), test.input, 0755)
 
 		result, err := ns.Config(test.path)
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
-		assert.NotEqual(t, 0, len(ns.cache), errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
+		c.Assert(len(ns.cache), qt.Not(qt.Equals), 0)
 	}
 }
 
--- a/tpl/images/init_test.go
+++ b/tpl/images/init_test.go
@@ -16,12 +16,14 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +35,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/inflect/inflect_test.go
+++ b/tpl/inflect/inflect_test.go
@@ -1,19 +1,18 @@
 package inflect
 
 import (
-	"fmt"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestInflect(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		fn     func(i interface{}) (string, error)
 		in     interface{}
 		expect interface{}
@@ -34,16 +33,15 @@
 		{ns.Singularize, "", ""},
 		{ns.Singularize, t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := test.fn(test.in)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
--- a/tpl/inflect/init_test.go
+++ b/tpl/inflect/init_test.go
@@ -16,12 +16,15 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +36,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/internal/templatefuncRegistry_test.go
+++ b/tpl/internal/templatefuncRegistry_test.go
@@ -17,7 +17,7 @@
 	"runtime"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 type Test struct {
@@ -28,11 +28,12 @@
 }
 
 func TestMethodToName(t *testing.T) {
+	c := qt.New(t)
 	test := &Test{}
 
 	if runtime.Compiler == "gccgo" {
-		require.Contains(t, methodToName(test.MyTestMethod), "thunk")
+		c.Assert(methodToName(test.MyTestMethod), qt.Contains, "thunk")
 	} else {
-		require.Equal(t, "MyTestMethod", methodToName(test.MyTestMethod))
+		c.Assert(methodToName(test.MyTestMethod), qt.Equals, "MyTestMethod")
 	}
 }
--- a/tpl/lang/init_test.go
+++ b/tpl/lang/init_test.go
@@ -16,12 +16,15 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +36,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/lang/lang_test.go
+++ b/tpl/lang/lang_test.go
@@ -1,16 +1,15 @@
 package lang
 
 import (
-	"fmt"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 func TestNumFormat(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New(&deps.Deps{})
 
@@ -41,23 +40,21 @@
 		{6, -12345.6789, "‏-|٫| ", "|", "‏-12 345٫678900"},
 	}
 
-	for i, c := range cases {
-		errMsg := fmt.Sprintf("[%d] %v", i, c)
-
+	for _, cas := range cases {
 		var s string
 		var err error
 
-		if len(c.runes) == 0 {
-			s, err = ns.NumFmt(c.prec, c.n)
+		if len(cas.runes) == 0 {
+			s, err = ns.NumFmt(cas.prec, cas.n)
 		} else {
-			if c.delim == "" {
-				s, err = ns.NumFmt(c.prec, c.n, c.runes)
+			if cas.delim == "" {
+				s, err = ns.NumFmt(cas.prec, cas.n, cas.runes)
 			} else {
-				s, err = ns.NumFmt(c.prec, c.n, c.runes, c.delim)
+				s, err = ns.NumFmt(cas.prec, cas.n, cas.runes, cas.delim)
 			}
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, c.want, s, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(s, qt.Equals, cas.want)
 	}
 }
--- a/tpl/math/init_test.go
+++ b/tpl/math/init_test.go
@@ -16,12 +16,14 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +35,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/math/math_test.go
+++ b/tpl/math/math_test.go
@@ -14,20 +14,19 @@
 package math
 
 import (
-	"fmt"
 	"math"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestBasicNSArithmetic(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		fn     func(a, b interface{}) (interface{}, error)
 		a      interface{}
 		b      interface{}
@@ -42,26 +41,25 @@
 		{ns.Div, 4, 2, int64(2)},
 		{ns.Div, 1.0, "foo", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := test.fn(test.a, test.b)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestCeil(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		x      interface{}
 		expect interface{}
 	}{
@@ -75,26 +73,26 @@
 		{-1.5, -1.0},
 		{"abc", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Ceil(test.x)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestFloor(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		x      interface{}
 		expect interface{}
 	}{
@@ -108,26 +106,26 @@
 		{-1.5, -2.0},
 		{"abc", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Floor(test.x)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestLog(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		expect interface{}
 	}{
@@ -138,12 +136,11 @@
 		{3.1, float64(1.1314)},
 		{"abc", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Log(test.a)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
@@ -153,17 +150,18 @@
 			result = float64(int(result*10000)) / 10000
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestMod(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		b      interface{}
 		expect interface{}
@@ -184,26 +182,26 @@
 		{"aaa", "0", false},
 		{"3", "aaa", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Mod(test.a, test.b)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestModBool(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		b      interface{}
 		expect interface{}
@@ -230,26 +228,26 @@
 		{"aaa", "0", nil},
 		{"3", "aaa", nil},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.ModBool(test.a, test.b)
 
 		if test.expect == nil {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestRound(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		x      interface{}
 		expect interface{}
 	}{
@@ -263,16 +261,15 @@
 		{-1.5, -2.0},
 		{"abc", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Round(test.x)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
--- a/tpl/os/init_test.go
+++ b/tpl/os/init_test.go
@@ -16,12 +16,14 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +35,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/os/os_test.go
+++ b/tpl/os/os_test.go
@@ -14,20 +14,19 @@
 package os
 
 import (
-	"fmt"
 	"path/filepath"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 func TestReadFile(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	workingDir := "/home/hugo"
 
@@ -40,7 +39,7 @@
 	afero.WriteFile(ns.deps.Fs.Source, filepath.Join(workingDir, "/f/f1.txt"), []byte("f1-content"), 0755)
 	afero.WriteFile(ns.deps.Fs.Source, filepath.Join("/home", "f2.txt"), []byte("f2-content"), 0755)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		filename string
 		expect   interface{}
 	}{
@@ -50,22 +49,22 @@
 		{"", false},
 		{"b", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.ReadFile(test.filename)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestFileExists(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	workingDir := "/home/hugo"
 
@@ -77,7 +76,7 @@
 	afero.WriteFile(ns.deps.Fs.Source, filepath.Join(workingDir, "/f/f1.txt"), []byte("f1-content"), 0755)
 	afero.WriteFile(ns.deps.Fs.Source, filepath.Join("/home", "f2.txt"), []byte("f2-content"), 0755)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		filename string
 		expect   interface{}
 	}{
@@ -87,22 +86,21 @@
 		{"b", false},
 		{"", nil},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 		result, err := ns.FileExists(test.filename)
 
 		if test.expect == nil {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestStat(t *testing.T) {
 	t.Parallel()
-
+	c := qt.New(t)
 	workingDir := "/home/hugo"
 
 	v := viper.New()
@@ -112,7 +110,7 @@
 
 	afero.WriteFile(ns.deps.Fs.Source, filepath.Join(workingDir, "/f/f1.txt"), []byte("f1-content"), 0755)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		filename string
 		expect   interface{}
 	}{
@@ -121,15 +119,14 @@
 		{"b", nil},
 		{"", nil},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 		result, err := ns.Stat(test.filename)
 
 		if test.expect == nil {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result.Size(), errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result.Size(), qt.Equals, test.expect)
 	}
 }
--- a/tpl/partials/init_test.go
+++ b/tpl/partials/init_test.go
@@ -16,13 +16,15 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/loggers"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -37,6 +39,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/path/init_test.go
+++ b/tpl/path/init_test.go
@@ -16,12 +16,15 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +36,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/path/path_test.go
+++ b/tpl/path/path_test.go
@@ -14,14 +14,12 @@
 package path
 
 import (
-	"fmt"
 	"path/filepath"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 var ns = New(&deps.Deps{Cfg: viper.New()})
@@ -30,8 +28,9 @@
 
 func TestBase(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		path   interface{}
 		expect interface{}
 	}{
@@ -44,24 +43,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Base(test.path)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestDir(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		path   interface{}
 		expect interface{}
 	}{
@@ -74,24 +73,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Dir(test.path)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestExt(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		path   interface{}
 		expect interface{}
 	}{
@@ -102,24 +101,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Ext(test.path)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestJoin(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		elements interface{}
 		expect   interface{}
 	}{
@@ -136,24 +135,24 @@
 		{tstNoStringer{}, false},
 		{[]interface{}{"", tstNoStringer{}}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Join(test.elements)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestSplit(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		path   interface{}
 		expect interface{}
 	}{
@@ -164,16 +163,15 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Split(test.path)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
--- a/tpl/reflect/init_test.go
+++ b/tpl/reflect/init_test.go
@@ -16,13 +16,15 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/loggers"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -34,6 +36,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/reflect/reflect_test.go
+++ b/tpl/reflect/reflect_test.go
@@ -14,10 +14,9 @@
 package reflect
 
 import (
-	"fmt"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
+	qt "github.com/frankban/quicktest"
 )
 
 var ns = New()
@@ -25,7 +24,8 @@
 type tstNoStringer struct{}
 
 func TestIsMap(t *testing.T) {
-	for i, test := range []struct {
+	c := qt.New(t)
+	for _, test := range []struct {
 		v      interface{}
 		expect interface{}
 	}{
@@ -33,14 +33,14 @@
 		{"foo", false},
 		{nil, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 		result := ns.IsMap(test.v)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestIsSlice(t *testing.T) {
-	for i, test := range []struct {
+	c := qt.New(t)
+	for _, test := range []struct {
 		v      interface{}
 		expect interface{}
 	}{
@@ -48,8 +48,7 @@
 		{"foo", false},
 		{nil, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 		result := ns.IsSlice(test.v)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
--- a/tpl/safe/init_test.go
+++ b/tpl/safe/init_test.go
@@ -16,12 +16,15 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
+
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +36,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/safe/safe_test.go
+++ b/tpl/safe/safe_test.go
@@ -14,12 +14,10 @@
 package safe
 
 import (
-	"fmt"
 	"html/template"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 type tstNoStringer struct{}
@@ -26,10 +24,11 @@
 
 func TestCSS(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		expect interface{}
 	}{
@@ -37,26 +36,26 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.CSS(test.a)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestHTML(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		expect interface{}
 	}{
@@ -64,26 +63,26 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.HTML(test.a)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestHTMLAttr(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		expect interface{}
 	}{
@@ -91,26 +90,25 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
-
 		result, err := ns.HTMLAttr(test.a)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestJS(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		expect interface{}
 	}{
@@ -118,26 +116,26 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.JS(test.a)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestJSStr(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		expect interface{}
 	}{
@@ -145,26 +143,26 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.JSStr(test.a)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestURL(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		expect interface{}
 	}{
@@ -172,26 +170,26 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.URL(test.a)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestSanitizeURL(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	ns := New()
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		a      interface{}
 		expect interface{}
 	}{
@@ -199,16 +197,15 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.SanitizeURL(test.a)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
--- a/tpl/site/init_test.go
+++ b/tpl/site/init_test.go
@@ -16,15 +16,17 @@
 import (
 	"testing"
 
-	"github.com/spf13/viper"
-
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/resources/page"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
+	"github.com/spf13/viper"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
+
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 	v := viper.New()
@@ -39,6 +41,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, s, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, s)
 }
--- a/tpl/strings/init_test.go
+++ b/tpl/strings/init_test.go
@@ -16,13 +16,16 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl/internal"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -34,6 +37,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/strings/regexp_test.go
+++ b/tpl/strings/regexp_test.go
@@ -14,17 +14,16 @@
 package strings
 
 import (
-	"fmt"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestFindRE(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		expr    string
 		content interface{}
 		limit   interface{}
@@ -39,24 +38,23 @@
 		{"[G|go", "Hugo is a static site generator written in Go.", nil, false},
 		{"[G|g]o", t, nil, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
-
 		result, err := ns.FindRE(test.expr, test.content, test.limit)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.DeepEquals, test.expect)
 	}
 }
 
 func TestReplaceRE(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		pattern interface{}
 		repl    interface{}
 		s       interface{}
@@ -71,16 +69,15 @@
 		{"^https?://([^/]+).*", tstNoStringer{}, "http://gohugo.io/docs", false},
 		{"^https?://([^/]+).*", "$2", tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.ReplaceRE(test.pattern, test.repl, test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
--- a/tpl/strings/strings_test.go
+++ b/tpl/strings/strings_test.go
@@ -14,15 +14,13 @@
 package strings
 
 import (
-	"fmt"
 	"html/template"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/spf13/cast"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 var ns = New(&deps.Deps{Cfg: viper.New()})
@@ -31,8 +29,9 @@
 
 func TestChomp(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -45,29 +44,29 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Chomp(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 
 		// repeat the check with template.HTML input
 		result, err = ns.Chomp(template.HTML(cast.ToString(test.s)))
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, template.HTML(cast.ToString(test.expect)), result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, template.HTML(cast.ToString(test.expect)))
 	}
 }
 
 func TestContains(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		substr interface{}
 		expect bool
@@ -88,24 +87,24 @@
 		{"", tstNoStringer{}, false, true},
 		{tstNoStringer{}, "", false, true},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Contains(test.s, test.substr)
 
 		if test.isErr {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestContainsAny(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		substr interface{}
 		expect bool
@@ -132,24 +131,24 @@
 		{"", tstNoStringer{}, false, true},
 		{tstNoStringer{}, "", false, true},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.ContainsAny(test.s, test.substr)
 
 		if test.isErr {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestCountRunes(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -159,24 +158,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.s)
 
 		result, err := ns.CountRunes(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestRuneCount(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -186,24 +185,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.s)
 
 		result, err := ns.RuneCount(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestCountWords(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -213,24 +212,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test.s)
 
 		result, err := ns.CountWords(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestHasPrefix(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		prefix interface{}
 		expect interface{}
@@ -247,24 +246,24 @@
 		{"", tstNoStringer{}, false, true},
 		{tstNoStringer{}, "", false, true},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.HasPrefix(test.s, test.prefix)
 
 		if test.isErr {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestHasSuffix(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		suffix interface{}
 		expect interface{}
@@ -281,24 +280,24 @@
 		{"", tstNoStringer{}, false, true},
 		{tstNoStringer{}, "", false, true},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.HasSuffix(test.s, test.suffix)
 
 		if test.isErr {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestReplace(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		old    interface{}
 		new    interface{}
@@ -312,25 +311,25 @@
 		{"a", tstNoStringer{}, "b", false},
 		{"a", "b", tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Replace(test.s, test.old, test.new)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestSliceString(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	var err error
-	for i, test := range []struct {
+	for _, test := range []struct {
 		v1     interface{}
 		v2     interface{}
 		v3     interface{}
@@ -362,7 +361,6 @@
 		{"a", t, nil, false},
 		{"a", 1, t, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		var result string
 		if test.v2 == nil {
@@ -374,12 +372,12 @@
 		}
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 
 	// Too many arguments
@@ -391,8 +389,9 @@
 
 func TestSplit(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		v1     interface{}
 		v2     string
 		expect interface{}
@@ -403,26 +402,25 @@
 		{123, "2", []string{"1", "3"}},
 		{tstNoStringer{}, ",", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Split(test.v1, test.v2)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.DeepEquals, test.expect)
 	}
 }
 
 func TestSubstr(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	var err error
-	var n int
-	for i, test := range []struct {
+	for _, test := range []struct {
 		v1     interface{}
 		v2     interface{}
 		v3     interface{}
@@ -459,10 +457,8 @@
 		{"abcdef", "doo", "doo", false},
 		{"abcdef", 1, "doo", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		var result string
-		n = i
 
 		if test.v3 == nil {
 			result, err = ns.Substr(test.v1, test.v2)
@@ -471,31 +467,26 @@
 		}
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 
-	n++
 	_, err = ns.Substr("abcdef")
-	if err == nil {
-		t.Errorf("[%d] Substr didn't return an expected error", n)
-	}
+	c.Assert(err, qt.Not(qt.IsNil))
 
-	n++
 	_, err = ns.Substr("abcdef", 1, 2, 3)
-	if err == nil {
-		t.Errorf("[%d] Substr didn't return an expected error", n)
-	}
+	c.Assert(err, qt.Not(qt.IsNil))
 }
 
 func TestTitle(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -505,24 +496,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Title(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestToLower(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -532,24 +523,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.ToLower(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestToUpper(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -559,24 +550,24 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.ToUpper(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestTrim(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		cutset interface{}
 		expect interface{}
@@ -593,24 +584,24 @@
 		{"", tstNoStringer{}, false},
 		{tstNoStringer{}, "", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Trim(test.s, test.cutset)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestTrimLeft(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		cutset interface{}
 		expect interface{}
@@ -628,24 +619,24 @@
 		{"", tstNoStringer{}, false},
 		{tstNoStringer{}, "", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.TrimLeft(test.cutset, test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestTrimPrefix(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		prefix interface{}
 		expect interface{}
@@ -658,24 +649,24 @@
 		{"", tstNoStringer{}, false},
 		{tstNoStringer{}, "", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.TrimPrefix(test.prefix, test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestTrimRight(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		cutset interface{}
 		expect interface{}
@@ -693,24 +684,24 @@
 		{"", tstNoStringer{}, false},
 		{tstNoStringer{}, "", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.TrimRight(test.cutset, test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestTrimSuffix(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		suffix interface{}
 		expect interface{}
@@ -723,24 +714,24 @@
 		{"", tstNoStringer{}, false},
 		{tstNoStringer{}, "", false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.TrimSuffix(test.suffix, test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestRepeat(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		n      interface{}
 		expect interface{}
@@ -758,16 +749,15 @@
 		{tstNoStringer{}, "", false},
 		{"ab", -1, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Repeat(test.n, test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
--- a/tpl/template_test.go
+++ b/tpl/template_test.go
@@ -16,16 +16,16 @@
 import (
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestExtractBaseof(t *testing.T) {
-	assert := require.New(t)
+	c := qt.New(t)
 
 	replaced := extractBaseOf(`failed: template: _default/baseof.html:37:11: executing "_default/baseof.html" at <.Parents>: can't evaluate field Parents in type *hugolib.PageOutput`)
 
-	assert.Equal("_default/baseof.html", replaced)
-	assert.Equal("", extractBaseOf("not baseof for you"))
-	assert.Equal("blog/baseof.html", extractBaseOf("template: blog/baseof.html:23:11:"))
-	assert.Equal("blog/baseof.ace", extractBaseOf("template: blog/baseof.ace:23:11:"))
+	c.Assert(replaced, qt.Equals, "_default/baseof.html")
+	c.Assert(extractBaseOf("not baseof for you"), qt.Equals, "")
+	c.Assert(extractBaseOf("template: blog/baseof.html:23:11:"), qt.Equals, "blog/baseof.html")
+	c.Assert(extractBaseOf("template: blog/baseof.ace:23:11:"), qt.Equals, "blog/baseof.ace")
 }
--- a/tpl/templates/init_test.go
+++ b/tpl/templates/init_test.go
@@ -16,12 +16,14 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +35,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/time/init_test.go
+++ b/tpl/time/init_test.go
@@ -16,12 +16,15 @@
 import (
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +36,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/tplimpl/shortcodes_test.go
+++ b/tpl/tplimpl/shortcodes_test.go
@@ -14,38 +14,37 @@
 package tplimpl
 
 import (
-	"fmt"
 	"testing"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestShortcodesTemplate(t *testing.T) {
 
 	t.Run("isShortcode", func(t *testing.T) {
-		assert := require.New(t)
-		assert.True(isShortcode("shortcodes/figures.html"))
-		assert.True(isShortcode("_internal/shortcodes/figures.html"))
-		assert.False(isShortcode("shortcodes\\figures.html"))
-		assert.False(isShortcode("myshortcodes"))
+		c := qt.New(t)
+		c.Assert(isShortcode("shortcodes/figures.html"), qt.Equals, true)
+		c.Assert(isShortcode("_internal/shortcodes/figures.html"), qt.Equals, true)
+		c.Assert(isShortcode("shortcodes\\figures.html"), qt.Equals, false)
+		c.Assert(isShortcode("myshortcodes"), qt.Equals, false)
 
 	})
 
 	t.Run("variantsFromName", func(t *testing.T) {
-		assert := require.New(t)
-		assert.Equal([]string{"", "html", "html"}, templateVariants("figure.html"))
-		assert.Equal([]string{"no", "no", "html"}, templateVariants("figure.no.html"))
-		assert.Equal([]string{"no", "amp", "html"}, templateVariants("figure.no.amp.html"))
-		assert.Equal([]string{"amp", "amp", "html"}, templateVariants("figure.amp.html"))
+		c := qt.New(t)
+		c.Assert(templateVariants("figure.html"), qt.DeepEquals, []string{"", "html", "html"})
+		c.Assert(templateVariants("figure.no.html"), qt.DeepEquals, []string{"no", "no", "html"})
+		c.Assert(templateVariants("figure.no.amp.html"), qt.DeepEquals, []string{"no", "amp", "html"})
+		c.Assert(templateVariants("figure.amp.html"), qt.DeepEquals, []string{"amp", "amp", "html"})
 
 		name, variants := templateNameAndVariants("figure.html")
-		assert.Equal("figure", name)
-		assert.Equal([]string{"", "html", "html"}, variants)
+		c.Assert(name, qt.Equals, "figure")
+		c.Assert(variants, qt.DeepEquals, []string{"", "html", "html"})
 
 	})
 
 	t.Run("compareVariants", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 		var s *shortcodeTemplates
 
 		tests := []struct {
@@ -62,15 +61,15 @@
 			{"One with output format, one without", "figure.amp.html", "figure.html", -1},
 		}
 
-		for i, test := range tests {
+		for _, test := range tests {
 			w := s.compareVariants(templateVariants(test.name1), templateVariants(test.name2))
-			assert.Equal(test.expected, w, fmt.Sprintf("[%d] %s", i, test.name))
+			c.Assert(w, qt.Equals, test.expected)
 		}
 
 	})
 
 	t.Run("indexOf", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
 		s := &shortcodeTemplates{
 			variants: []shortcodeVariant{
@@ -79,20 +78,20 @@
 			},
 		}
 
-		assert.Equal(0, s.indexOf([]string{"a", "b", "c"}))
-		assert.Equal(1, s.indexOf([]string{"a", "b", "d"}))
-		assert.Equal(-1, s.indexOf([]string{"a", "b", "x"}))
+		c.Assert(s.indexOf([]string{"a", "b", "c"}), qt.Equals, 0)
+		c.Assert(s.indexOf([]string{"a", "b", "d"}), qt.Equals, 1)
+		c.Assert(s.indexOf([]string{"a", "b", "x"}), qt.Equals, -1)
 
 	})
 
 	t.Run("Name", func(t *testing.T) {
-		assert := require.New(t)
+		c := qt.New(t)
 
-		assert.Equal("foo.html", templateBaseName(templateShortcode, "shortcodes/foo.html"))
-		assert.Equal("foo.html", templateBaseName(templateShortcode, "_internal/shortcodes/foo.html"))
-		assert.Equal("test/foo.html", templateBaseName(templateShortcode, "shortcodes/test/foo.html"))
+		c.Assert(templateBaseName(templateShortcode, "shortcodes/foo.html"), qt.Equals, "foo.html")
+		c.Assert(templateBaseName(templateShortcode, "_internal/shortcodes/foo.html"), qt.Equals, "foo.html")
+		c.Assert(templateBaseName(templateShortcode, "shortcodes/test/foo.html"), qt.Equals, "test/foo.html")
 
-		assert.True(true)
+		c.Assert(true, qt.Equals, true)
 
 	})
 }
--- a/tpl/tplimpl/template_ast_transformers_test.go
+++ b/tpl/tplimpl/template_ast_transformers_test.go
@@ -23,7 +23,7 @@
 
 	"github.com/spf13/cast"
 
-	"github.com/stretchr/testify/require"
+	qt "github.com/frankban/quicktest"
 )
 
 var (
@@ -175,77 +175,78 @@
 
 func TestParamsKeysToLower(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	_, err := applyTemplateTransformers(templateUndefined, nil, nil)
-	require.Error(t, err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	templ, err := template.New("foo").Funcs(testFuncs).Parse(paramsTempl)
 
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
-	c := newTemplateContext(createParseTreeLookup(templ))
+	ctx := newTemplateContext(createParseTreeLookup(templ))
 
-	require.Equal(t, -1, c.decl.indexOfReplacementStart([]string{}))
+	c.Assert(ctx.decl.indexOfReplacementStart([]string{}), qt.Equals, -1)
 
-	c.applyTransformations(templ.Tree.Root)
+	ctx.applyTransformations(templ.Tree.Root)
 
 	var b bytes.Buffer
 
-	require.NoError(t, templ.Execute(&b, paramsData))
+	c.Assert(templ.Execute(&b, paramsData), qt.IsNil)
 
 	result := b.String()
 
-	require.Contains(t, result, "P1: P1L")
-	require.Contains(t, result, "P1_2: P1L")
-	require.Contains(t, result, "P1_3: P1L")
-	require.Contains(t, result, "P1_4: P1L")
-	require.Contains(t, result, "P2: P2L")
-	require.Contains(t, result, "P2_2: P2L")
-	require.Contains(t, result, "P2_3: P2L")
-	require.Contains(t, result, "P2_4: P2L")
-	require.Contains(t, result, "P22: P22L")
-	require.Contains(t, result, "P22_nested: P22L_nested")
-	require.Contains(t, result, "P3: P3H")
-	require.Contains(t, result, "P3_2: P3H")
-	require.Contains(t, result, "P3_3: P3H")
-	require.Contains(t, result, "P3_4: P3H")
-	require.Contains(t, result, "P4: 13")
-	require.Contains(t, result, "P5: P1L")
-	require.Contains(t, result, "P5_2: P2L")
+	c.Assert(result, qt.Contains, "P1: P1L")
+	c.Assert(result, qt.Contains, "P1_2: P1L")
+	c.Assert(result, qt.Contains, "P1_3: P1L")
+	c.Assert(result, qt.Contains, "P1_4: P1L")
+	c.Assert(result, qt.Contains, "P2: P2L")
+	c.Assert(result, qt.Contains, "P2_2: P2L")
+	c.Assert(result, qt.Contains, "P2_3: P2L")
+	c.Assert(result, qt.Contains, "P2_4: P2L")
+	c.Assert(result, qt.Contains, "P22: P22L")
+	c.Assert(result, qt.Contains, "P22_nested: P22L_nested")
+	c.Assert(result, qt.Contains, "P3: P3H")
+	c.Assert(result, qt.Contains, "P3_2: P3H")
+	c.Assert(result, qt.Contains, "P3_3: P3H")
+	c.Assert(result, qt.Contains, "P3_4: P3H")
+	c.Assert(result, qt.Contains, "P4: 13")
+	c.Assert(result, qt.Contains, "P5: P1L")
+	c.Assert(result, qt.Contains, "P5_2: P2L")
 
-	require.Contains(t, result, "IF: P1L")
-	require.Contains(t, result, "ELSE: P1L")
+	c.Assert(result, qt.Contains, "IF: P1L")
+	c.Assert(result, qt.Contains, "ELSE: P1L")
 
-	require.Contains(t, result, "WITH: P1L")
+	c.Assert(result, qt.Contains, "WITH: P1L")
 
-	require.Contains(t, result, "RANGE: 3: P1L")
+	c.Assert(result, qt.Contains, "RANGE: 3: P1L")
 
-	require.Contains(t, result, "Hi There")
+	c.Assert(result, qt.Contains, "Hi There")
 
 	// Issue #2740
-	require.Contains(t, result, "F1: themes/P2L-theme")
-	require.Contains(t, result, "F2: themes/P2L-theme")
-	require.Contains(t, result, "F3: themes/P2L-theme")
+	c.Assert(result, qt.Contains, "F1: themes/P2L-theme")
+	c.Assert(result, qt.Contains, "F2: themes/P2L-theme")
+	c.Assert(result, qt.Contains, "F3: themes/P2L-theme")
 
-	require.Contains(t, result, "PSLICE: PSLICE1|PSLICE3|")
-	require.Contains(t, result, "PARAMS STRING: foo:.Params.toc_hide:[!= true]")
-	require.Contains(t, result, "PARAMS STRING2: foo:.Params.toc_hide:[!= true]")
-	require.Contains(t, result, "PARAMS STRING3: .Params.TOC_HIDE:!=:[P1L]")
+	c.Assert(result, qt.Contains, "PSLICE: PSLICE1|PSLICE3|")
+	c.Assert(result, qt.Contains, "PARAMS STRING: foo:.Params.toc_hide:[!= true]")
+	c.Assert(result, qt.Contains, "PARAMS STRING2: foo:.Params.toc_hide:[!= true]")
+	c.Assert(result, qt.Contains, "PARAMS STRING3: .Params.TOC_HIDE:!=:[P1L]")
 
 	// Issue #5094
-	require.Contains(t, result, "PARAMS COMPOSITE: [1 3]")
+	c.Assert(result, qt.Contains, "PARAMS COMPOSITE: [1 3]")
 
 	// Issue #5068
-	require.Contains(t, result, "PCurrentSection: pcurrentsection")
+	c.Assert(result, qt.Contains, "PCurrentSection: pcurrentsection")
 
 	// Issue #5541
-	require.Contains(t, result, "PARAMS TIME: 1972-02-28")
-	require.Contains(t, result, "PARAMS TIME2: 1972-02-28")
+	c.Assert(result, qt.Contains, "PARAMS TIME: 1972-02-28")
+	c.Assert(result, qt.Contains, "PARAMS TIME2: 1972-02-28")
 
 	// Issue ##5615
-	require.Contains(t, result, "PARAMS SITE GLOBAL1: global-site")
-	require.Contains(t, result, "PARAMS SITE GLOBAL2: global-site")
-	require.Contains(t, result, "PARAMS SITE GLOBAL3: global-site")
+	c.Assert(result, qt.Contains, "PARAMS SITE GLOBAL1: global-site")
+	c.Assert(result, qt.Contains, "PARAMS SITE GLOBAL2: global-site")
+	c.Assert(result, qt.Contains, "PARAMS SITE GLOBAL3: global-site")
 
 }
 
@@ -275,8 +276,10 @@
 
 func TestParamsKeysToLowerVars(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
+
 	var (
-		ctx = map[string]interface{}{
+		data = map[string]interface{}{
 			"Params": map[string]interface{}{
 				"colors": map[string]interface{}{
 					"blue": "Amber",
@@ -304,31 +307,32 @@
 
 	templ, err := template.New("foo").Parse(paramsTempl)
 
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
-	c := newTemplateContext(createParseTreeLookup(templ))
+	ctx := newTemplateContext(createParseTreeLookup(templ))
 
-	c.applyTransformations(templ.Tree.Root)
+	ctx.applyTransformations(templ.Tree.Root)
 
 	var b bytes.Buffer
 
-	require.NoError(t, templ.Execute(&b, ctx))
+	c.Assert(templ.Execute(&b, data), qt.IsNil)
 
 	result := b.String()
 
-	require.Contains(t, result, "Color: Amber")
-	require.Contains(t, result, "Blue: Amber")
-	require.Contains(t, result, "Pretty First1: Indigo")
-	require.Contains(t, result, "Pretty First2: Indigo")
-	require.Contains(t, result, "Pretty First3: Indigo")
+	c.Assert(result, qt.Contains, "Color: Amber")
+	c.Assert(result, qt.Contains, "Blue: Amber")
+	c.Assert(result, qt.Contains, "Pretty First1: Indigo")
+	c.Assert(result, qt.Contains, "Pretty First2: Indigo")
+	c.Assert(result, qt.Contains, "Pretty First3: Indigo")
 
 }
 
 func TestParamsKeysToLowerInBlockTemplate(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	var (
-		ctx = map[string]interface{}{
+		data = map[string]interface{}{
 			"Params": map[string]interface{}{
 				"lower": "P1L",
 			},
@@ -344,28 +348,29 @@
 	)
 
 	masterTpl, err := template.New("foo").Parse(master)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	overlayTpl, err := template.Must(masterTpl.Clone()).Parse(overlay)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 	overlayTpl = overlayTpl.Lookup(overlayTpl.Name())
 
-	c := newTemplateContext(createParseTreeLookup(overlayTpl))
+	ctx := newTemplateContext(createParseTreeLookup(overlayTpl))
 
-	c.applyTransformations(overlayTpl.Tree.Root)
+	ctx.applyTransformations(overlayTpl.Tree.Root)
 
 	var b bytes.Buffer
 
-	require.NoError(t, overlayTpl.Execute(&b, ctx))
+	c.Assert(overlayTpl.Execute(&b, data), qt.IsNil)
 
 	result := b.String()
 
-	require.Contains(t, result, "P1: P1L")
-	require.Contains(t, result, "P2: P1L")
+	c.Assert(result, qt.Contains, "P1: P1L")
+	c.Assert(result, qt.Contains, "P2: P1L")
 }
 
 // Issue #2927
 func TestTransformRecursiveTemplate(t *testing.T) {
+	c := qt.New(t)
 
 	recursive := `
 {{ define "menu-nodes" }}
@@ -378,10 +383,10 @@
 `
 
 	templ, err := template.New("foo").Parse(recursive)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
-	c := newTemplateContext(createParseTreeLookup(templ))
-	c.applyTransformations(templ.Tree.Root)
+	ctx := newTemplateContext(createParseTreeLookup(templ))
+	ctx.applyTransformations(templ.Tree.Root)
 
 }
 
@@ -399,7 +404,7 @@
 func TestInsertIsZeroFunc(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	var (
 		ctx = map[string]interface{}{
@@ -434,33 +439,33 @@
 `
 	)
 
-	d := newD(assert)
+	d := newD(c)
 	h := d.Tmpl.(tpl.TemplateHandler)
 
 	// HTML templates
-	assert.NoError(h.AddTemplate("mytemplate.html", templ1))
-	assert.NoError(h.AddTemplate("othertemplate.html", templ2))
+	c.Assert(h.AddTemplate("mytemplate.html", templ1), qt.IsNil)
+	c.Assert(h.AddTemplate("othertemplate.html", templ2), qt.IsNil)
 
 	// Text templates
-	assert.NoError(h.AddTemplate("_text/mytexttemplate.txt", templ1))
-	assert.NoError(h.AddTemplate("_text/myothertexttemplate.txt", templ2))
+	c.Assert(h.AddTemplate("_text/mytexttemplate.txt", templ1), qt.IsNil)
+	c.Assert(h.AddTemplate("_text/myothertexttemplate.txt", templ2), qt.IsNil)
 
-	assert.NoError(h.MarkReady())
+	c.Assert(h.MarkReady(), qt.IsNil)
 
 	for _, name := range []string{"mytemplate.html", "mytexttemplate.txt"} {
 		tt, _ := d.Tmpl.Lookup(name)
 		result, err := tt.(tpl.TemplateExecutor).ExecuteToString(ctx)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
-		assert.Contains(result, ".True: TRUE")
-		assert.Contains(result, ".TimeZero1: FALSE")
-		assert.Contains(result, ".TimeZero2: FALSE")
-		assert.Contains(result, ".TimeZero3: TRUE")
-		assert.Contains(result, ".Now: TRUE")
-		assert.Contains(result, "TimeZero1 with: FALSE")
-		assert.Contains(result, ".TimeZero1: mytemplate: FALSE")
-		assert.Contains(result, ".TimeZero1: other-file-template: FALSE")
-		assert.Contains(result, ".NonEmptyInterfaceTypedNil: FALSE")
+		c.Assert(result, qt.Contains, ".True: TRUE")
+		c.Assert(result, qt.Contains, ".TimeZero1: FALSE")
+		c.Assert(result, qt.Contains, ".TimeZero2: FALSE")
+		c.Assert(result, qt.Contains, ".TimeZero3: TRUE")
+		c.Assert(result, qt.Contains, ".Now: TRUE")
+		c.Assert(result, qt.Contains, "TimeZero1 with: FALSE")
+		c.Assert(result, qt.Contains, ".TimeZero1: mytemplate: FALSE")
+		c.Assert(result, qt.Contains, ".TimeZero1: other-file-template: FALSE")
+		c.Assert(result, qt.Contains, ".NonEmptyInterfaceTypedNil: FALSE")
 	}
 
 }
@@ -492,16 +497,16 @@
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			assert := require.New(t)
+			c := qt.New(t)
 
 			templ, err := template.New("foo").Funcs(funcs).Parse(test.tplString)
-			require.NoError(t, err)
+			c.Assert(err, qt.IsNil)
 
-			c := newTemplateContext(createParseTreeLookup(templ))
-			c.typ = templateShortcode
-			c.applyTransformations(templ.Tree.Root)
+			ctx := newTemplateContext(createParseTreeLookup(templ))
+			ctx.typ = templateShortcode
+			ctx.applyTransformations(templ.Tree.Root)
 
-			assert.Equal(test.expected, c.Info)
+			c.Assert(ctx.Info, qt.Equals, test.expected)
 		})
 	}
 
@@ -534,16 +539,16 @@
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
-			assert := require.New(t)
+			c := qt.New(t)
 
 			templ, err := template.New("foo").Funcs(funcs).Parse(test.tplString)
-			require.NoError(t, err)
+			c.Assert(err, qt.IsNil)
 
 			_, err = applyTemplateTransformers(templatePartial, templ.Tree, createParseTreeLookup(templ))
 
 			// Just check that it doesn't fail in this test. We have functional tests
 			// in hugoblib.
-			assert.NoError(err)
+			c.Assert(err, qt.IsNil)
 
 		})
 	}
--- a/tpl/tplimpl/template_funcs_test.go
+++ b/tpl/tplimpl/template_funcs_test.go
@@ -25,6 +25,7 @@
 
 	"github.com/gohugoio/hugo/resources/page"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/common/hugo"
 	"github.com/gohugoio/hugo/common/loggers"
 	"github.com/gohugoio/hugo/config"
@@ -37,7 +38,6 @@
 	"github.com/gohugoio/hugo/tpl/partials"
 	"github.com/spf13/afero"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 var (
@@ -80,6 +80,7 @@
 
 func TestTemplateFuncsExamples(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	workingDir := "/home/hugo"
 
@@ -99,7 +100,7 @@
 	depsCfg := newDepsConfig(v)
 	depsCfg.Fs = fs
 	d, err := deps.New(depsCfg)
-	require.NoError(t, err)
+	c.Assert(err, qt.IsNil)
 
 	var data struct {
 		Title   string
@@ -119,15 +120,15 @@
 			for i, example := range mm.Examples {
 				in, expected := example[0], example[1]
 				d.WithTemplate = func(templ tpl.TemplateHandler) error {
-					require.NoError(t, templ.AddTemplate("test", in))
-					require.NoError(t, templ.AddTemplate("partials/header.html", "<title>Hugo Rocks!</title>"))
+					c.Assert(templ.AddTemplate("test", in), qt.IsNil)
+					c.Assert(templ.AddTemplate("partials/header.html", "<title>Hugo Rocks!</title>"), qt.IsNil)
 					return nil
 				}
-				require.NoError(t, d.LoadResources())
+				c.Assert(d.LoadResources(), qt.IsNil)
 
 				var b bytes.Buffer
 				templ, _ := d.Tmpl.Lookup("test")
-				require.NoError(t, templ.Execute(&b, &data))
+				c.Assert(templ.Execute(&b, &data), qt.IsNil)
 				if b.String() != expected {
 					t.Fatalf("%s[%d]: got %q expected %q", ns.Name, i, b.String(), expected)
 				}
@@ -141,7 +142,7 @@
 func TestPartialCached(t *testing.T) {
 	t.Parallel()
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	partial := `Now: {{ now.UnixNano }}`
 	name := "testing"
@@ -163,18 +164,18 @@
 	}
 
 	de, err := deps.New(config)
-	assert.NoError(err)
-	assert.NoError(de.LoadResources())
+	c.Assert(err, qt.IsNil)
+	c.Assert(de.LoadResources(), qt.IsNil)
 
 	ns := partials.New(de)
 
 	res1, err := ns.IncludeCached(name, &data)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	for j := 0; j < 10; j++ {
 		time.Sleep(2 * time.Nanosecond)
 		res2, err := ns.IncludeCached(name, &data)
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		if !reflect.DeepEqual(res1, res2) {
 			t.Fatalf("cache mismatch")
@@ -181,7 +182,7 @@
 		}
 
 		res3, err := ns.IncludeCached(name, &data, fmt.Sprintf("variant%d", j))
-		assert.NoError(err)
+		c.Assert(err, qt.IsNil)
 
 		if reflect.DeepEqual(res1, res3) {
 			t.Fatalf("cache mismatch")
@@ -205,6 +206,7 @@
 }
 
 func doBenchmarkPartial(b *testing.B, f func(ns *partials.Namespace) error) {
+	c := qt.New(b)
 	config := newDepsConfig(viper.New())
 	config.WithTemplate = func(templ tpl.TemplateHandler) error {
 		err := templ.AddTemplate("partials/bench1", `{{ shuffle (seq 1 10) }}`)
@@ -216,8 +218,8 @@
 	}
 
 	de, err := deps.New(config)
-	require.NoError(b, err)
-	require.NoError(b, de.LoadResources())
+	c.Assert(err, qt.IsNil)
+	c.Assert(de.LoadResources(), qt.IsNil)
 
 	ns := partials.New(de)
 
--- a/tpl/tplimpl/template_info_test.go
+++ b/tpl/tplimpl/template_info_test.go
@@ -15,31 +15,32 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/gohugoio/hugo/tpl"
-	"github.com/stretchr/testify/require"
 )
 
 func TestTemplateInfoShortcode(t *testing.T) {
-	assert := require.New(t)
-	d := newD(assert)
+	c := qt.New(t)
+	d := newD(c)
 	h := d.Tmpl.(tpl.TemplateHandler)
 
-	assert.NoError(h.AddTemplate("shortcodes/mytemplate.html", `
+	c.Assert(h.AddTemplate("shortcodes/mytemplate.html", `
 {{ .Inner }}
-`))
+`), qt.IsNil)
+
 	tt, found, _ := d.Tmpl.LookupVariant("mytemplate", tpl.TemplateVariants{})
 
-	assert.True(found)
+	c.Assert(found, qt.Equals, true)
 	tti, ok := tt.(tpl.TemplateInfoProvider)
-	assert.True(ok)
-	assert.True(tti.TemplateInfo().IsInner)
+	c.Assert(ok, qt.Equals, true)
+	c.Assert(tti.TemplateInfo().IsInner, qt.Equals, true)
 
 }
 
 // TODO(bep) move and use in other places
-func newD(assert *require.Assertions) *deps.Deps {
+func newD(c *qt.C) *deps.Deps {
 	v := newTestConfig()
 	fs := hugofs.NewMem(v)
 
@@ -46,7 +47,7 @@
 	depsCfg := newDepsConfig(v)
 	depsCfg.Fs = fs
 	d, err := deps.New(depsCfg)
-	assert.NoError(err)
+	c.Assert(err, qt.IsNil)
 
 	provider := DefaultTemplateProvider
 	provider.Update(d)
--- a/tpl/transform/init_test.go
+++ b/tpl/transform/init_test.go
@@ -16,12 +16,14 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -33,6 +35,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/transform/remarshal_test.go
+++ b/tpl/transform/remarshal_test.go
@@ -14,12 +14,11 @@
 package transform
 
 import (
-	"fmt"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/helpers"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestRemarshal(t *testing.T) {
@@ -28,7 +27,7 @@
 	v := viper.New()
 	v.Set("contentDir", "content")
 	ns := New(newDeps(v))
-	assert := require.New(t)
+	c := qt.New(t)
 
 	tomlExample := `title = "Test Metadata"
 		
@@ -96,10 +95,10 @@
 	for _, v1 := range variants {
 		for _, v2 := range variants {
 			// Both from and to may be the same here, but that is fine.
-			fromTo := fmt.Sprintf("%s => %s", v2.format, v1.format)
+			fromTo := qt.Commentf("%s => %s", v2.format, v1.format)
 
 			converted, err := ns.Remarshal(v1.format, v2.data)
-			assert.NoError(err, fromTo)
+			c.Assert(err, qt.IsNil, fromTo)
 			diff := helpers.DiffStrings(v1.data, converted)
 			if len(diff) > 0 {
 				t.Errorf("[%s] Expected \n%v\ngot\n%v\ndiff:\n%v", fromTo, v1.data, converted, diff)
@@ -117,7 +116,7 @@
 	v.Set("contentDir", "content")
 	ns := New(newDeps(v))
 
-	assert := require.New(t)
+	c := qt.New(t)
 
 	input := `
 Hugo = "Rules"
@@ -138,7 +137,7 @@
 `
 
 	for _, format := range []string{"json", "yaml", "toml"} {
-		fromTo := fmt.Sprintf("%s => %s", "toml", format)
+		fromTo := qt.Commentf("%s => %s", "toml", format)
 
 		converted := input
 		var err error
@@ -145,7 +144,7 @@
 		// Do a round-trip conversion
 		for _, toFormat := range []string{format, "toml"} {
 			converted, err = ns.Remarshal(toFormat, converted)
-			assert.NoError(err, fromTo)
+			c.Assert(err, qt.IsNil, fromTo)
 		}
 
 		diff := helpers.DiffStrings(expected, converted)
@@ -161,12 +160,12 @@
 	v := viper.New()
 	v.Set("contentDir", "content")
 	ns := New(newDeps(v))
-	assert := require.New(t)
+	c := qt.New(t)
 
 	_, err := ns.Remarshal("asdf", "asdf")
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 	_, err = ns.Remarshal("json", "asdf")
-	assert.Error(err)
+	c.Assert(err, qt.Not(qt.IsNil))
 
 }
--- a/tpl/transform/transform_test.go
+++ b/tpl/transform/transform_test.go
@@ -14,10 +14,10 @@
 package transform
 
 import (
-	"fmt"
 	"html/template"
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/config"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/gohugoio/hugo/helpers"
@@ -24,8 +24,6 @@
 	"github.com/gohugoio/hugo/hugofs"
 	"github.com/gohugoio/hugo/langs"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 type tstNoStringer struct{}
@@ -32,11 +30,12 @@
 
 func TestEmojify(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	v := viper.New()
 	ns := New(newDeps(v))
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -45,28 +44,28 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %s", i, test.s)
 
 		result, err := ns.Emojify(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestHighlight(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	v := viper.New()
 	v.Set("contentDir", "content")
 	ns := New(newDeps(v))
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		lang   string
 		opts   string
@@ -77,28 +76,28 @@
 		{`<Foo attr=" &lt; "></Foo>`, "xml", "", `&amp;lt;`},
 		{tstNoStringer{}, "go", "", false},
 	} {
-		errMsg := fmt.Sprintf("[%d]", i)
 
 		result, err := ns.Highlight(test.s, test.lang, test.opts)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Contains(t, result, test.expect.(string), errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(string(result), qt.Contains, test.expect.(string))
 	}
 }
 
 func TestHTMLEscape(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	v := viper.New()
 	v.Set("contentDir", "content")
 	ns := New(newDeps(v))
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -107,28 +106,28 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %s", i, test.s)
 
 		result, err := ns.HTMLEscape(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestHTMLUnescape(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	v := viper.New()
 	v.Set("contentDir", "content")
 	ns := New(newDeps(v))
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -137,28 +136,28 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %s", i, test.s)
 
 		result, err := ns.HTMLUnescape(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
 func TestMarkdownify(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	v := viper.New()
 	v.Set("contentDir", "content")
 	ns := New(newDeps(v))
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -166,17 +165,16 @@
 		{[]byte("Hello Bytes **World!**"), template.HTML("Hello Bytes <strong>World!</strong>")},
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %s", i, test.s)
 
 		result, err := ns.Markdownify(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
@@ -183,9 +181,7 @@
 // Issue #3040
 func TestMarkdownifyBlocksOfText(t *testing.T) {
 	t.Parallel()
-
-	assert := require.New(t)
-
+	c := qt.New(t)
 	v := viper.New()
 	v.Set("contentDir", "content")
 	ns := New(newDeps(v))
@@ -203,20 +199,20 @@
 `
 
 	result, err := ns.Markdownify(text)
-	assert.NoError(err)
-	assert.Equal(template.HTML(
-		"<p>#First</p>\n\n<p>This is some <em>bold</em> text.</p>\n\n<h2 id=\"second\">Second</h2>\n\n<p>This is some more text.</p>\n\n<p>And then some.</p>\n"),
-		result)
+	c.Assert(err, qt.IsNil)
+	c.Assert(result, qt.Equals, template.HTML(
+		"<p>#First</p>\n\n<p>This is some <em>bold</em> text.</p>\n\n<h2 id=\"second\">Second</h2>\n\n<p>This is some more text.</p>\n\n<p>And then some.</p>\n"))
 
 }
 
 func TestPlainify(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
 	v := viper.New()
 	ns := New(newDeps(v))
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		s      interface{}
 		expect interface{}
 	}{
@@ -224,17 +220,16 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %s", i, test.s)
 
 		result, err := ns.Plainify(test.s)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result, qt.Equals, test.expect)
 	}
 }
 
--- a/tpl/transform/unmarshal_test.go
+++ b/tpl/transform/unmarshal_test.go
@@ -23,9 +23,9 @@
 
 	"github.com/gohugoio/hugo/media"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/resources/resource"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 const (
@@ -82,13 +82,13 @@
 
 	v := viper.New()
 	ns := New(newDeps(v))
-	assert := require.New(t)
+	c := qt.New(t)
 
 	assertSlogan := func(m map[string]interface{}) {
-		assert.Equal("Hugo Rocks!", m["slogan"])
+		c.Assert(m["slogan"], qt.Equals, "Hugo Rocks!")
 	}
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		data    interface{}
 		options interface{}
 		expect  interface{}
@@ -113,27 +113,27 @@
 		}},
 		{testContentResource{key: "r1", content: `1997,Ford,E350,"ac, abs, moon",3000.00
 1999,Chevy,"Venture ""Extended Edition""","",4900.00`, mime: media.CSVType}, nil, func(r [][]string) {
-			assert.Equal(2, len(r))
+			c.Assert(len(r), qt.Equals, 2)
 			first := r[0]
-			assert.Equal(5, len(first))
-			assert.Equal("Ford", first[1])
+			c.Assert(len(first), qt.Equals, 5)
+			c.Assert(first[1], qt.Equals, "Ford")
 		}},
 		{testContentResource{key: "r1", content: `a;b;c`, mime: media.CSVType}, map[string]interface{}{"delimiter": ";"}, func(r [][]string) {
-			assert.Equal(r, [][]string{{"a", "b", "c"}})
+			c.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
 
 		}},
 		{"a,b,c", nil, func(r [][]string) {
-			assert.Equal(r, [][]string{{"a", "b", "c"}})
+			c.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
 
 		}},
 		{"a;b;c", map[string]interface{}{"delimiter": ";"}, func(r [][]string) {
-			assert.Equal(r, [][]string{{"a", "b", "c"}})
+			c.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
 
 		}},
 		{testContentResource{key: "r1", content: `
 % This is a comment
 a;b;c`, mime: media.CSVType}, map[string]interface{}{"DElimiter": ";", "Comment": "%"}, func(r [][]string) {
-			assert.Equal(r, [][]string{{"a", "b", "c"}})
+			c.Assert([][]string{{"a", "b", "c"}}, qt.DeepEquals, r)
 
 		}},
 		// errors
@@ -144,7 +144,6 @@
 		{`{ notjson }`, nil, false},
 		{tstNoStringer{}, nil, false},
 	} {
-		errMsg := fmt.Sprintf("[%d]", i)
 
 		ns.cache.Clear()
 
@@ -159,20 +158,20 @@
 		result, err := ns.Unmarshal(args...)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			assert.Error(err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 		} else if fn, ok := test.expect.(func(m map[string]interface{})); ok {
-			assert.NoError(err, errMsg)
+			c.Assert(err, qt.IsNil)
 			m, ok := result.(map[string]interface{})
-			assert.True(ok, errMsg)
+			c.Assert(ok, qt.Equals, true)
 			fn(m)
 		} else if fn, ok := test.expect.(func(r [][]string)); ok {
-			assert.NoError(err, errMsg)
+			c.Assert(err, qt.IsNil)
 			r, ok := result.([][]string)
-			assert.True(ok, errMsg)
+			c.Assert(ok, qt.Equals, true)
 			fn(r)
 		} else {
-			assert.NoError(err, errMsg)
-			assert.Equal(test.expect, result, errMsg)
+			c.Assert(err, qt.IsNil)
+			c.Assert(result, qt.Equals, test.expect)
 		}
 
 	}
--- a/tpl/urls/init_test.go
+++ b/tpl/urls/init_test.go
@@ -16,13 +16,15 @@
 import (
 	"testing"
 
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
+	"github.com/gohugoio/hugo/htesting/hqt"
 	"github.com/gohugoio/hugo/tpl/internal"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/require"
 )
 
 func TestInit(t *testing.T) {
+	c := qt.New(t)
 	var found bool
 	var ns *internal.TemplateFuncsNamespace
 
@@ -34,6 +36,6 @@
 		}
 	}
 
-	require.True(t, found)
-	require.IsType(t, &Namespace{}, ns.Context())
+	c.Assert(found, qt.Equals, true)
+	c.Assert(ns.Context(), hqt.IsSameType, &Namespace{})
 }
--- a/tpl/urls/urls_test.go
+++ b/tpl/urls/urls_test.go
@@ -14,14 +14,14 @@
 package urls
 
 import (
-	"fmt"
 	"net/url"
 	"testing"
 
+	"github.com/gohugoio/hugo/htesting/hqt"
+
+	qt "github.com/frankban/quicktest"
 	"github.com/gohugoio/hugo/deps"
 	"github.com/spf13/viper"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
 )
 
 var ns = New(&deps.Deps{Cfg: viper.New()})
@@ -30,8 +30,9 @@
 
 func TestParse(t *testing.T) {
 	t.Parallel()
+	c := qt.New(t)
 
-	for i, test := range []struct {
+	for _, test := range []struct {
 		rawurl interface{}
 		expect interface{}
 	}{
@@ -53,16 +54,16 @@
 		// errors
 		{tstNoStringer{}, false},
 	} {
-		errMsg := fmt.Sprintf("[%d] %v", i, test)
 
 		result, err := ns.Parse(test.rawurl)
 
 		if b, ok := test.expect.(bool); ok && !b {
-			require.Error(t, err, errMsg)
+			c.Assert(err, qt.Not(qt.IsNil))
 			continue
 		}
 
-		require.NoError(t, err, errMsg)
-		assert.Equal(t, test.expect, result, errMsg)
+		c.Assert(err, qt.IsNil)
+		c.Assert(result,
+			qt.CmpEquals(hqt.DeepAllowUnexported(&url.URL{}, url.Userinfo{})), test.expect)
 	}
 }
--- a/transform/chain_test.go
+++ b/transform/chain_test.go
@@ -18,7 +18,7 @@
 	"strings"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
+	qt "github.com/frankban/quicktest"
 )
 
 func TestChainZeroTransformers(t *testing.T) {
@@ -64,6 +64,7 @@
 }
 
 func TestNewEmptyTransforms(t *testing.T) {
+	c := qt.New(t)
 	transforms := NewEmpty()
-	assert.Equal(t, 20, cap(transforms))
+	c.Assert(cap(transforms), qt.Equals, 20)
 }