diff --git a/Makefile b/Makefile
index 32bef5c6dbccf2ac4981b4c7f1fbfd08313426cc..394a4a2e0fbd817bdc5c2e523c7a52babbcd6211 100644
--- a/Makefile
+++ b/Makefile
@@ -74,7 +74,7 @@ test: test-unit
 test-unit:
 	@echo
 	@echo "==> Running unit tests <=="
-	HELM_HOME=/no/such/dir $(GO) test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS)
+	HELM_HOME=/no_such_dir $(GO) test $(GOFLAGS) -run $(TESTS) $(PKG) $(TESTFLAGS)
 
 .PHONY: test-style
 test-style:
diff --git a/cmd/helm/create.go b/cmd/helm/create.go
index 39ec211aae228a2dae6a06d363abfc52880ed924..6a099454a1a1029adc0d84a5c587cbb4a4079988 100644
--- a/cmd/helm/create.go
+++ b/cmd/helm/create.go
@@ -26,7 +26,6 @@ import (
 
 	"k8s.io/helm/pkg/chartutil"
 	"k8s.io/helm/pkg/hapi/chart"
-	"k8s.io/helm/pkg/helm/helmpath"
 )
 
 const createDesc = `
@@ -51,11 +50,7 @@ will be overwritten, but other files will be left alone.
 
 type createOptions struct {
 	starter string // --starter
-
-	// args
-	name string
-
-	home helmpath.Home
+	name    string
 }
 
 func newCreateCmd(out io.Writer) *cobra.Command {
@@ -66,7 +61,6 @@ func newCreateCmd(out io.Writer) *cobra.Command {
 		Short: "create a new chart with the given name",
 		Long:  createDesc,
 		RunE: func(cmd *cobra.Command, args []string) error {
-			o.home = settings.Home
 			if len(args) == 0 {
 				return errors.New("the name of the new chart is required")
 			}
@@ -93,7 +87,7 @@ func (o *createOptions) run(out io.Writer) error {
 
 	if o.starter != "" {
 		// Create from the starter
-		lstarter := filepath.Join(o.home.Starters(), o.starter)
+		lstarter := filepath.Join(settings.Home.Starters(), o.starter)
 		return chartutil.CreateFrom(cfile, filepath.Dir(o.name), lstarter)
 	}
 
diff --git a/cmd/helm/create_test.go b/cmd/helm/create_test.go
index bf3fdc342b0f20f14edda67bc16e2f170eaa68ba..5ec69f67859d067c3aa8f8d7ad7a2c5d232d9be7 100644
--- a/cmd/helm/create_test.go
+++ b/cmd/helm/create_test.go
@@ -28,23 +28,10 @@ import (
 )
 
 func TestCreateCmd(t *testing.T) {
-	cname := "testchart"
-	// Make a temp dir
-	tdir, err := ioutil.TempDir("", "helm-create-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tdir)
+	tdir := testTempDir(t)
+	defer testChdir(t, tdir)()
 
-	// CD into it
-	pwd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if err := os.Chdir(tdir); err != nil {
-		t.Fatal(err)
-	}
-	defer os.Chdir(pwd)
+	cname := "testchart"
 
 	// Run a create
 	if _, err := executeCommand(nil, "create "+cname); err != nil {
@@ -73,28 +60,17 @@ func TestCreateCmd(t *testing.T) {
 }
 
 func TestCreateStarterCmd(t *testing.T) {
+	defer resetEnv()()
+
 	cname := "testchart"
 	// Make a temp dir
-	tdir, err := ioutil.TempDir("", "helm-create-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tdir)
-
-	thome, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(thome.String())
-		cleanup()
-	}()
+	tdir := testTempDir(t)
 
-	settings.Home = thome
+	hh := testHelmHome(t)
+	settings.Home = hh
 
 	// Create a starter.
-	starterchart := filepath.Join(thome.String(), "starters")
+	starterchart := hh.Starters()
 	os.Mkdir(starterchart, 0755)
 	if dest, err := chartutil.Create(&chart.Metadata{Name: "starterchart"}, starterchart); err != nil {
 		t.Fatalf("Could not create chart: %s", err)
@@ -106,18 +82,10 @@ func TestCreateStarterCmd(t *testing.T) {
 		t.Fatalf("Could not write template: %s", err)
 	}
 
-	// CD into it
-	pwd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if err := os.Chdir(tdir); err != nil {
-		t.Fatal(err)
-	}
-	defer os.Chdir(pwd)
+	defer testChdir(t, tdir)()
 
 	// Run a create
-	if _, err := executeCommand(nil, fmt.Sprintf("--home=%s create --starter=starterchart %s", thome, cname)); err != nil {
+	if _, err := executeCommand(nil, fmt.Sprintf("--home=%s create --starter=starterchart %s", hh, cname)); err != nil {
 		t.Errorf("Failed to run create: %s", err)
 		return
 	}
@@ -149,9 +117,8 @@ func TestCreateStarterCmd(t *testing.T) {
 	for _, tpl := range c.Templates {
 		if tpl.Name == "templates/foo.tpl" {
 			found = true
-			data := tpl.Data
-			if string(data) != "test" {
-				t.Errorf("Expected template 'test', got %q", string(data))
+			if data := string(tpl.Data); data != "test" {
+				t.Errorf("Expected template 'test', got %q", data)
 			}
 		}
 	}
diff --git a/cmd/helm/delete_test.go b/cmd/helm/delete_test.go
index fffaccdd6f14b1e16ae9f741fce97361cbd6bf62..a391d995f54a59d99b90289e94fdf0a153088b69 100644
--- a/cmd/helm/delete_test.go
+++ b/cmd/helm/delete_test.go
@@ -27,7 +27,7 @@ func TestDelete(t *testing.T) {
 
 	rels := []*release.Release{helm.ReleaseMock(&helm.MockReleaseOptions{Name: "aeneas"})}
 
-	tests := []releaseCase{
+	tests := []cmdTestCase{
 		{
 			name:   "basic delete",
 			cmd:    "delete aeneas",
@@ -59,5 +59,5 @@ func TestDelete(t *testing.T) {
 			wantError: true,
 		},
 	}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/dependency_build.go b/cmd/helm/dependency_build.go
index 69ff3637dd2db9bf4cd37c314e65335877936519..7a9942087848e4feea45767ba00a3edf0e127feb 100644
--- a/cmd/helm/dependency_build.go
+++ b/cmd/helm/dependency_build.go
@@ -22,7 +22,6 @@ import (
 
 	"k8s.io/helm/pkg/downloader"
 	"k8s.io/helm/pkg/getter"
-	"k8s.io/helm/pkg/helm/helmpath"
 )
 
 const dependencyBuildDesc = `
