diff --git a/android/module.go b/android/module.go
index 516fa78..d1a779d 100644
--- a/android/module.go
+++ b/android/module.go
@@ -193,6 +193,7 @@
 	GetProperties() []interface{}
 
 	BuildParamsForTests() []BuildParams
+	RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
 	VariablesForTests() map[string]string
 }
 
@@ -477,6 +478,7 @@
 
 	// For tests
 	buildParams []BuildParams
+	ruleParams  map[blueprint.Rule]blueprint.RuleParams
 	variables   map[string]string
 
 	prefer32 func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool
@@ -496,6 +498,10 @@
 	return a.buildParams
 }
 
+func (a *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
+	return a.ruleParams
+}
+
 func (a *ModuleBase) VariablesForTests() map[string]string {
 	return a.variables
 }
@@ -795,6 +801,10 @@
 		variables:              make(map[string]string),
 	}
 
+	if ctx.config.captureBuild {
+		ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
+	}
+
 	desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
 	var suffix []string
 	if ctx.Os().Class != Device && ctx.Os().Class != Generic {
@@ -854,6 +864,7 @@
 	}
 
 	a.buildParams = ctx.buildParams
+	a.ruleParams = ctx.ruleParams
 	a.variables = ctx.variables
 }
 
@@ -877,6 +888,7 @@
 
 	// For tests
 	buildParams []BuildParams
+	ruleParams  map[blueprint.Rule]blueprint.RuleParams
 	variables   map[string]string
 }
 
@@ -952,7 +964,13 @@
 func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
 	argNames ...string) blueprint.Rule {
 
-	return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
+	rule := a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
+
+	if a.config.captureBuild {
+		a.ruleParams[rule] = params
+	}
+
+	return rule
 }
 
 func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
diff --git a/android/register.go b/android/register.go
index 93c2870..d79982a 100644
--- a/android/register.go
+++ b/android/register.go
@@ -61,7 +61,7 @@
 		if makevars, ok := singleton.(SingletonMakeVarsProvider); ok {
 			registerSingletonMakeVarsProvider(makevars)
 		}
-		return singletonAdaptor{singleton}
+		return &singletonAdaptor{Singleton: singleton}
 	}
 }
 
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index f738faf..f157ab7 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -364,17 +364,26 @@
 	_, errs = ctx.PrepareBuildActions(config)
 	FailIfErrored(t, errs)
 
-	foo := ctx.ModuleForTests("foo", "").Rule("rule")
+	check := func(t *testing.T, params TestingBuildParams, wantOutput string) {
+		if len(params.RuleParams.CommandDeps) != 1 || params.RuleParams.CommandDeps[0] != "cp" {
+			t.Errorf("want RuleParams.CommandDeps = [%q], got %q", "cp", params.RuleParams.CommandDeps)
+		}
 
-	// TODO: make RuleParams accessible to tests and verify rule.Command().Tools() ends up in CommandDeps
+		if len(params.Implicits) != 1 || params.Implicits[0].String() != "bar" {
+			t.Errorf("want Implicits = [%q], got %q", "bar", params.Implicits.Strings())
+		}
 
-	if len(foo.Implicits) != 1 || foo.Implicits[0].String() != "bar" {
-		t.Errorf("want foo.Implicits = [%q], got %q", "bar", foo.Implicits.Strings())
+		if len(params.Outputs) != 1 || params.Outputs[0].String() != wantOutput {
+			t.Errorf("want Outputs = [%q], got %q", wantOutput, params.Outputs.Strings())
+		}
 	}
 
-	wantOutput := filepath.Join(buildDir, ".intermediates", "foo", "foo")
-	if len(foo.Outputs) != 1 || foo.Outputs[0].String() != wantOutput {
-		t.Errorf("want foo.Outputs = [%q], got %q", wantOutput, foo.Outputs.Strings())
-	}
-
+	t.Run("module", func(t *testing.T) {
+		check(t, ctx.ModuleForTests("foo", "").Rule("rule"),
+			filepath.Join(buildDir, ".intermediates", "foo", "foo"))
+	})
+	t.Run("singleton", func(t *testing.T) {
+		check(t, ctx.SingletonForTests("rule_builder_test").Rule("rule"),
+			filepath.Join(buildDir, "baz"))
+	})
 }