@@ -40,10 +39,7 @@ type dependencyBuildOptions struct {
 	keyring string // --keyring
 	verify  bool   // --verify
 
-	// args
 	chartpath string
-
-	helmhome helmpath.Home
 }
 
 func newDependencyBuildCmd(out io.Writer) *cobra.Command {
@@ -56,7 +52,6 @@ func newDependencyBuildCmd(out io.Writer) *cobra.Command {
 		Short: "rebuild the charts/ directory based on the requirements.lock file",
 		Long:  dependencyBuildDesc,
 		RunE: func(cmd *cobra.Command, args []string) error {
-			o.helmhome = settings.Home
 			if len(args) > 0 {
 				o.chartpath = args[0]
 			}
@@ -75,7 +70,7 @@ func (o *dependencyBuildOptions) run(out io.Writer) error {
 	man := &downloader.Manager{
 		Out:       out,
 		ChartPath: o.chartpath,
-		HelmHome:  o.helmhome,
+		HelmHome:  settings.Home,
 		Keyring:   o.keyring,
 		Getters:   getter.All(settings),
 	}
diff --git a/cmd/helm/dependency_build_test.go b/cmd/helm/dependency_build_test.go
index b313f5c2c64975bb7a5592673265176cf7c1184e..234fc9b30f7e5bc62eb7c9ba33ee673bd519187f 100644
--- a/cmd/helm/dependency_build_test.go
+++ b/cmd/helm/dependency_build_test.go
@@ -27,22 +27,14 @@ import (
 )
 
 func TestDependencyBuildCmd(t *testing.T) {
-	hh, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(hh.String())
-		cleanup()
-	}()
+	defer resetEnv()()
 
+	hh := testHelmHome(t)
 	settings.Home = hh
 
 	srv := repotest.NewServer(hh.String())
 	defer srv.Stop()
-	_, err = srv.CopyCharts("testdata/testcharts/*.tgz")
-	if err != nil {
+	if _, err := srv.CopyCharts("testdata/testcharts/*.tgz"); err != nil {
 		t.Fatal(err)
 	}
 
diff --git a/cmd/helm/dependency_test.go b/cmd/helm/dependency_test.go
index 27e64f28b1e8a5f8d58165da134adc830ce0da5b..98dcab1a67a02d61aa5eee13e656683f9c7a2a68 100644
--- a/cmd/helm/dependency_test.go
+++ b/cmd/helm/dependency_test.go
@@ -20,7 +20,7 @@ import (
 )
 
 func TestDependencyListCmd(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:      "No such chart",
 		cmd:       "dependency list /no/such/chart",
 		golden:    "output/dependency-list-no-chart.txt",
@@ -38,5 +38,5 @@ func TestDependencyListCmd(t *testing.T) {
 		cmd:    "dependency list testdata/testcharts/reqtest-0.1.0.tgz",
 		golden: "output/dependency-list-archive.txt",
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/dependency_update_test.go b/cmd/helm/dependency_update_test.go
index f8d0537bc91421eaca91ea15b1e43acd17f96260..212106af420aebf31164e3d38919dc372b312942 100644
--- a/cmd/helm/dependency_update_test.go
+++ b/cmd/helm/dependency_update_test.go
@@ -35,16 +35,9 @@ import (
 )
 
 func TestDependencyUpdateCmd(t *testing.T) {
-	hh, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(hh.String())
-		cleanup()
-	}()
+	defer resetEnv()()
 
+	hh := testHelmHome(t)
 	settings.Home = hh
 
 	srv := repotest.NewServer(hh.String())
@@ -125,16 +118,9 @@ func TestDependencyUpdateCmd(t *testing.T) {
 }
 
 func TestDependencyUpdateCmd_SkipRefresh(t *testing.T) {
-	hh, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(hh.String())
-		cleanup()
-	}()
+	defer resetEnv()()
 
+	hh := testHelmHome(t)
 	settings.Home = hh
 
 	srv := repotest.NewServer(hh.String())
@@ -163,16 +149,9 @@ func TestDependencyUpdateCmd_SkipRefresh(t *testing.T) {
 }
 
 func TestDependencyUpdateCmd_DontDeleteOldChartsOnError(t *testing.T) {
-	hh, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(hh.String())
-		cleanup()
-	}()
+	defer resetEnv()()
 
+	hh := testHelmHome(t)
 	settings.Home = hh
 
 	srv := repotest.NewServer(hh.String())
diff --git a/cmd/helm/fetch_test.go b/cmd/helm/fetch_test.go
index 66b688a415acbec25f2a446f474eb7d5aaabcd5d..86c0c53270495b5b199d590aba494bb7c356c1ed 100644
--- a/cmd/helm/fetch_test.go
+++ b/cmd/helm/fetch_test.go
@@ -28,20 +28,14 @@ import (
 )
 
 func TestFetchCmd(t *testing.T) {
-	hh, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(hh.String())
-		cleanup()
-	}()
-	srv := repotest.NewServer(hh.String())
-	defer srv.Stop()
+	defer resetEnv()()
 
+	hh := testHelmHome(t)
 	settings.Home = hh
 
+	srv := repotest.NewServer(hh.String())
+	defer srv.Stop()
+
 	// all flags will get "--home=TMDIR -d outdir" appended.
 	tests := []struct {
 		name         string
@@ -131,7 +125,7 @@ func TestFetchCmd(t *testing.T) {
 	}
 
 	for _, tt := range tests {
-		outdir := filepath.Join(hh.String(), "testout")
+		outdir := hh.Path("testout")
 		os.RemoveAll(outdir)
 		os.Mkdir(outdir, 0755)
 
diff --git a/cmd/helm/get_hooks_test.go b/cmd/helm/get_hooks_test.go
index 1af2fdbd3bf5ba4926551170f456d8a264fa979d..001c826b63e77294e2d0b438759d9fbaf6be3059 100644
--- a/cmd/helm/get_hooks_test.go
+++ b/cmd/helm/get_hooks_test.go
@@ -24,7 +24,7 @@ import (
 )
 
 func TestGetHooks(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:   "get hooks with release",
 		cmd:    "get hooks aeneas",
 		golden: "output/get-hooks.txt",
@@ -35,5 +35,5 @@ func TestGetHooks(t *testing.T) {
 		golden:    "output/get-hooks-no-args.txt",
 		wantError: true,
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/get_manifest_test.go b/cmd/helm/get_manifest_test.go
index 08160a71b5b61414815b5ceae0e3aebe06dcd158..da29aee1dc7cd0dcfc967bed9cfccaf7d31baf8d 100644
--- a/cmd/helm/get_manifest_test.go
+++ b/cmd/helm/get_manifest_test.go
@@ -24,7 +24,7 @@ import (
 )
 
 func TestGetManifest(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:   "get manifest with release",
 		cmd:    "get manifest juno",
 		golden: "output/get-manifest.txt",
@@ -35,5 +35,5 @@ func TestGetManifest(t *testing.T) {
 		golden:    "output/get-manifest-no-args.txt",
 		wantError: true,
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/get_test.go b/cmd/helm/get_test.go
index 9a00bb35665693fa0dcce1053dcc2f8a759a0fa0..1df178aa8881acc71ebe8fb1c0f5496783a48247 100644
--- a/cmd/helm/get_test.go
+++ b/cmd/helm/get_test.go
@@ -24,7 +24,7 @@ import (
 )
 
 func TestGetCmd(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:   "get with a release",
 		cmd:    "get thomas-guide",
 		golden: "output/get-release.txt",
@@ -35,5 +35,5 @@ func TestGetCmd(t *testing.T) {
 		golden:    "output/get-no-args.txt",
 		wantError: true,
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/get_values_test.go b/cmd/helm/get_values_test.go
index bcef9c43288f0bb04a1be8bb425f0333c5059dc0..a9e81dbcef241ea2476d8321b61cbd7cf343d227 100644
--- a/cmd/helm/get_values_test.go
+++ b/cmd/helm/get_values_test.go
@@ -24,7 +24,7 @@ import (
 )
 
 func TestGetValuesCmd(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:   "get values with a release",
 		cmd:    "get values thomas-guide",
 		golden: "output/get-values.txt",
@@ -35,5 +35,5 @@ func TestGetValuesCmd(t *testing.T) {
 		golden:    "output/get-values-args.txt",
 		wantError: true,
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/helm.go b/cmd/helm/helm.go
index 1451fac3725edc1ef3158f5c6d2a6dc44912f037..1e58be85fddb715000f2d3532a11cd54175429c0 100644
--- a/cmd/helm/helm.go
+++ b/cmd/helm/helm.go
@@ -18,14 +18,12 @@ package main // import "k8s.io/helm/cmd/helm"
 
 import (
 	"fmt"
-	"io"
 	"log"
 	"os"
 	"strings"
 	"sync"
 
 	"github.com/pkg/errors"
-	"github.com/spf13/cobra"
 	// Import to initialize client auth plugins.
 	_ "k8s.io/client-go/plugin/pkg/client/auth"
 	"k8s.io/client-go/tools/clientcmd"
@@ -42,83 +40,6 @@ var (
 	configOnce sync.Once
 )
 
-var globalUsage = `The Kubernetes package manager
-
-To begin working with Helm, run the 'helm init' command:
-
-	$ helm init
-
-This will set up any necessary local configuration.
-
-Common actions from this point include:
-
-- helm search:    search for charts
-- helm fetch:     download a chart to your local directory to view
-- helm install:   upload the chart to Kubernetes
-- helm list:      list releases of charts
-
-Environment:
-  $HELM_HOME          set an alternative location for Helm files. By default, these are stored in ~/.helm
-  $HELM_NO_PLUGINS    disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
-  $KUBECONFIG         set an alternative Kubernetes configuration file (default "~/.kube/config")
-`
-
-func newRootCmd(c helm.Interface, out io.Writer, args []string) *cobra.Command {
-	cmd := &cobra.Command{
-		Use:          "helm",
-		Short:        "The Helm package manager for Kubernetes.",
-		Long:         globalUsage,
-		SilenceUsage: true,
-	}
-	flags := cmd.PersistentFlags()
-
-	settings.AddFlags(flags)
-
-	cmd.AddCommand(
-		// chart commands
-		newCreateCmd(out),
-		newDependencyCmd(out),
-		newFetchCmd(out),
-		newInspectCmd(out),
-		newLintCmd(out),
-		newPackageCmd(out),
-		newRepoCmd(out),
-		newSearchCmd(out),
-		newVerifyCmd(out),
-
-		// release commands
-		newDeleteCmd(c, out),
-		newGetCmd(c, out),
-		newHistoryCmd(c, out),
-		newInstallCmd(c, out),
-		newListCmd(c, out),
-		newReleaseTestCmd(c, out),
-		newRollbackCmd(c, out),
-		newStatusCmd(c, out),
-		newUpgradeCmd(c, out),
-
-		newCompletionCmd(out),
-		newHomeCmd(out),
-		newInitCmd(out),
-		newPluginCmd(out),
-		newTemplateCmd(out),
-		newVersionCmd(out),
-
-		// Hidden documentation generator command: 'helm docs'
-		newDocsCmd(out),
-	)
-
-	flags.Parse(args)
-
-	// set defaults from environment
-	settings.Init(flags)
-
-	// Find and add plugins
-	loadPlugins(cmd, out)
-
-	return cmd
-}
-
 func init() {
 	log.SetFlags(log.Lshortfile)
 }
diff --git a/cmd/helm/helm_test.go b/cmd/helm/helm_test.go
index 46cfeddb82f992e401b61e89c9556c56379d6e12..f1d7563afe365cb46c7dede74e38654b8e0633b2 100644
--- a/cmd/helm/helm_test.go
+++ b/cmd/helm/helm_test.go
@@ -20,12 +20,10 @@ import (
 	"bytes"
 	"io/ioutil"
 	"os"
-	"path/filepath"
 	"strings"
 	"testing"
 
 	shellwords "github.com/mattn/go-shellwords"
-	"github.com/pkg/errors"
 	"github.com/spf13/cobra"
 
 	"k8s.io/helm/internal/test"
@@ -35,30 +33,40 @@ import (
 	"k8s.io/helm/pkg/repo"
 )
 
-func executeCommand(c helm.Interface, cmd string) (string, error) {
-	_, output, err := executeCommandC(c, cmd)
-	return output, err
-}
+// base temp directory
+var testingDir string
 
-func executeCommandC(client helm.Interface, cmd string) (*cobra.Command, string, error) {
-	args, err := shellwords.Parse(cmd)
+func init() {
+	var err error
+	testingDir, err = ioutil.TempDir(testingDir, "helm")
 	if err != nil {
-		return nil, "", err
+		panic(err)
 	}
-	buf := new(bytes.Buffer)
-	root := newRootCmd(client, buf, args)
-	root.SetOutput(buf)
-	root.SetArgs(args)
+}
 
-	c, err := root.ExecuteC()
+func TestMain(m *testing.M) {
+	os.Unsetenv("HELM_HOME")
 
-	return c, buf.String(), err
+	exitCode := m.Run()
+	os.RemoveAll(testingDir)
+	os.Exit(exitCode)
 }
 
-func testReleaseCmd(t *testing.T, tests []releaseCase) {
+func testTempDir(t *testing.T) string {
+	t.Helper()
+	d, err := ioutil.TempDir(testingDir, "helm")
+	if err != nil {
+		t.Fatal(err)
+	}
+	return d
+}
+
+func runTestCmd(t *testing.T, tests []cmdTestCase) {
 	t.Helper()
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			defer resetEnv()()
+
 			c := &helm.FakeClient{
 				Rels:          tt.rels,
 				TestRunStatus: tt.testRunStatus,
@@ -74,8 +82,8 @@ func testReleaseCmd(t *testing.T, tests []releaseCase) {
 	}
 }
 
-// releaseCase describes a test case that works with releases.
-type releaseCase struct {
+// cmdTestCase describes a test case that works with releases.
+type cmdTestCase struct {
 	name      string
 	cmd       string
 	golden    string
@@ -85,29 +93,28 @@ type releaseCase struct {
 	testRunStatus map[string]release.TestRunStatus
 }
 
-// tempHelmHome sets up a Helm Home in a temp dir.
-//
-// This does not clean up the directory. You must do that yourself.
-// You  must also set helmHome yourself.
-func tempHelmHome(t *testing.T) (helmpath.Home, error) {
-	oldhome := settings.Home
-	dir, err := ioutil.TempDir("", "helm_home-")
+func executeCommand(c helm.Interface, cmd string) (string, error) {
+	_, output, err := executeCommandC(c, cmd)
+	return output, err
+}
+
+func executeCommandC(client helm.Interface, cmd string) (*cobra.Command, string, error) {
+	args, err := shellwords.Parse(cmd)
 	if err != nil {
-		return helmpath.Home("n/"), err
+		return nil, "", err
 	}
+	buf := new(bytes.Buffer)
+	root := newRootCmd(client, buf, args)
+	root.SetOutput(buf)
+	root.SetArgs(args)
 
-	settings.Home = helmpath.Home(dir)
-	if err := ensureTestHome(t, settings.Home); err != nil {
-		return helmpath.Home("n/"), err
-	}
-	settings.Home = oldhome
-	return helmpath.Home(dir), nil
+	c, err := root.ExecuteC()
+
+	return c, buf.String(), err
 }
 
 // ensureTestHome creates a home directory like ensureHome, but without remote references.
-//
-// t is used only for logging.
-func ensureTestHome(t *testing.T, home helmpath.Home) error {
+func ensureTestHome(t *testing.T, home helmpath.Home) {
 	t.Helper()
 	for _, p := range []string{
 		home.String(),
@@ -117,7 +124,7 @@ func ensureTestHome(t *testing.T, home helmpath.Home) error {
 		home.Starters(),
 	} {
 		if err := os.MkdirAll(p, 0755); err != nil {
-			return errors.Wrapf(err, "could not create %s", p)
+			t.Fatal(err)
 		}
 	}
 
@@ -130,96 +137,30 @@ func ensureTestHome(t *testing.T, home helmpath.Home) error {
 			Cache: "charts-index.yaml",
 		})
 		if err := rf.WriteFile(repoFile, 0644); err != nil {
-			return err
+			t.Fatal(err)
 		}
 	}
 	if r, err := repo.LoadRepositoriesFile(repoFile); err == repo.ErrRepoOutOfDate {
 		t.Log("Updating repository file format...")
 		if err := r.WriteFile(repoFile, 0644); err != nil {
-			return err
+			t.Fatal(err)
 		}
 	}
-
 	t.Logf("$HELM_HOME has been configured at %s.\n", home)
-	return nil
-
 }
 
-func TestRootCmd(t *testing.T) {
-	cleanup := resetEnv()
-	defer cleanup()
-
-	tests := []struct {
-		name, args, home string
-		envars           map[string]string
-	}{
-		{
-			name: "defaults",
-			args: "home",
-			home: filepath.Join(os.Getenv("HOME"), "/.helm"),
-		},
-		{
-			name: "with --home set",
-			args: "--home /foo",
-			home: "/foo",
-		},
-		{
-			name: "subcommands with --home set",
-			args: "home --home /foo",
-			home: "/foo",
-		},
-		{
-			name:   "with $HELM_HOME set",
-			args:   "home",
-			envars: map[string]string{"HELM_HOME": "/bar"},
-			home:   "/bar",
-		},
-		{
-			name:   "subcommands with $HELM_HOME set",
-			args:   "home",
-			envars: map[string]string{"HELM_HOME": "/bar"},
-			home:   "/bar",
-		},
-		{
-			name:   "with $HELM_HOME and --home set",
-			args:   "home --home /foo",
-			envars: map[string]string{"HELM_HOME": "/bar"},
-			home:   "/foo",
-		},
-	}
-
-	// ensure not set locally
-	os.Unsetenv("HELM_HOME")
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			defer os.Unsetenv("HELM_HOME")
-
-			for k, v := range tt.envars {
-				os.Setenv(k, v)
-			}
-
-			cmd, _, err := executeCommandC(nil, tt.args)
-			if err != nil {
-				t.Fatalf("unexpected error: %s", err)
-			}
-
-			if settings.Home.String() != tt.home {
-				t.Errorf("expected home %q, got %q", tt.home, settings.Home)
-			}
-			homeFlag := cmd.Flag("home").Value.String()
-			homeFlag = os.ExpandEnv(homeFlag)
-			if homeFlag != tt.home {
-				t.Errorf("expected home %q, got %q", tt.home, homeFlag)
-			}
-		})
-	}
+// testHelmHome sets up a Helm Home in a temp dir.
+func testHelmHome(t *testing.T) helmpath.Home {
+	t.Helper()
+	dir := helmpath.Home(testTempDir(t))
+	ensureTestHome(t, dir)
+	return dir
 }
 
 func resetEnv() func() {
-	origSettings := settings
-	origEnv := os.Environ()
+	origSettings, origEnv := settings, os.Environ()
 	return func() {
+		os.Clearenv()
 		settings = origSettings
 		for _, pair := range origEnv {
 			kv := strings.SplitN(pair, "=", 2)
@@ -227,3 +168,15 @@ func resetEnv() func() {
 		}
 	}
 }
+
+func testChdir(t *testing.T, dir string) func() {
+	t.Helper()
+	old, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := os.Chdir(dir); err != nil {
+		t.Fatal(err)
+	}
+	return func() { os.Chdir(old) }
+}
diff --git a/cmd/helm/history_test.go b/cmd/helm/history_test.go
index 84fcfe69126beea6e842652bd5cf3448cc92eb88..3d7786e0464e93bf51d957509f1830a5444e95e8 100644
--- a/cmd/helm/history_test.go
+++ b/cmd/helm/history_test.go
@@ -32,7 +32,7 @@ func TestHistoryCmd(t *testing.T) {
 		})
 	}
 
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name: "get history for release",
 		cmd:  "history angry-bird",
 		rels: []*rpb.Release{
@@ -67,5 +67,5 @@ func TestHistoryCmd(t *testing.T) {
 		},
 		golden: "output/history.json",
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/init_test.go b/cmd/helm/init_test.go
index 5ee148baeea62ce247f7285574f43884d9144c6c..5f6724b286aa9b130df2929293d93fdcf2f37d5d 100644
--- a/cmd/helm/init_test.go
+++ b/cmd/helm/init_test.go
@@ -18,7 +18,6 @@ package main
 
 import (
 	"bytes"
-	"io/ioutil"
 	"os"
 	"testing"
 
@@ -26,14 +25,9 @@ import (
 )
 
 func TestEnsureHome(t *testing.T) {
-	home, err := ioutil.TempDir("", "helm_home")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(home)
+	hh := helmpath.Home(testTempDir(t))
 
 	b := bytes.NewBuffer(nil)
-	hh := helmpath.Home(home)
 	settings.Home = hh
 	if err := ensureDirectories(hh, b); err != nil {
 		t.Error(err)
diff --git a/cmd/helm/install_test.go b/cmd/helm/install_test.go
index 3978053452a6bda58b9771bffdd4938c4d0eb2bc..298edb5f2b5d3355508b6f8e70445b06d5f24436 100644
--- a/cmd/helm/install_test.go
+++ b/cmd/helm/install_test.go
@@ -23,7 +23,7 @@ import (
 )
 
 func TestInstall(t *testing.T) {
-	tests := []releaseCase{
+	tests := []cmdTestCase{
 		// Install, base case
 		{
 			name:   "basic install",
@@ -120,7 +120,7 @@ func TestInstall(t *testing.T) {
 		},
 	}
 
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
 
 type nameTemplateTestCase struct {
diff --git a/cmd/helm/list_test.go b/cmd/helm/list_test.go
index efffaf07037d18da8f76bf1686360326f57afcec..2a331eb01bdd71b8eab7fcb2fa7c3a33e74aa6e5 100644
--- a/cmd/helm/list_test.go
+++ b/cmd/helm/list_test.go
@@ -24,7 +24,7 @@ import (
 )
 
 func TestListCmd(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name: "with a release",
 		cmd:  "list",
 		rels: []*release.Release{
@@ -111,5 +111,5 @@ func TestListCmd(t *testing.T) {
 		golden: "output/list-with-old-releases.txt",
 	}}
 
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/package_test.go b/cmd/helm/package_test.go
index ead7c7fb19f115cbe4b2e43efd91142ebaab7f81..d7f0e0f9daede36c90c53421e76d9d332af06c98 100644
--- a/cmd/helm/package_test.go
+++ b/cmd/helm/package_test.go
@@ -53,6 +53,7 @@ func TestSetVersion(t *testing.T) {
 }
 
 func TestPackage(t *testing.T) {
+	defer resetEnv()()
 
 	tests := []struct {
 		name    string
@@ -132,32 +133,20 @@ func TestPackage(t *testing.T) {
 		},
 	}
 
-	// Because these tests are destructive, we run them in a tempdir.
 	origDir, err := os.Getwd()
 	if err != nil {
 		t.Fatal(err)
 	}
-	tmp, err := ioutil.TempDir("", "helm-package-test-")
-	if err != nil {
-		t.Fatal(err)
-	}
+	tmp := testTempDir(t)
 
 	t.Logf("Running tests in %s", tmp)
-	if err := os.Chdir(tmp); err != nil {
-		t.Fatal(err)
-	}
+	defer testChdir(t, tmp)()
 
 	if err := os.Mkdir("toot", 0777); err != nil {
 		t.Fatal(err)
 	}
 
 	ensureTestHome(t, helmpath.Home(tmp))
-	cleanup := resetEnv()
-	defer func() {
-		os.Chdir(origDir)
-		os.RemoveAll(tmp)
-		cleanup()
-	}()
 
 	settings.Home = helmpath.Home(tmp)
 
@@ -210,22 +199,14 @@ func TestPackage(t *testing.T) {
 }
 
 func TestSetAppVersion(t *testing.T) {
+	defer resetEnv()()
+
 	var ch *chart.Chart
 	expectedAppVersion := "app-version-foo"
-	tmp, _ := ioutil.TempDir("", "helm-package-app-version-")
+	tmp := testTempDir(t)
 
-	thome, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(tmp)
-		os.RemoveAll(thome.String())
-		cleanup()
-	}()
-
-	settings.Home = helmpath.Home(thome)
+	hh := testHelmHome(t)
+	settings.Home = helmpath.Home(hh)
 
 	c := newPackageCmd(&bytes.Buffer{})
 	flags := map[string]string{
@@ -233,8 +214,7 @@ func TestSetAppVersion(t *testing.T) {
 		"app-version": expectedAppVersion,
 	}
 	setFlags(c, flags)
-	err = c.RunE(c, []string{"testdata/testcharts/alpine"})
-	if err != nil {
+	if err := c.RunE(c, []string{"testdata/testcharts/alpine"}); err != nil {
 		t.Errorf("unexpected error %q", err)
 	}
 
@@ -244,7 +224,7 @@ func TestSetAppVersion(t *testing.T) {
 	} else if fi.Size() == 0 {
 		t.Errorf("file %q has zero bytes.", chartPath)
 	}
-	ch, err = chartutil.Load(chartPath)
+	ch, err := chartutil.Load(chartPath)
 	if err != nil {
 		t.Errorf("unexpected error loading packaged chart: %v", err)
 	}
@@ -254,6 +234,8 @@ func TestSetAppVersion(t *testing.T) {
 }
 
 func TestPackageValues(t *testing.T) {
+	defer resetEnv()()
+
 	testCases := []struct {
 		desc               string
 		args               []string
@@ -288,26 +270,13 @@ func TestPackageValues(t *testing.T) {
 		},
 	}
 
-	thome, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(thome.String())
-		cleanup()
-	}()
-
-	settings.Home = thome
+	hh := testHelmHome(t)
+	settings.Home = hh
 
 	for _, tc := range testCases {
 		var files []string
 		for _, contents := range tc.valuefilesContents {
-			f, err := createValuesFile(contents)
-			if err != nil {
-				t.Errorf("%q unexpected error creating temporary values file: %q", tc.desc, err)
-			}
-			defer os.RemoveAll(filepath.Dir(f))
+			f := createValuesFile(t, contents)
 			files = append(files, f)
 		}
 		valueFiles := strings.Join(files, ",")
@@ -322,11 +291,7 @@ func TestPackageValues(t *testing.T) {
 }
 
 func runAndVerifyPackageCommandValues(t *testing.T, args []string, flags map[string]string, valueFiles string, expected chartutil.Values) {
-	outputDir, err := ioutil.TempDir("", "helm-package")
-	if err != nil {
-		t.Errorf("unexpected error creating temporary output directory: %q", err)
-	}
-	defer os.RemoveAll(outputDir)
+	outputDir := testTempDir(t)
 
 	if len(flags) == 0 {
 		flags = make(map[string]string)
@@ -339,16 +304,14 @@ func runAndVerifyPackageCommandValues(t *testing.T, args []string, flags map[str
 
 	cmd := newPackageCmd(&bytes.Buffer{})
 	setFlags(cmd, flags)
-	err = cmd.RunE(cmd, args)
-	if err != nil {
+	if err := cmd.RunE(cmd, args); err != nil {
 		t.Errorf("unexpected error: %q", err)
 	}
 
 	outputFile := filepath.Join(outputDir, "alpine-0.1.0.tgz")
 	verifyOutputChartExists(t, outputFile)
 
-	var actual chartutil.Values
-	actual, err = getChartValues(outputFile)
+	actual, err := getChartValues(outputFile)
 	if err != nil {
 		t.Errorf("unexpected error extracting chart values: %q", err)
 	}
@@ -356,19 +319,15 @@ func runAndVerifyPackageCommandValues(t *testing.T, args []string, flags map[str
 	verifyValues(t, actual, expected)
 }
 
-func createValuesFile(data string) (string, error) {
-	outputDir, err := ioutil.TempDir("", "values-file")
-	if err != nil {
-		return "", err
-	}
+func createValuesFile(t *testing.T, data string) string {
+	outputDir := testTempDir(t)
 
 	outputFile := filepath.Join(outputDir, "values.yaml")
-	if err = ioutil.WriteFile(outputFile, []byte(data), 0755); err != nil {
-		os.RemoveAll(outputFile)
-		return "", err
+	if err := ioutil.WriteFile(outputFile, []byte(data), 0755); err != nil {
+		t.Fatalf("err: %s", err)
 	}
 
-	return outputFile, nil
+	return outputFile
 }
 
 func getChartValues(chartPath string) (chartutil.Values, error) {
diff --git a/cmd/helm/plugin_test.go b/cmd/helm/plugin_test.go
index 707616f5aa88ec56b29aae12ae3aa52a0673083d..32af2cd213ec5e4bdf2a833202b3503d98aedf25 100644
--- a/cmd/helm/plugin_test.go
+++ b/cmd/helm/plugin_test.go
@@ -62,8 +62,7 @@ func TestManuallyProcessArgs(t *testing.T) {
 }
 
 func TestLoadPlugins(t *testing.T) {
-	cleanup := resetEnv()
-	defer cleanup()
+	defer resetEnv()()
 
 	settings.Home = "testdata/helmhome"
 
@@ -133,8 +132,7 @@ func TestLoadPlugins(t *testing.T) {
 }
 
 func TestLoadPlugins_HelmNoPlugins(t *testing.T) {
-	cleanup := resetEnv()
-	defer cleanup()
+	defer resetEnv()()
 
 	settings.Home = "testdata/helmhome"
 
@@ -151,6 +149,7 @@ func TestLoadPlugins_HelmNoPlugins(t *testing.T) {
 }
 
 func TestSetupEnv(t *testing.T) {
+	defer resetEnv()()
 	name := "pequod"
 	settings.Home = helmpath.Home("testdata/helmhome")
 	base := filepath.Join(settings.Home.Plugins(), name)
diff --git a/cmd/helm/release_testing_test.go b/cmd/helm/release_testing_test.go
index 6213cda33d48bce57ccd84f34abb71e45d2c81b3..4f7392b9391ede1689eed7c44ae3167efad6b402 100644
--- a/cmd/helm/release_testing_test.go
+++ b/cmd/helm/release_testing_test.go
@@ -23,7 +23,7 @@ import (
 )
 
 func TestReleaseTesting(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:          "basic test",
 		cmd:           "test example-release",
 		testRunStatus: map[string]release.TestRunStatus{"PASSED: green lights everywhere": release.TestRunSuccess},
@@ -62,5 +62,5 @@ func TestReleaseTesting(t *testing.T) {
 			"PASSED: feel free to party again":            release.TestRunSuccess},
 		wantError: true,
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/repo_add_test.go b/cmd/helm/repo_add_test.go
index 4f4f041da30220905c9788998a1dd469c9e7f1fc..406d9c7561104444ecd2e4e7607b511305ed9834 100644
--- a/cmd/helm/repo_add_test.go
+++ b/cmd/helm/repo_add_test.go
@@ -26,50 +26,43 @@ import (
 )
 
 func TestRepoAddCmd(t *testing.T) {
-	srv, thome, err := repotest.NewTempServer("testdata/testserver/*.*")
+	defer resetEnv()()
+
+	srv, hh, err := repotest.NewTempServer("testdata/testserver/*.*")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	cleanup := resetEnv()
 	defer func() {
 		srv.Stop()
-		os.RemoveAll(thome.String())
-		cleanup()
+		os.RemoveAll(hh.String())
 	}()
-	if err := ensureTestHome(t, thome); err != nil {
-		t.Fatal(err)
-	}
-
-	settings.Home = thome
+	ensureTestHome(t, hh)
+	settings.Home = hh
 
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:   "add a repository",
-		cmd:    fmt.Sprintf("repo add test-name %s --home %s", srv.URL(), thome),
+		cmd:    fmt.Sprintf("repo add test-name %s --home %s", srv.URL(), hh),
 		golden: "output/repo-add.txt",
 	}}
 
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
 
 func TestRepoAdd(t *testing.T) {
-	ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*")
+	defer resetEnv()()
+
+	ts, hh, err := repotest.NewTempServer("testdata/testserver/*.*")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	cleanup := resetEnv()
-	hh := thome
 	defer func() {
 		ts.Stop()
-		os.RemoveAll(thome.String())
-		cleanup()
+		os.RemoveAll(hh.String())
 	}()
-	if err := ensureTestHome(t, hh); err != nil {
-		t.Fatal(err)
-	}
-
-	settings.Home = thome
+	ensureTestHome(t, hh)
+	settings.Home = hh
 
 	const testRepoName = "test-name"
 
diff --git a/cmd/helm/repo_index_test.go b/cmd/helm/repo_index_test.go
index 4d6313f6c35ab1d53438863b500bf239fd9e9e4e..026e162f33c1b39e33556a505864d2571f98e63b 100644
--- a/cmd/helm/repo_index_test.go
+++ b/cmd/helm/repo_index_test.go
@@ -19,7 +19,6 @@ package main
 import (
 	"bytes"
 	"io"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"testing"
@@ -29,11 +28,7 @@ import (
 
 func TestRepoIndexCmd(t *testing.T) {
 
-	dir, err := ioutil.TempDir("", "helm-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(dir)
+	dir := testTempDir(t)
 
 	comp := filepath.Join(dir, "compressedchart-0.1.0.tgz")
 	if err := linkOrCopy("testdata/testcharts/compressedchart-0.1.0.tgz", comp); err != nil {
diff --git a/cmd/helm/repo_remove_test.go b/cmd/helm/repo_remove_test.go
index 7b7ad5a5d0b6a9be996d2e2476f119bb7128a404..340af3ef8dbb5ab1718c4b6a4888f45a2f4de6b0 100644
--- a/cmd/helm/repo_remove_test.go
+++ b/cmd/helm/repo_remove_test.go
@@ -22,29 +22,24 @@ import (
 	"strings"
 	"testing"
 
-	"k8s.io/helm/pkg/helm/helmpath"
 	"k8s.io/helm/pkg/repo"
 	"k8s.io/helm/pkg/repo/repotest"
 )
 
 func TestRepoRemove(t *testing.T) {
-	ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*")
+	defer resetEnv()()
+
+	ts, hh, err := repotest.NewTempServer("testdata/testserver/*.*")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	hh := helmpath.Home(thome)
-	cleanup := resetEnv()
 	defer func() {
 		ts.Stop()
-		os.RemoveAll(thome.String())
-		cleanup()
+		os.RemoveAll(hh.String())
 	}()
-	if err := ensureTestHome(t, hh); err != nil {
-		t.Fatal(err)
-	}
-
-	settings.Home = thome
+	ensureTestHome(t, hh)
+	settings.Home = hh
 
 	const testRepoName = "test-name"
 
diff --git a/cmd/helm/repo_update_test.go b/cmd/helm/repo_update_test.go
index 5821133149a5c5d1223e70be1eb36eb621c33002..b84cd7a2d678f79cb0d4bd7d55a25cb70a30eef3 100644
--- a/cmd/helm/repo_update_test.go
+++ b/cmd/helm/repo_update_test.go
@@ -30,18 +30,10 @@ import (
 )
 
 func TestUpdateCmd(t *testing.T) {
-	thome, err := tempHelmHome(t)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	cleanup := resetEnv()
-	defer func() {
-		os.RemoveAll(thome.String())
-		cleanup()
-	}()
+	defer resetEnv()()
 
-	settings.Home = thome
+	hh := testHelmHome(t)
+	settings.Home = hh
 
 	out := bytes.NewBuffer(nil)
 	// Instead of using the HTTP updater, we provide our own for this test.
@@ -53,7 +45,7 @@ func TestUpdateCmd(t *testing.T) {
 	}
 	o := &repoUpdateOptions{
 		update: updater,
-		home:   helmpath.Home(thome),
+		home:   helmpath.Home(hh),
 	}
 	if err := o.run(out); err != nil {
 		t.Fatal(err)
@@ -65,23 +57,19 @@ func TestUpdateCmd(t *testing.T) {
 }
 
 func TestUpdateCharts(t *testing.T) {
-	ts, thome, err := repotest.NewTempServer("testdata/testserver/*.*")
+	defer resetEnv()()
+
+	ts, hh, err := repotest.NewTempServer("testdata/testserver/*.*")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	hh := helmpath.Home(thome)
-	cleanup := resetEnv()
 	defer func() {
 		ts.Stop()
-		os.RemoveAll(thome.String())
-		cleanup()
+		os.RemoveAll(hh.String())
 	}()
-	if err := ensureTestHome(t, hh); err != nil {
-		t.Fatal(err)
-	}
-
-	settings.Home = thome
+	ensureTestHome(t, hh)
+	settings.Home = hh
 
 	r, err := repo.NewChartRepository(&repo.Entry{
 		Name:  "charts",
diff --git a/cmd/helm/rollback_test.go b/cmd/helm/rollback_test.go
index fd78c4d0dc21b622a23612436fad20bf542152c4..73624c31e0a423f0aafe5725b67582656feb36b7 100644
--- a/cmd/helm/rollback_test.go
+++ b/cmd/helm/rollback_test.go
@@ -21,7 +21,7 @@ import (
 )
 
 func TestRollbackCmd(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:   "rollback a release",
 		cmd:    "rollback funny-honey 1",
 		golden: "output/rollback.txt",
@@ -39,5 +39,5 @@ func TestRollbackCmd(t *testing.T) {
 		golden:    "output/rollback-no-args.txt",
 		wantError: true,
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/root.go b/cmd/helm/root.go
new file mode 100644
index 0000000000000000000000000000000000000000..4ee8945883e67931014c275d4aeaa7883b0d6167
--- /dev/null
+++ b/cmd/helm/root.go
@@ -0,0 +1,102 @@
+/*
+Copyright 2016 The Kubernetes 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 main // import "k8s.io/helm/cmd/helm"
+
+import (
+	"io"
+
+	"github.com/spf13/cobra"
+
+	"k8s.io/helm/pkg/helm"
+)
+
+var globalUsage = `The Kubernetes package manager
+
+To begin working with Helm, run the 'helm init' command:
+
+	$ helm init
+
+This will set up any necessary local configuration.
+
+Common actions from this point include:
+
+- helm search:    search for charts
+- helm fetch:     download a chart to your local directory to view
+- helm install:   upload the chart to Kubernetes
+- helm list:      list releases of charts
+
+Environment:
+  $HELM_HOME          set an alternative location for Helm files. By default, these are stored in ~/.helm
+  $HELM_NO_PLUGINS    disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins.
+  $KUBECONFIG         set an alternative Kubernetes configuration file (default "~/.kube/config")
+`
+
+func newRootCmd(c helm.Interface, out io.Writer, args []string) *cobra.Command {
+	cmd := &cobra.Command{
+		Use:          "helm",
+		Short:        "The Helm package manager for Kubernetes.",
+		Long:         globalUsage,
+		SilenceUsage: true,
+	}
+	flags := cmd.PersistentFlags()
+
+	settings.AddFlags(flags)
+
+	cmd.AddCommand(
+		// chart commands
+		newCreateCmd(out),
+		newDependencyCmd(out),
+		newFetchCmd(out),
+		newInspectCmd(out),
+		newLintCmd(out),
+		newPackageCmd(out),
+		newRepoCmd(out),
+		newSearchCmd(out),
+		newVerifyCmd(out),
+
+		// release commands
+		newDeleteCmd(c, out),
+		newGetCmd(c, out),
+		newHistoryCmd(c, out),
+		newInstallCmd(c, out),
+		newListCmd(c, out),
+		newReleaseTestCmd(c, out),
+		newRollbackCmd(c, out),
+		newStatusCmd(c, out),
+		newUpgradeCmd(c, out),
+
+		newCompletionCmd(out),
+		newHomeCmd(out),
+		newInitCmd(out),
+		newPluginCmd(out),
+		newTemplateCmd(out),
+		newVersionCmd(out),
+
+		// Hidden documentation generator command: 'helm docs'
+		newDocsCmd(out),
+	)
+
+	flags.Parse(args)
+
+	// set defaults from environment
+	settings.Init(flags)
+
+	// Find and add plugins
+	loadPlugins(cmd, out)
+
+	return cmd
+}
diff --git a/cmd/helm/root_test.go b/cmd/helm/root_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..4787a43b18f30a2e6d9124e4f0f23f913992b2f4
--- /dev/null
+++ b/cmd/helm/root_test.go
@@ -0,0 +1,93 @@
+/*
+Copyright 2016 The Kubernetes 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 main
+
+import (
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+func TestRootCmd(t *testing.T) {
+	defer resetEnv()()
+
+	tests := []struct {
+		name, args, home string
+		envars           map[string]string
+	}{
+		{
+			name: "defaults",
+			args: "home",
+			home: filepath.Join(os.Getenv("HOME"), "/.helm"),
+		},
+		{
+			name: "with --home set",
+			args: "--home /foo",
+			home: "/foo",
+		},
+		{
+			name: "subcommands with --home set",
+			args: "home --home /foo",
+			home: "/foo",
+		},
+		{
+			name:   "with $HELM_HOME set",
+			args:   "home",
+			envars: map[string]string{"HELM_HOME": "/bar"},
+			home:   "/bar",
+		},
+		{
+			name:   "subcommands with $HELM_HOME set",
+			args:   "home",
+			envars: map[string]string{"HELM_HOME": "/bar"},
+			home:   "/bar",
+		},
+		{
+			name:   "with $HELM_HOME and --home set",
+			args:   "home --home /foo",
+			envars: map[string]string{"HELM_HOME": "/bar"},
+			home:   "/foo",
+		},
+	}
+
+	// ensure not set locally
+	os.Unsetenv("HELM_HOME")
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			defer os.Unsetenv("HELM_HOME")
+
+			for k, v := range tt.envars {
+				os.Setenv(k, v)
+			}
+
+			cmd, _, err := executeCommandC(nil, tt.args)
+			if err != nil {
+				t.Fatalf("unexpected error: %s", err)
+			}
+
+			if settings.Home.String() != tt.home {
+				t.Errorf("expected home %q, got %q", tt.home, settings.Home)
+			}
+			homeFlag := cmd.Flag("home").Value.String()
+			homeFlag = os.ExpandEnv(homeFlag)
+			if homeFlag != tt.home {
+				t.Errorf("expected home %q, got %q", tt.home, homeFlag)
+			}
+		})
+	}
+}
diff --git a/cmd/helm/search_test.go b/cmd/helm/search_test.go
index 27d8c6c3e5d63389c9aabc9506e565a042de28eb..9733942c0d27e901d1f1e0d4b8cb25082dba753f 100644
--- a/cmd/helm/search_test.go
+++ b/cmd/helm/search_test.go
@@ -21,51 +21,52 @@ import (
 )
 
 func TestSearchCmd(t *testing.T) {
-	tests := []releaseCase{{
+	defer resetEnv()()
+
+	setHome := func(cmd string) string {
+		return cmd + " --home=testdata/helmhome"
+	}
+
+	tests := []cmdTestCase{{
 		name:   "search for 'maria', expect one match",
-		cmd:    "search maria",
+		cmd:    setHome("search maria"),
 		golden: "output/search-single.txt",
 	}, {
 		name:   "search for 'alpine', expect two matches",
-		cmd:    "search alpine",
+		cmd:    setHome("search alpine"),
 		golden: "output/search-multiple.txt",
 	}, {
 		name:   "search for 'alpine' with versions, expect three matches",
-		cmd:    "search alpine --versions",
+		cmd:    setHome("search alpine --versions"),
 		golden: "output/search-multiple-versions.txt",
 	}, {
 		name:   "search for 'alpine' with version constraint, expect one match with version 0.1.0",
-		cmd:    "search alpine --version '>= 0.1, < 0.2'",
+		cmd:    setHome("search alpine --version '>= 0.1, < 0.2'"),
 		golden: "output/search-constraint.txt",
 	}, {
 		name:   "search for 'alpine' with version constraint, expect one match with version 0.1.0",
-		cmd:    "search alpine --versions --version '>= 0.1, < 0.2'",
+		cmd:    setHome("search alpine --versions --version '>= 0.1, < 0.2'"),
 		golden: "output/search-versions-constraint.txt",
 	}, {
 		name:   "search for 'alpine' with version constraint, expect one match with version 0.2.0",
-		cmd:    "search alpine --version '>= 0.1'",
+		cmd:    setHome("search alpine --version '>= 0.1'"),
 		golden: "output/search-constraint-single.txt",
 	}, {
 		name:   "search for 'alpine' with version constraint and --versions, expect two matches",
-		cmd:    "search alpine --versions --version '>= 0.1'",
+		cmd:    setHome("search alpine --versions --version '>= 0.1'"),
 		golden: "output/search-multiple-versions-constraints.txt",
 	}, {
 		name:   "search for 'syzygy', expect no matches",
-		cmd:    "search syzygy",
+		cmd:    setHome("search syzygy"),
 		golden: "output/search-not-found.txt",
 	}, {
 		name:   "search for 'alp[a-z]+', expect two matches",
-		cmd:    "search alp[a-z]+ --regexp",
+		cmd:    setHome("search alp[a-z]+ --regexp"),
 		golden: "output/search-regex.txt",
 	}, {
 		name:      "search for 'alp[', expect failure to compile regexp",
-		cmd:       "search alp[ --regexp",
+		cmd:       setHome("search alp[ --regexp"),
 		wantError: true,
 	}}
-
-	cleanup := resetEnv()
-	defer cleanup()
-
-	settings.Home = "testdata/helmhome"
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/status_test.go b/cmd/helm/status_test.go
index c94d278a36d173196e28993a87b28f9419dd7b10..787b59e6fcff73f4394b5ccaebc3dd2a91a38b61 100644
--- a/cmd/helm/status_test.go
+++ b/cmd/helm/status_test.go
@@ -32,7 +32,7 @@ func TestStatusCmd(t *testing.T) {
 		}}
 	}
 
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:   "get status of a deployed release",
 		cmd:    "status flummoxed-chickadee",
 		golden: "output/status.txt",
@@ -89,5 +89,5 @@ func TestStatusCmd(t *testing.T) {
 			},
 		}),
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/testdata/output/upgrade-with-install-timeout.txt b/cmd/helm/testdata/output/upgrade-with-install-timeout.txt
index 4a2233228b965232cdd456c7b7c931445a6a4e4c..11d66d8d34fc5bce1302e804809267e6a21a6e8d 100644
--- a/cmd/helm/testdata/output/upgrade-with-install-timeout.txt
+++ b/cmd/helm/testdata/output/upgrade-with-install-timeout.txt
@@ -1,47 +1,3 @@
-REVISION: 1
-RELEASED: Fri Sep  2 22:04:05 1977
-CHART: testUpgradeChart-0.1.0
-USER-SUPPLIED VALUES:
-name: "value"
-COMPUTED VALUES:
-affinity: {}
-fullnameOverride: ""
-image:
-  pullPolicy: IfNotPresent
-  repository: nginx
-  tag: stable
-ingress:
-  annotations: {}
-  enabled: false
-  hosts:
-  - chart-example.local
-  path: /
-  tls: []
-name: value
-nameOverride: ""
-nodeSelector: {}
-replicaCount: 1
-resources: {}
-service:
-  port: 80
-  type: ClusterIP
-tolerations: []
-
-HOOKS:
----
-# pre-install-hook
-apiVersion: v1
-kind: Job
-metadata:
-  annotations:
-    "helm.sh/hook": pre-install
-
-MANIFEST:
-apiVersion: v1
-kind: Secret
-metadata:
-  name: fixture
-
 Release "crazy-bunny" has been upgraded. Happy Helming!
 LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC
 NAMESPACE: default
diff --git a/cmd/helm/testdata/output/upgrade-with-install.txt b/cmd/helm/testdata/output/upgrade-with-install.txt
index 90d69d65f12de0d75efa7dbdc2c640fc576f4511..95cc1f625c31f4e880a238a8ffcf909e21910fa1 100644
--- a/cmd/helm/testdata/output/upgrade-with-install.txt
+++ b/cmd/helm/testdata/output/upgrade-with-install.txt
@@ -1,47 +1,3 @@
-REVISION: 1
-RELEASED: Fri Sep  2 22:04:05 1977
-CHART: testUpgradeChart-0.1.0
-USER-SUPPLIED VALUES:
-name: "value"
-COMPUTED VALUES:
-affinity: {}
-fullnameOverride: ""
-image:
-  pullPolicy: IfNotPresent
-  repository: nginx
-  tag: stable
-ingress:
-  annotations: {}
-  enabled: false
-  hosts:
-  - chart-example.local
-  path: /
-  tls: []
-name: value
-nameOverride: ""
-nodeSelector: {}
-replicaCount: 1
-resources: {}
-service:
-  port: 80
-  type: ClusterIP
-tolerations: []
-
-HOOKS:
----
-# pre-install-hook
-apiVersion: v1
-kind: Job
-metadata:
-  annotations:
-    "helm.sh/hook": pre-install
-
-MANIFEST:
-apiVersion: v1
-kind: Secret
-metadata:
-  name: fixture
-
 Release "zany-bunny" has been upgraded. Happy Helming!
 LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC
 NAMESPACE: default
diff --git a/cmd/helm/testdata/output/upgrade-with-reset-values.txt b/cmd/helm/testdata/output/upgrade-with-reset-values.txt
index 4e5989e7f77b53d26b2d55df37934ce0e50be2f1..53227b1923b2e8840b784db8e1475d1272e8c5f9 100644
--- a/cmd/helm/testdata/output/upgrade-with-reset-values.txt
+++ b/cmd/helm/testdata/output/upgrade-with-reset-values.txt
@@ -1,47 +1,3 @@
-REVISION: 4
-RELEASED: Fri Sep  2 22:04:05 1977
-CHART: testUpgradeChart-0.1.0
-USER-SUPPLIED VALUES:
-name: "value"
-COMPUTED VALUES:
-affinity: {}
-fullnameOverride: ""
-image:
-  pullPolicy: IfNotPresent
-  repository: nginx
-  tag: stable
-ingress:
-  annotations: {}
-  enabled: false
-  hosts:
-  - chart-example.local
-  path: /
-  tls: []
-name: value
-nameOverride: ""
-nodeSelector: {}
-replicaCount: 1
-resources: {}
-service:
-  port: 80
-  type: ClusterIP
-tolerations: []
-
-HOOKS:
----
-# pre-install-hook
-apiVersion: v1
-kind: Job
-metadata:
-  annotations:
-    "helm.sh/hook": pre-install
-
-MANIFEST:
-apiVersion: v1
-kind: Secret
-metadata:
-  name: fixture
-
 Release "funny-bunny" has been upgraded. Happy Helming!
 LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC
 NAMESPACE: default
diff --git a/cmd/helm/testdata/output/upgrade-with-reset-values2.txt b/cmd/helm/testdata/output/upgrade-with-reset-values2.txt
index 12c5d47a817f73e20d319f0997f0fc6f29be0cbd..53227b1923b2e8840b784db8e1475d1272e8c5f9 100644
--- a/cmd/helm/testdata/output/upgrade-with-reset-values2.txt
+++ b/cmd/helm/testdata/output/upgrade-with-reset-values2.txt
@@ -1,47 +1,3 @@
-REVISION: 5
-RELEASED: Fri Sep  2 22:04:05 1977
-CHART: testUpgradeChart-0.1.0
-USER-SUPPLIED VALUES:
-name: "value"
-COMPUTED VALUES:
-affinity: {}
-fullnameOverride: ""
-image:
-  pullPolicy: IfNotPresent
-  repository: nginx
-  tag: stable
-ingress:
-  annotations: {}
-  enabled: false
-  hosts:
-  - chart-example.local
-  path: /
-  tls: []
-name: value
-nameOverride: ""
-nodeSelector: {}
-replicaCount: 1
-resources: {}
-service:
-  port: 80
-  type: ClusterIP
-tolerations: []
-
-HOOKS:
----
-# pre-install-hook
-apiVersion: v1
-kind: Job
-metadata:
-  annotations:
-    "helm.sh/hook": pre-install
-
-MANIFEST:
-apiVersion: v1
-kind: Secret
-metadata:
-  name: fixture
-
 Release "funny-bunny" has been upgraded. Happy Helming!
 LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC
 NAMESPACE: default
diff --git a/cmd/helm/testdata/output/upgrade-with-timeout.txt b/cmd/helm/testdata/output/upgrade-with-timeout.txt
index 156fa59519e1fad25e6aa4b2a031f400bd1dac12..53227b1923b2e8840b784db8e1475d1272e8c5f9 100644
--- a/cmd/helm/testdata/output/upgrade-with-timeout.txt
+++ b/cmd/helm/testdata/output/upgrade-with-timeout.txt
@@ -1,47 +1,3 @@
-REVISION: 3
-RELEASED: Fri Sep  2 22:04:05 1977
-CHART: testUpgradeChart-0.1.0
-USER-SUPPLIED VALUES:
-name: "value"
-COMPUTED VALUES:
-affinity: {}
-fullnameOverride: ""
-image:
-  pullPolicy: IfNotPresent
-  repository: nginx
-  tag: stable
-ingress:
-  annotations: {}
-  enabled: false
-  hosts:
-  - chart-example.local
-  path: /
-  tls: []
-name: value
-nameOverride: ""
-nodeSelector: {}
-replicaCount: 1
-resources: {}
-service:
-  port: 80
-  type: ClusterIP
-tolerations: []
-
-HOOKS:
----
-# pre-install-hook
-apiVersion: v1
-kind: Job
-metadata:
-  annotations:
-    "helm.sh/hook": pre-install
-
-MANIFEST:
-apiVersion: v1
-kind: Secret
-metadata:
-  name: fixture
-
 Release "funny-bunny" has been upgraded. Happy Helming!
 LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC
 NAMESPACE: default
diff --git a/cmd/helm/testdata/output/upgrade-with-wait.txt b/cmd/helm/testdata/output/upgrade-with-wait.txt
index 092c813a23c8ab7941df34d94f540c5ce069a7a2..11d66d8d34fc5bce1302e804809267e6a21a6e8d 100644
--- a/cmd/helm/testdata/output/upgrade-with-wait.txt
+++ b/cmd/helm/testdata/output/upgrade-with-wait.txt
@@ -1,47 +1,3 @@
-REVISION: 2
-RELEASED: Fri Sep  2 22:04:05 1977
-CHART: testUpgradeChart-0.1.0
-USER-SUPPLIED VALUES:
-name: "value"
-COMPUTED VALUES:
-affinity: {}
-fullnameOverride: ""
-image:
-  pullPolicy: IfNotPresent
-  repository: nginx
-  tag: stable
-ingress:
-  annotations: {}
-  enabled: false
-  hosts:
-  - chart-example.local
-  path: /
-  tls: []
-name: value
-nameOverride: ""
-nodeSelector: {}
-replicaCount: 1
-resources: {}
-service:
-  port: 80
-  type: ClusterIP
-tolerations: []
-
-HOOKS:
----
-# pre-install-hook
-apiVersion: v1
-kind: Job
-metadata:
-  annotations:
-    "helm.sh/hook": pre-install
-
-MANIFEST:
-apiVersion: v1
-kind: Secret
-metadata:
-  name: fixture
-
 Release "crazy-bunny" has been upgraded. Happy Helming!
 LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC
 NAMESPACE: default
diff --git a/cmd/helm/testdata/output/upgrade.txt b/cmd/helm/testdata/output/upgrade.txt
index 2a31c7ea72c20e2b781720454606ad5610a84850..53227b1923b2e8840b784db8e1475d1272e8c5f9 100644
--- a/cmd/helm/testdata/output/upgrade.txt
+++ b/cmd/helm/testdata/output/upgrade.txt
@@ -1,47 +1,3 @@
-REVISION: 2
-RELEASED: Fri Sep  2 22:04:05 1977
-CHART: testUpgradeChart-0.1.0
-USER-SUPPLIED VALUES:
-name: "value"
-COMPUTED VALUES:
-affinity: {}
-fullnameOverride: ""
-image:
-  pullPolicy: IfNotPresent
-  repository: nginx
-  tag: stable
-ingress:
-  annotations: {}
-  enabled: false
-  hosts:
-  - chart-example.local
-  path: /
-  tls: []
-name: value
-nameOverride: ""
-nodeSelector: {}
-replicaCount: 1
-resources: {}
-service:
-  port: 80
-  type: ClusterIP
-tolerations: []
-
-HOOKS:
----
-# pre-install-hook
-apiVersion: v1
-kind: Job
-metadata:
-  annotations:
-    "helm.sh/hook": pre-install
-
-MANIFEST:
-apiVersion: v1
-kind: Secret
-metadata:
-  name: fixture
-
 Release "funny-bunny" has been upgraded. Happy Helming!
 LAST DEPLOYED: 1977-09-02 22:04:05 +0000 UTC
 NAMESPACE: default
diff --git a/cmd/helm/upgrade_test.go b/cmd/helm/upgrade_test.go
index 4b689297e71190782d762b04c29771ee56f58ce3..c75b50b1ad14f8d49230dca07af61fa1109d6346 100644
--- a/cmd/helm/upgrade_test.go
+++ b/cmd/helm/upgrade_test.go
@@ -17,9 +17,6 @@ limitations under the License.
 package main
 
 import (
-	"io/ioutil"
-	"os"
-	"path/filepath"
 	"testing"
 
 	"k8s.io/helm/pkg/chartutil"
@@ -29,8 +26,7 @@ import (
 )
 
 func TestUpgradeCmd(t *testing.T) {
-	tmpChart, _ := ioutil.TempDir("testdata", "tmp")
-	defer os.RemoveAll(tmpChart)
+	tmpChart := testTempDir(t)
 	cfile := &chart.Metadata{
 		Name:        "testUpgradeChart",
 		Description: "A Helm chart for Kubernetes",
@@ -38,9 +34,12 @@ func TestUpgradeCmd(t *testing.T) {
 	}
 	chartPath, err := chartutil.Create(cfile, tmpChart)
 	if err != nil {
-		t.Errorf("Error creating chart for upgrade: %v", err)
+		t.Fatalf("Error creating chart for upgrade: %v", err)
+	}
+	ch, err := chartutil.Load(chartPath)
+	if err != nil {
+		t.Fatalf("Error loading chart: %v", err)
 	}
-	ch, _ := chartutil.Load(chartPath)
 	_ = helm.ReleaseMock(&helm.MockReleaseOptions{
 		Name:  "funny-bunny",
 		Chart: ch,
@@ -55,11 +54,11 @@ func TestUpgradeCmd(t *testing.T) {
 
 	chartPath, err = chartutil.Create(cfile, tmpChart)
 	if err != nil {
-		t.Errorf("Error creating chart: %v", err)
+		t.Fatalf("Error creating chart: %v", err)
 	}
 	ch, err = chartutil.Load(chartPath)
 	if err != nil {
-		t.Errorf("Error loading updated chart: %v", err)
+		t.Fatalf("Error loading updated chart: %v", err)
 	}
 
 	// update chart version again
@@ -71,22 +70,22 @@ func TestUpgradeCmd(t *testing.T) {
 
 	chartPath, err = chartutil.Create(cfile, tmpChart)
 	if err != nil {
-		t.Errorf("Error creating chart: %v", err)
+		t.Fatalf("Error creating chart: %v", err)
 	}
 	var ch2 *chart.Chart
 	ch2, err = chartutil.Load(chartPath)
 	if err != nil {
-		t.Errorf("Error loading updated chart: %v", err)
+		t.Fatalf("Error loading updated chart: %v", err)
 	}
 
-	missingDepsPath := filepath.Join("testdata/testcharts/chart-missing-deps")
-	badDepsPath := filepath.Join("testdata/testcharts/chart-bad-requirements")
+	missingDepsPath := "testdata/testcharts/chart-missing-deps"
+	badDepsPath := "testdata/testcharts/chart-bad-requirements"
 
 	relMock := func(n string, v int, ch *chart.Chart) *release.Release {
 		return helm.ReleaseMock(&helm.MockReleaseOptions{Name: n, Version: v, Chart: ch})
 	}
 
-	tests := []releaseCase{
+	tests := []cmdTestCase{
 		{
 			name:   "upgrade a release",
 			cmd:    "upgrade funny-bunny " + chartPath,
@@ -142,5 +141,5 @@ func TestUpgradeCmd(t *testing.T) {
 			wantError: true,
 		},
 	}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/cmd/helm/version_test.go b/cmd/helm/version_test.go
index 166b78f93fd6a221efe44674f1524f941a105de6..0573dbf06ff1d0fa76970c07c6238b2e7a59f060 100644
--- a/cmd/helm/version_test.go
+++ b/cmd/helm/version_test.go
@@ -20,7 +20,7 @@ import (
 )
 
 func TestVersion(t *testing.T) {
-	tests := []releaseCase{{
+	tests := []cmdTestCase{{
 		name:   "default",
 		cmd:    "version",
 		golden: "output/version.txt",
@@ -29,5 +29,5 @@ func TestVersion(t *testing.T) {
 		cmd:    "version --template='Version: {{.Version}}'",
 		golden: "output/version-template.txt",
 	}}
-	testReleaseCmd(t, tests)
+	runTestCmd(t, tests)
 }
diff --git a/internal/test/test.go b/internal/test/test.go
index 6dbff7b90de6979540ec1e4cffe3e8a77a80315b..a61c32a8396cd1df507f448902abd50c803790fe 100644
--- a/internal/test/test.go
+++ b/internal/test/test.go
@@ -42,7 +42,7 @@ func AssertGoldenBytes(t TestingT, actual []byte, filename string) {
 	t.Helper()
 
 	if err := compare(actual, path(filename)); err != nil {
-		t.Fatalf("%+v", err)
+		t.Fatalf("%v", err)
 	}
 }
 
@@ -50,7 +50,7 @@ func AssertGoldenString(t TestingT, actual, filename string) {
 	t.Helper()
 
 	if err := compare([]byte(actual), path(filename)); err != nil {
-		t.Fatalf("%+v", err)
+		t.Fatalf("%v", err)
 	}
 }
 
diff --git a/pkg/helm/environment/environment_test.go b/pkg/helm/environment/environment_test.go
index ebc5822b48d87941785f7f5710ed9211df2ebdaf..3f506b09972eec772ea899ddda44439192ab1920 100644
--- a/pkg/helm/environment/environment_test.go
+++ b/pkg/helm/environment/environment_test.go
@@ -71,11 +71,10 @@ func TestEnvSettings(t *testing.T) {
 		},
 	}
 
-	cleanup := resetEnv()
-	defer cleanup()
-
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			defer resetEnv()()
+
 			for k, v := range tt.envars {
 				os.Setenv(k, v)
 			}
@@ -103,8 +102,6 @@ func TestEnvSettings(t *testing.T) {
 			if settings.KubeContext != tt.kcontext {
 				t.Errorf("expected kube-context %q, got %q", tt.kcontext, settings.KubeContext)
 			}
-
-			cleanup()
 		})
 	}
 }