diff --git a/android/singleton.go b/android/singleton.go
index 05ec6b5..a59d54a 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -76,10 +76,31 @@
 
 type singletonAdaptor struct {
 	Singleton
+
+	buildParams []BuildParams
+	ruleParams  map[blueprint.Rule]blueprint.RuleParams
 }
 
-func (s singletonAdaptor) GenerateBuildActions(ctx blueprint.SingletonContext) {
-	s.Singleton.GenerateBuildActions(singletonContextAdaptor{ctx})
+var _ testBuildProvider = (*singletonAdaptor)(nil)
+
+func (s *singletonAdaptor) GenerateBuildActions(ctx blueprint.SingletonContext) {
+	sctx := &singletonContextAdaptor{SingletonContext: ctx}
+	if sctx.Config().captureBuild {
+		sctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams)
+	}
+
+	s.Singleton.GenerateBuildActions(sctx)
+
+	s.buildParams = sctx.buildParams
+	s.ruleParams = sctx.ruleParams
+}
+
+func (s *singletonAdaptor) BuildParamsForTests() []BuildParams {
+	return s.buildParams
+}
+
+func (s *singletonAdaptor) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
+	return s.ruleParams
 }
 
 type Singleton interface {
@@ -88,35 +109,45 @@
 
 type singletonContextAdaptor struct {
 	blueprint.SingletonContext
+
+	buildParams []BuildParams
+	ruleParams  map[blueprint.Rule]blueprint.RuleParams
 }
 
-func (s singletonContextAdaptor) Config() Config {
+func (s *singletonContextAdaptor) Config() Config {
 	return s.SingletonContext.Config().(Config)
 }
 
-func (s singletonContextAdaptor) DeviceConfig() DeviceConfig {
+func (s *singletonContextAdaptor) DeviceConfig() DeviceConfig {
 	return DeviceConfig{s.Config().deviceConfig}
 }
 
-func (s singletonContextAdaptor) Variable(pctx PackageContext, name, value string) {
+func (s *singletonContextAdaptor) Variable(pctx PackageContext, name, value string) {
 	s.SingletonContext.Variable(pctx.PackageContext, name, value)
 }
 
-func (s singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule {
-	return s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...)
+func (s *singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule {
+	rule := s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...)
+	if s.Config().captureBuild {
+		s.ruleParams[rule] = params
+	}
+	return rule
 }
 
-func (s singletonContextAdaptor) Build(pctx PackageContext, params BuildParams) {
+func (s *singletonContextAdaptor) Build(pctx PackageContext, params BuildParams) {
+	if s.Config().captureBuild {
+		s.buildParams = append(s.buildParams, params)
+	}
 	bparams := convertBuildParams(params)
 	s.SingletonContext.Build(pctx.PackageContext, bparams)
 
 }
 
-func (s singletonContextAdaptor) SetNinjaBuildDir(pctx PackageContext, value string) {
+func (s *singletonContextAdaptor) SetNinjaBuildDir(pctx PackageContext, value string) {
 	s.SingletonContext.SetNinjaBuildDir(pctx.PackageContext, value)
 }
 
-func (s singletonContextAdaptor) Eval(pctx PackageContext, ninjaStr string) (string, error) {
+func (s *singletonContextAdaptor) Eval(pctx PackageContext, ninjaStr string) (string, error) {
 	return s.SingletonContext.Eval(pctx.PackageContext, ninjaStr)
 }
 
@@ -144,34 +175,34 @@
 	}
 }
 
-func (s singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) {
+func (s *singletonContextAdaptor) VisitAllModulesBlueprint(visit func(blueprint.Module)) {
 	s.SingletonContext.VisitAllModules(visit)
 }
 
-func (s singletonContextAdaptor) VisitAllModules(visit func(Module)) {
+func (s *singletonContextAdaptor) VisitAllModules(visit func(Module)) {
 	s.SingletonContext.VisitAllModules(visitAdaptor(visit))
 }
 
-func (s singletonContextAdaptor) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) {
+func (s *singletonContextAdaptor) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) {
 	s.SingletonContext.VisitAllModulesIf(predAdaptor(pred), visitAdaptor(visit))
 }
 
-func (s singletonContextAdaptor) VisitDepsDepthFirst(module Module, visit func(Module)) {
+func (s *singletonContextAdaptor) VisitDepsDepthFirst(module Module, visit func(Module)) {
 	s.SingletonContext.VisitDepsDepthFirst(module, visitAdaptor(visit))
 }
 
-func (s singletonContextAdaptor) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
+func (s *singletonContextAdaptor) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
 	s.SingletonContext.VisitDepsDepthFirstIf(module, predAdaptor(pred), visitAdaptor(visit))
 }
 
-func (s singletonContextAdaptor) VisitAllModuleVariants(module Module, visit func(Module)) {
+func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit func(Module)) {
 	s.SingletonContext.VisitAllModuleVariants(module, visitAdaptor(visit))
 }
 
-func (s singletonContextAdaptor) PrimaryModule(module Module) Module {
+func (s *singletonContextAdaptor) PrimaryModule(module Module) Module {
 	return s.SingletonContext.PrimaryModule(module).(Module)
 }
 
-func (s singletonContextAdaptor) FinalModule(module Module) Module {
+func (s *singletonContextAdaptor) FinalModule(module Module) Module {
 	return s.SingletonContext.FinalModule(module).(Module)
 }
diff --git a/android/testing.go b/android/testing.go
index b7a043e..b4008af 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -31,7 +31,7 @@
 
 	nameResolver := NewNameResolver(namespaceExportFilter)
 	ctx := &TestContext{
-		Context:      blueprint.NewContext(),
+		Context:      &Context{blueprint.NewContext()},
 		NameResolver: nameResolver,
 	}
 
@@ -47,7 +47,7 @@
 }
 
 type TestContext struct {
-	*blueprint.Context
+	*Context
 	preArch, preDeps, postDeps []RegisterMutatorFunc
 	NameResolver               *NameResolver
 }
@@ -65,7 +65,7 @@
 }
 
 func (ctx *TestContext) Register() {
-	registerMutators(ctx.Context, ctx.preArch, ctx.preDeps, ctx.postDeps)
+	registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps)
 
 	ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(EnvSingleton))
 }
@@ -102,6 +102,24 @@
 	return variants
 }
 
+// SingletonForTests returns a TestingSingleton for the singleton registered with the given name.
+func (ctx *TestContext) SingletonForTests(name string) TestingSingleton {
+	allSingletonNames := []string{}
+	for _, s := range ctx.Singletons() {
+		n := ctx.SingletonName(s)
+		if n == name {
+			return TestingSingleton{
+				singleton: s.(*singletonAdaptor).Singleton,
+				provider:  s.(testBuildProvider),
+			}
+		}
+		allSingletonNames = append(allSingletonNames, n)
+	}
+
+	panic(fmt.Errorf("failed to find singleton %q."+
+		"\nall singletons: %v", name, allSingletonNames))
+}
+
 // MockFileSystem causes the Context to replace all reads with accesses to the provided map of
 // filenames to contents stored as a byte slice.
 func (ctx *TestContext) MockFileSystem(files map[string][]byte) {
@@ -121,6 +139,95 @@
 	ctx.Context.MockFileSystem(files)
 }
 
+type testBuildProvider interface {
+	BuildParamsForTests() []BuildParams
+	RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
+}
+
+type TestingBuildParams struct {
+	BuildParams
+	RuleParams blueprint.RuleParams
+}
+
+func newTestingBuildParams(provider testBuildProvider, bparams BuildParams) TestingBuildParams {
+	return TestingBuildParams{
+		BuildParams: bparams,
+		RuleParams:  provider.RuleParamsForTests()[bparams.Rule],
+	}
+}
+
+func maybeBuildParamsFromRule(provider testBuildProvider, rule string) TestingBuildParams {
+	for _, p := range provider.BuildParamsForTests() {
+		if strings.Contains(p.Rule.String(), rule) {
+			return newTestingBuildParams(provider, p)
+		}
+	}
+	return TestingBuildParams{}
+}
+
+func buildParamsFromRule(provider testBuildProvider, rule string) TestingBuildParams {
+	p := maybeBuildParamsFromRule(provider, rule)
+	if p.Rule == nil {
+		panic(fmt.Errorf("couldn't find rule %q", rule))
+	}
+	return p
+}
+
+func maybeBuildParamsFromDescription(provider testBuildProvider, desc string) TestingBuildParams {
+	for _, p := range provider.BuildParamsForTests() {
+		if p.Description == desc {
+			return newTestingBuildParams(provider, p)
+		}
+	}
+	return TestingBuildParams{}
+}
+
+func buildParamsFromDescription(provider testBuildProvider, desc string) TestingBuildParams {
+	p := maybeBuildParamsFromDescription(provider, desc)
+	if p.Rule == nil {
+		panic(fmt.Errorf("couldn't find description %q", desc))
+	}
+	return p
+}
+
+func maybeBuildParamsFromOutput(provider testBuildProvider, file string) (TestingBuildParams, []string) {
+	var searchedOutputs []string
+	for _, p := range provider.BuildParamsForTests() {
+		outputs := append(WritablePaths(nil), p.Outputs...)
+		if p.Output != nil {
+			outputs = append(outputs, p.Output)
+		}
+		for _, f := range outputs {
+			if f.String() == file || f.Rel() == file {
+				return newTestingBuildParams(provider, p), nil
+			}
+			searchedOutputs = append(searchedOutputs, f.Rel())
+		}
+	}
+	return TestingBuildParams{}, searchedOutputs
+}
+
+func buildParamsFromOutput(provider testBuildProvider, file string) TestingBuildParams {
+	p, searchedOutputs := maybeBuildParamsFromOutput(provider, file)
+	if p.Rule == nil {
+		panic(fmt.Errorf("couldn't find output %q.\nall outputs: %v",
+			file, searchedOutputs))
+	}
+	return p
+}
+
+func allOutputs(provider testBuildProvider) []string {
+	var outputFullPaths []string
+	for _, p := range provider.BuildParamsForTests() {
+		outputs := append(WritablePaths(nil), p.Outputs...)
+		if p.Output != nil {
+			outputs = append(outputs, p.Output)
+		}
+		outputFullPaths = append(outputFullPaths, outputs.Strings()...)
+	}
+	return outputFullPaths
+}
+
 // TestingModule is wrapper around an android.Module that provides methods to find information about individual
 // ctx.Build parameters for verification in tests.
 type TestingModule struct {
@@ -134,91 +241,96 @@
 
 // MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Returns an empty
 // BuildParams if no rule is found.
-func (m TestingModule) MaybeRule(rule string) BuildParams {
-	for _, p := range m.module.BuildParamsForTests() {
-		if strings.Contains(p.Rule.String(), rule) {
-			return p
-		}
-	}
-	return BuildParams{}
+func (m TestingModule) MaybeRule(rule string) TestingBuildParams {
+	return maybeBuildParamsFromRule(m.module, rule)
 }
 
 // Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Panics if no rule is found.
-func (m TestingModule) Rule(rule string) BuildParams {
-	p := m.MaybeRule(rule)
-	if p.Rule == nil {
-		panic(fmt.Errorf("couldn't find rule %q", rule))
-	}
-	return p
+func (m TestingModule) Rule(rule string) TestingBuildParams {
+	return buildParamsFromRule(m.module, rule)
 }
 
 // MaybeDescription finds a call to ctx.Build with BuildParams.Description set to a the given string.  Returns an empty
 // BuildParams if no rule is found.
-func (m TestingModule) MaybeDescription(desc string) BuildParams {
-	for _, p := range m.module.BuildParamsForTests() {
-		if p.Description == desc {
-			return p
-		}
-	}
-	return BuildParams{}
+func (m TestingModule) MaybeDescription(desc string) TestingBuildParams {
+	return maybeBuildParamsFromDescription(m.module, desc)
 }
 
 // Description finds a call to ctx.Build with BuildParams.Description set to a the given string.  Panics if no rule is
 // found.
-func (m TestingModule) Description(desc string) BuildParams {
-	p := m.MaybeDescription(desc)
-	if p.Rule == nil {
-		panic(fmt.Errorf("couldn't find description %q", desc))
-	}
-	return p
-}
-
-func (m TestingModule) maybeOutput(file string) (BuildParams, []string) {
-	var searchedOutputs []string
-	for _, p := range m.module.BuildParamsForTests() {
-		outputs := append(WritablePaths(nil), p.Outputs...)
-		if p.Output != nil {
-			outputs = append(outputs, p.Output)
-		}
-		for _, f := range outputs {
-			if f.String() == file || f.Rel() == file {
-				return p, nil
-			}
-			searchedOutputs = append(searchedOutputs, f.Rel())
-		}
-	}
-	return BuildParams{}, searchedOutputs
+func (m TestingModule) Description(desc string) TestingBuildParams {
+	return buildParamsFromDescription(m.module, desc)
 }
 
 // MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
 // value matches the provided string.  Returns an empty BuildParams if no rule is found.
-func (m TestingModule) MaybeOutput(file string) BuildParams {
-	p, _ := m.maybeOutput(file)
+func (m TestingModule) MaybeOutput(file string) TestingBuildParams {
+	p, _ := maybeBuildParamsFromOutput(m.module, file)
 	return p
 }
 
 // Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
 // value matches the provided string.  Panics if no rule is found.
-func (m TestingModule) Output(file string) BuildParams {
-	p, searchedOutputs := m.maybeOutput(file)
-	if p.Rule == nil {
-		panic(fmt.Errorf("couldn't find output %q.\nall outputs: %v",
-			file, searchedOutputs))
-	}
-	return p
+func (m TestingModule) Output(file string) TestingBuildParams {
+	return buildParamsFromOutput(m.module, file)
 }
 
 // AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
 func (m TestingModule) AllOutputs() []string {
-	var outputFullPaths []string
-	for _, p := range m.module.BuildParamsForTests() {
-		outputs := append(WritablePaths(nil), p.Outputs...)
-		if p.Output != nil {
-			outputs = append(outputs, p.Output)
-		}
-		outputFullPaths = append(outputFullPaths, outputs.Strings()...)
-	}
-	return outputFullPaths
+	return allOutputs(m.module)
+}
+
+// TestingSingleton is wrapper around an android.Singleton that provides methods to find information about individual
+// ctx.Build parameters for verification in tests.
+type TestingSingleton struct {
+	singleton Singleton
+	provider  testBuildProvider
+}
+
+// Singleton returns the Singleton wrapped by the TestingSingleton.
+func (s TestingSingleton) Singleton() Singleton {
+	return s.singleton
+}
+
+// MaybeRule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Returns an empty
+// BuildParams if no rule is found.
+func (s TestingSingleton) MaybeRule(rule string) TestingBuildParams {
+	return maybeBuildParamsFromRule(s.provider, rule)
+}
+
+// Rule finds a call to ctx.Build with BuildParams.Rule set to a rule with the given name.  Panics if no rule is found.
+func (s TestingSingleton) Rule(rule string) TestingBuildParams {
+	return buildParamsFromRule(s.provider, rule)
+}
+
+// MaybeDescription finds a call to ctx.Build with BuildParams.Description set to a the given string.  Returns an empty
+// BuildParams if no rule is found.
+func (s TestingSingleton) MaybeDescription(desc string) TestingBuildParams {
+	return maybeBuildParamsFromDescription(s.provider, desc)
+}
+
+// Description finds a call to ctx.Build with BuildParams.Description set to a the given string.  Panics if no rule is
+// found.
+func (s TestingSingleton) Description(desc string) TestingBuildParams {
+	return buildParamsFromDescription(s.provider, desc)
+}
+
+// MaybeOutput finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
+// value matches the provided string.  Returns an empty BuildParams if no rule is found.
+func (s TestingSingleton) MaybeOutput(file string) TestingBuildParams {
+	p, _ := maybeBuildParamsFromOutput(s.provider, file)
+	return p
+}
+
+// Output finds a call to ctx.Build with a BuildParams.Output or BuildParams.Outputs whose String() or Rel()
+// value matches the provided string.  Panics if no rule is found.
+func (s TestingSingleton) Output(file string) TestingBuildParams {
+	return buildParamsFromOutput(s.provider, file)
+}
+
+// AllOutputs returns all 'BuildParams.Output's and 'BuildParams.Outputs's in their full path string forms.
+func (s TestingSingleton) AllOutputs() []string {
+	return allOutputs(s.provider)
 }
 
 func FailIfErrored(t *testing.T, errs []error) {
