diff --git a/cmd/cli/kubectl-kyverno/apis/v1alpha1/test.go b/cmd/cli/kubectl-kyverno/apis/v1alpha1/test.go
index e5c6f35b2e..4934bdd073 100644
--- a/cmd/cli/kubectl-kyverno/apis/v1alpha1/test.go
+++ b/cmd/cli/kubectl-kyverno/apis/v1alpha1/test.go
@@ -24,6 +24,9 @@ type Test struct {
 	// Resources are the resource to be used in the test
 	Resources []string `json:"resources,omitempty"`
 
+	// Target Resources are for policies that have mutate existing
+	TargetResources []string `json:"targetResources,omitempty"`
+
 	// Variables is the values to be used in the test
 	Variables string `json:"variables,omitempty"`
 
@@ -54,6 +57,15 @@ type CheckResult struct {
 	Error v1alpha1.Any `json:"error"`
 }
 
+type TestResourceSpec struct {
+	Group       string `json:"group,omitempty"`
+	Version     string `json:"version,omitempty"`
+	Kind        string `json:"kind,omitempty"`
+	Namespace   string `json:"namespace,omitempty"`
+	Subresource string `json:"subresource,omitempty"`
+	Name        string `json:"name,omitempty"`
+}
+
 type CheckMatch struct {
 	// Resource filters engine responses
 	Resource *v1alpha1.Any `json:"resource,omitempty"`
diff --git a/cmd/cli/kubectl-kyverno/apis/v1alpha1/test_result.go b/cmd/cli/kubectl-kyverno/apis/v1alpha1/test_result.go
index 6a9f2939cf..2f544723c6 100644
--- a/cmd/cli/kubectl-kyverno/apis/v1alpha1/test_result.go
+++ b/cmd/cli/kubectl-kyverno/apis/v1alpha1/test_result.go
@@ -67,5 +67,5 @@ type TestResult struct {
 	TestResultDeprecated `json:",inline,omitempty"`
 
 	// Resources gives us the list of resources on which the policy is going to be applied.
-	Resources []string `json:"resources"`
+	Resources []any `json:"resources"`
 }
diff --git a/cmd/cli/kubectl-kyverno/commands/apply/command.go b/cmd/cli/kubectl-kyverno/commands/apply/command.go
index 4a1e3881d3..c17a740a47 100644
--- a/cmd/cli/kubectl-kyverno/commands/apply/command.go
+++ b/cmd/cli/kubectl-kyverno/commands/apply/command.go
@@ -34,6 +34,8 @@ import (
 	"github.com/spf13/cobra"
 	admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/client-go/dynamic"
 	"k8s.io/client-go/kubernetes"
 )
@@ -60,6 +62,7 @@ type ApplyCommandConfig struct {
 	AuditWarn             bool
 	ResourcePaths         []string
 	PolicyPaths           []string
+	TargetResourcePaths   []string
 	GitBranch             string
 	warnExitCode          int
 	warnNoPassed          bool
@@ -134,6 +137,8 @@ func Command() *cobra.Command {
 	}
 	cmd.Flags().StringSliceVarP(&applyCommandConfig.ResourcePaths, "resource", "r", []string{}, "Path to resource files")
 	cmd.Flags().StringSliceVarP(&applyCommandConfig.ResourcePaths, "resources", "", []string{}, "Path to resource files")
+	cmd.Flags().StringSliceVarP(&applyCommandConfig.TargetResourcePaths, "target-resource", "", []string{}, "Path to individual files containing target resources files for policies that have mutate existing")
+	cmd.Flags().StringSliceVarP(&applyCommandConfig.TargetResourcePaths, "target-resources", "", []string{}, "Path to a directory containing target resources files for policies that have mutate existing")
 	cmd.Flags().BoolVarP(&applyCommandConfig.Cluster, "cluster", "c", false, "Checks if policies should be applied to cluster in the current context")
 	cmd.Flags().StringVarP(&applyCommandConfig.MutateLogPath, "output", "o", "", "Prints the mutated/generated resources in provided file/directory")
 	// currently `set` flag supports variable for single policy applied on single resource
@@ -189,18 +194,28 @@ func (c *ApplyCommandConfig) applyCommandHelper(out io.Writer) (*processor.Resul
 		return nil, nil, skipInvalidPolicies, nil, fmt.Errorf("failed to decode yaml (%w)", err)
 	}
 	var store store.Store
-	rc, resources1, skipInvalidPolicies, responses1, dClient, err := c.initStoreAndClusterClient(&store, skipInvalidPolicies)
-	if err != nil {
-		return rc, resources1, skipInvalidPolicies, responses1, err
-	}
 	rc, resources1, skipInvalidPolicies, responses1, policies, vaps, vapBindings, err := c.loadPolicies(skipInvalidPolicies)
 	if err != nil {
 		return rc, resources1, skipInvalidPolicies, responses1, err
 	}
-	resources, err := c.loadResources(out, policies, vaps, dClient)
+	var targetResources []*unstructured.Unstructured
+	if len(c.TargetResourcePaths) > 0 {
+		targetResources, err = c.loadResources(out, c.TargetResourcePaths, policies, vaps, nil)
+		if err != nil {
+			return rc, resources1, skipInvalidPolicies, responses1, err
+		}
+	}
+
+	rc, resources1, skipInvalidPolicies, responses1, dClient, err := c.initStoreAndClusterClient(&store, skipInvalidPolicies, targetResources...)
 	if err != nil {
 		return rc, resources1, skipInvalidPolicies, responses1, err
 	}
+
+	resources, err := c.loadResources(out, c.ResourcePaths, policies, vaps, dClient)
+	if err != nil {
+		return rc, resources1, skipInvalidPolicies, responses1, err
+	}
+
 	var exceptions []*kyvernov2.PolicyException
 	if c.inlineExceptions {
 		exceptions = exception.SelectFrom(resources)
@@ -339,6 +354,7 @@ func (c *ApplyCommandConfig) applyPolicytoResource(
 			Stdin:                c.Stdin,
 			Rc:                   &rc,
 			PrintPatchResource:   true,
+			Cluster:              c.Cluster,
 			Client:               dClient,
 			AuditWarn:            c.AuditWarn,
 			Subresources:         vars.Subresources(),
@@ -362,8 +378,8 @@ func (c *ApplyCommandConfig) applyPolicytoResource(
 	return &rc, resources, responses, nil
 }
 
-func (c *ApplyCommandConfig) loadResources(out io.Writer, policies []kyvernov1.PolicyInterface, vap []admissionregistrationv1beta1.ValidatingAdmissionPolicy, dClient dclient.Interface) ([]*unstructured.Unstructured, error) {
-	resources, err := common.GetResourceAccordingToResourcePath(out, nil, c.ResourcePaths, c.Cluster, policies, vap, dClient, c.Namespace, c.PolicyReport, "")
+func (c *ApplyCommandConfig) loadResources(out io.Writer, paths []string, policies []kyvernov1.PolicyInterface, vap []admissionregistrationv1beta1.ValidatingAdmissionPolicy, dClient dclient.Interface) ([]*unstructured.Unstructured, error) {
+	resources, err := common.GetResourceAccordingToResourcePath(out, nil, paths, c.Cluster, policies, vap, dClient, c.Namespace, c.PolicyReport, "")
 	if err != nil {
 		return resources, fmt.Errorf("failed to load resources (%w)", err)
 	}
@@ -429,7 +445,7 @@ func (c *ApplyCommandConfig) loadPolicies(skipInvalidPolicies SkippedInvalidPoli
 	return nil, nil, skipInvalidPolicies, nil, policies, vaps, vapBindings, nil
 }
 
-func (c *ApplyCommandConfig) initStoreAndClusterClient(store *store.Store, skipInvalidPolicies SkippedInvalidPolicies) (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, dclient.Interface, error) {
+func (c *ApplyCommandConfig) initStoreAndClusterClient(store *store.Store, skipInvalidPolicies SkippedInvalidPolicies, targetResources ...*unstructured.Unstructured) (*processor.ResultCounts, []*unstructured.Unstructured, SkippedInvalidPolicies, []engineapi.EngineResponse, dclient.Interface, error) {
 	store.SetLocal(true)
 	store.SetRegistryAccess(c.RegistryAccess)
 	if c.Cluster {
@@ -455,6 +471,18 @@ func (c *ApplyCommandConfig) initStoreAndClusterClient(store *store.Store, skipI
 			return nil, nil, skipInvalidPolicies, nil, nil, err
 		}
 	}
+	if len(targetResources) > 0 && !c.Cluster {
+		var targets []runtime.Object
+		for _, t := range targetResources {
+			targets = append(targets, t)
+		}
+
+		dClient, err = dclient.NewFakeClient(runtime.NewScheme(), map[schema.GroupVersionResource]string{}, targets...)
+		dClient.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
+		if err != nil {
+			return nil, nil, skipInvalidPolicies, nil, nil, err
+		}
+	}
 	return nil, nil, skipInvalidPolicies, nil, dClient, err
 }
 
diff --git a/cmd/cli/kubectl-kyverno/commands/test/command.go b/cmd/cli/kubectl-kyverno/commands/test/command.go
index 87670876f8..6676c0789d 100644
--- a/cmd/cli/kubectl-kyverno/commands/test/command.go
+++ b/cmd/cli/kubectl-kyverno/commands/test/command.go
@@ -17,7 +17,6 @@ import (
 	"github.com/sergi/go-diff/diffmatchpatch"
 	"github.com/spf13/cobra"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
-	"k8s.io/client-go/tools/cache"
 )
 
 func Command() *cobra.Command {
@@ -127,7 +126,7 @@ func testCommandExecute(
 			if err := printTestResult(filteredResults, responses, rc, &resultsTable, test.Fs, resourcePath); err != nil {
 				return fmt.Errorf("failed to print test result (%w)", err)
 			}
-			if err := printCheckResult(test.Test.Checks, responses, rc, &resultsTable); err != nil {
+			if err := printCheckResult(test.Test.Checks, *responses, rc, &resultsTable); err != nil {
 				return fmt.Errorf("failed to print test result (%w)", err)
 			}
 			fullTable.AddFailed(resultsTable.RawRows...)
@@ -152,19 +151,15 @@ func testCommandExecute(
 	return nil
 }
 
-func checkResult(test v1alpha1.TestResult, fs billy.Filesystem, resoucePath string, response engineapi.EngineResponse, rule engineapi.RuleResponse) (bool, string, string) {
+func checkResult(test v1alpha1.TestResult, fs billy.Filesystem, resoucePath string, response engineapi.EngineResponse, rule engineapi.RuleResponse, actualResource unstructured.Unstructured) (bool, string, string) {
 	expected := test.Result
 	// fallback to the deprecated field
 	if expected == "" {
 		expected = test.Status
 	}
 	// fallback on deprecated field
-	patchedResource := test.PatchedResource
-	if test.PatchedResources != "" {
-		patchedResource = test.PatchedResources
-	}
-	if patchedResource != "" {
-		equals, diff, err := getAndCompareResource([]*unstructured.Unstructured{&response.PatchedResource}, fs, filepath.Join(resoucePath, patchedResource))
+	if test.PatchedResource != "" {
+		equals, diff, err := getAndCompareResource(actualResource, fs, filepath.Join(resoucePath, test.PatchedResource))
 		if err != nil {
 			return false, err.Error(), "Resource error"
 		}
@@ -175,14 +170,14 @@ func checkResult(test v1alpha1.TestResult, fs billy.Filesystem, resoucePath stri
 		}
 	}
 	if test.GeneratedResource != "" {
-		equals, diff, err := getAndCompareResource(rule.GeneratedResources(), fs, filepath.Join(resoucePath, test.GeneratedResource))
+		equals, diff, err := getAndCompareResource(actualResource, fs, filepath.Join(resoucePath, test.GeneratedResource))
 		if err != nil {
 			return false, err.Error(), "Resource error"
 		}
 		if !equals {
 			dmp := diffmatchpatch.New()
 			legend := dmp.DiffPrettyText(dmp.DiffMain("only in expected", "only in actual", false))
-			return false, fmt.Sprintf("Generated resource didn't match the generated resource in the test result\n(%s)\n\n%s", legend, diff), "Resource diff"
+			return false, fmt.Sprintf("Patched resource didn't match the generated resource in the test result\n(%s)\n\n%s", legend, diff), "Resource diff"
 		}
 	}
 	result := report.ComputePolicyReportResult(false, response, rule)
@@ -192,27 +187,6 @@ func checkResult(test v1alpha1.TestResult, fs billy.Filesystem, resoucePath stri
 	return true, result.Message, "Ok"
 }
 
-func lookupEngineResponses(test v1alpha1.TestResult, resourceName string, responses ...engineapi.EngineResponse) []engineapi.EngineResponse {
-	matches := make([]engineapi.EngineResponse, 0, len(responses))
-	for _, response := range responses {
-		policy := response.Policy()
-		resource := response.Resource
-		pName := cache.MetaObjectToName(policy.MetaObject()).String()
-		rName := cache.MetaObjectToName(&resource).String()
-		if test.Kind != resource.GetKind() {
-			continue
-		}
-		if pName != test.Policy {
-			continue
-		}
-		if resourceName != "" && rName != resourceName && resource.GetName() != resourceName {
-			continue
-		}
-		matches = append(matches, response)
-	}
-	return matches
-}
-
 func lookupRuleResponses(test v1alpha1.TestResult, responses ...engineapi.RuleResponse) []engineapi.RuleResponse {
 	var matches []engineapi.RuleResponse
 	// Since there are no rules in case of validating admission policies, responses are returned without checking rule names.
diff --git a/cmd/cli/kubectl-kyverno/commands/test/compare.go b/cmd/cli/kubectl-kyverno/commands/test/compare.go
index 5feaa28aac..26aa307434 100644
--- a/cmd/cli/kubectl-kyverno/commands/test/compare.go
+++ b/cmd/cli/kubectl-kyverno/commands/test/compare.go
@@ -11,41 +11,26 @@ import (
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 )
 
-func getAndCompareResource(actualResources []*unstructured.Unstructured, fs billy.Filesystem, path string) (bool, string, error) {
-	expectedResources, err := resource.GetResourceFromPath(fs, path)
+func getAndCompareResource(actualResource unstructured.Unstructured, fs billy.Filesystem, path string) (bool, string, error) {
+	expectedResource, err := resource.GetResourceFromPath(fs, path, actualResource.GetAPIVersion(), actualResource.GetKind(), actualResource.GetNamespace(), actualResource.GetName())
 	if err != nil {
 		return false, "", fmt.Errorf("error: failed to load resource (%s)", err)
 	}
+	resource.FixupGenerateLabels(actualResource)
+	resource.FixupGenerateLabels(*expectedResource)
 
-	expectedResourcesMap := map[string]unstructured.Unstructured{}
-	for _, expectedResource := range expectedResources {
-		if expectedResource == nil {
-			continue
-		}
-		r := *expectedResource
-		resource.FixupGenerateLabels(r)
-		expectedResourcesMap[expectedResource.GetNamespace()+"/"+expectedResource.GetName()] = r
+	equals, err := resource.Compare(actualResource, *expectedResource, true)
+	if err != nil {
+		return false, "", fmt.Errorf("error: failed to compare resources (%s)", err)
 	}
-
-	for _, actualResource := range actualResources {
-		if actualResource == nil {
-			continue
-		}
-		r := *actualResource
-		resource.FixupGenerateLabels(r)
-		equals, err := resource.Compare(r, expectedResourcesMap[r.GetNamespace()+"/"+r.GetName()], true)
-		if err != nil {
-			return false, "", fmt.Errorf("error: failed to compare resources (%s)", err)
-		}
-		if !equals {
-			log.Log.V(4).Info("Resource diff", "expected", expectedResourcesMap[r.GetNamespace()+"/"+r.GetName()], "actual", r)
-			es, _ := yaml.Marshal(expectedResourcesMap[r.GetNamespace()+"/"+r.GetName()])
-			as, _ := yaml.Marshal(r)
-			dmp := diffmatchpatch.New()
-			diffs := dmp.DiffMain(string(es), string(as), false)
-			log.Log.V(4).Info("\n" + dmp.DiffPrettyText(diffs) + "\n")
-			return false, dmp.DiffPrettyText(diffs), nil
-		}
+	if !equals {
+		log.Log.V(4).Info("Resource diff", "expected", expectedResource, "actual", actualResource)
+		es, _ := yaml.Marshal(expectedResource)
+		as, _ := yaml.Marshal(actualResource)
+		dmp := diffmatchpatch.New()
+		diffs := dmp.DiffMain(string(es), string(as), false)
+		log.Log.V(4).Info("\n" + dmp.DiffPrettyText(diffs) + "\n")
+		return false, dmp.DiffPrettyText(diffs), nil
 	}
 	return true, "", nil
 }
diff --git a/cmd/cli/kubectl-kyverno/commands/test/output.go b/cmd/cli/kubectl-kyverno/commands/test/output.go
index eee1cb17e1..2a20b0d35e 100644
--- a/cmd/cli/kubectl-kyverno/commands/test/output.go
+++ b/cmd/cli/kubectl-kyverno/commands/test/output.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"fmt"
 	"io"
+	"strings"
 
 	"github.com/go-git/go-billy/v5"
 	"github.com/kyverno/kyverno-json/pkg/engine/assert"
@@ -12,12 +13,13 @@ import (
 	"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/output/color"
 	"github.com/kyverno/kyverno/cmd/cli/kubectl-kyverno/output/table"
 	engineapi "github.com/kyverno/kyverno/pkg/engine/api"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
 func printCheckResult(
 	checks []v1alpha1.CheckResult,
-	responses []engineapi.EngineResponse,
+	responses TestResponse,
 	rc *resultCounts,
 	resultsTable *table.Table,
 ) error {
@@ -25,7 +27,10 @@ func printCheckResult(
 	testCount := 1
 	for _, check := range checks {
 		// filter engine responses
-		matchingEngineResponses := responses
+		var matchingEngineResponses []engineapi.EngineResponse
+		for _, engineresponses := range responses.Trigger {
+			matchingEngineResponses = append(matchingEngineResponses, engineresponses...)
+		}
 		// 1. by resource
 		if check.Match.Resource != nil {
 			var filtered []engineapi.EngineResponse
@@ -160,9 +165,10 @@ func printCheckResult(
 	return nil
 }
 
+// a test that contains a policy that may contain several rules
 func printTestResult(
 	tests []v1alpha1.TestResult,
-	responses []engineapi.EngineResponse,
+	responses *TestResponse,
 	rc *resultCounts,
 	resultsTable *table.Table,
 	fs billy.Filesystem,
@@ -170,80 +176,144 @@ func printTestResult(
 ) error {
 	testCount := 1
 	for _, test := range tests {
-		// lookup matching engine responses (without the resource name)
-		// to reduce the search scope
-		responses := lookupEngineResponses(test, "", responses...)
-		// TODO fix deprecated fields
-		// identify the resources to be looked up
 		var resources []string
-		if test.Resources != nil {
-			resources = append(resources, test.Resources...)
-		} else if test.Resource != "" {
-			resources = append(resources, test.Resource)
+		// The test specifies certain resources to check, results will be checked for those resources only
+		if test.Resource != "" {
+			test.Resources = append(test.Resources, test.Resource)
 		}
-		for _, resource := range resources {
-			var rows []table.Row
-			// lookup matching engine responses (with the resource name this time)
-			for _, response := range lookupEngineResponses(test, resource, responses...) {
-				// lookup matching rule responses
-				for _, rule := range lookupRuleResponses(test, response.PolicyResponse.Rules...) {
-					// perform test checks
-					ok, message, reason := checkResult(test, fs, resoucePath, response, rule)
-					// if checks failed but we were expecting a fail it's considered a success
-					success := ok || (!ok && test.Result == policyreportv1alpha2.StatusFail)
-					row := table.Row{
-						RowCompact: table.RowCompact{
-							ID:        testCount,
-							Policy:    color.Policy("", test.Policy),
-							Rule:      color.Rule(test.Rule),
-							Resource:  color.Resource(test.Kind, test.Namespace, resource),
-							Reason:    reason,
-							IsFailure: !success,
-						},
-						Message: message,
-					}
-					if success {
-						row.Result = color.ResultPass()
-						if test.Result == policyreportv1alpha2.StatusSkip {
-							rc.Skip++
-						} else {
-							rc.Pass++
+		if test.Resources != nil {
+			for _, r := range test.Resources {
+				for _, m := range []map[string][]engineapi.EngineResponse{responses.Target, responses.Trigger} {
+					for resourceGVKAndName := range m {
+						nameParts := strings.Split(resourceGVKAndName, ",")
+						if resourceString, ok := r.(string); ok {
+							nsAndName := strings.Split(resourceString, "/")
+							if len(nsAndName) == 1 {
+								if resourceString == nameParts[len(nameParts)-1] {
+									resources = append(resources, resourceGVKAndName)
+								}
+							}
+							if len(nsAndName) == 2 {
+								if nsAndName[0] == nameParts[len(nameParts)-2] && nsAndName[1] == nameParts[len(nameParts)-1] {
+									resources = append(resources, resourceGVKAndName)
+								}
+							}
 						}
-					} else {
-						row.Result = color.ResultFail()
-						rc.Fail++
-					}
-					testCount++
-					rows = append(rows, row)
-				}
 
-				// if there are no RuleResponse, the resource has been excluded. This is a pass.
-				if len(rows) == 0 {
-					row := table.Row{
-						RowCompact: table.RowCompact{
-							ID:        testCount,
-							Policy:    color.Policy("", test.Policy),
-							Rule:      color.Rule(test.Rule),
-							Resource:  color.Resource(test.Kind, test.Namespace, resource),
-							Result:    color.ResultPass(),
-							Reason:    color.Excluded(),
-							IsFailure: false,
-						},
-						Message: color.Excluded(),
+						if resourceSpec, ok := r.(v1alpha1.TestResourceSpec); ok {
+							if resourceSpec.Group == "" {
+								if resourceSpec.Version != nameParts[0] {
+									continue
+								}
+							} else {
+								if resourceSpec.Group+"/"+resourceSpec.Version != nameParts[0] {
+									continue
+								}
+							}
+							if resourceSpec.Namespace != nameParts[len(nameParts)-2] {
+								continue
+							}
+							if resourceSpec.Name == nameParts[len(nameParts)-1] {
+								resources = append(resources, resourceGVKAndName)
+							}
+						}
 					}
-					rc.Skip++
-					testCount++
-					rows = append(rows, row)
 				}
 			}
-			// if not found
-			if len(rows) == 0 {
+		}
+
+		// The test specifies no resources, check all results
+		if len(resources) == 0 {
+			for r := range responses.Target {
+				resources = append(resources, r)
+			}
+			for r := range responses.Trigger {
+				resources = append(resources, r)
+			}
+		}
+
+		for _, resource := range resources {
+			var rows []table.Row
+			var resourceSkipped bool
+			if _, ok := responses.Trigger[resource]; ok {
+				for _, response := range responses.Trigger[resource] {
+					polNameNs := strings.Split(test.Policy, "/")
+					if response.Policy().GetName() != polNameNs[len(polNameNs)-1] {
+						continue
+					}
+					for _, rule := range lookupRuleResponses(test, response.PolicyResponse.Rules...) {
+						r := response.Resource
+
+						if rule.RuleType() != "Generation" {
+							if rule.RuleType() == "Mutation" {
+								r = response.PatchedResource
+							}
+
+							ok, message, reason := checkResult(test, fs, resoucePath, response, rule, r)
+							if strings.Contains(message, "not found in manifest") {
+								resourceSkipped = true
+								continue
+							}
+
+							success := ok || (!ok && test.Result == policyreportv1alpha2.StatusFail)
+							resourceRows := createRowsAccordingToResults(test, rc, &testCount, success, message, reason, strings.Replace(resource, ",", "/", -1))
+							rows = append(rows, resourceRows...)
+						} else {
+							generatedResources := rule.GeneratedResources()
+							for _, r := range generatedResources {
+								ok, message, reason := checkResult(test, fs, resoucePath, response, rule, *r)
+
+								success := ok || (!ok && test.Result == policyreportv1alpha2.StatusFail)
+								resourceRows := createRowsAccordingToResults(test, rc, &testCount, success, message, reason, r.GetName())
+								rows = append(rows, resourceRows...)
+							}
+						}
+					}
+
+					// if there are no RuleResponse, the resource has been excluded. This is a pass.
+					if len(rows) == 0 && !resourceSkipped {
+						row := table.Row{
+							RowCompact: table.RowCompact{
+								ID:        testCount,
+								Policy:    color.Policy("", test.Policy),
+								Rule:      color.Rule(test.Rule),
+								Resource:  color.Resource(test.Kind, test.Namespace, strings.Replace(resource, ",", "/", -1)),
+								Result:    color.ResultPass(),
+								Reason:    color.Excluded(),
+								IsFailure: false,
+							},
+							Message: color.Excluded(),
+						}
+						rc.Skip++
+						testCount++
+						rows = append(rows, row)
+					}
+				}
+			}
+
+			// Check if the resource specified exists in the targets
+			if _, ok := responses.Target[resource]; ok {
+				for _, response := range responses.Target[resource] {
+					// we are doing this twice which is kinda not nice
+					nameParts := strings.Split(resource, ",")
+					name, ns, kind, apiVersion := nameParts[len(nameParts)-1], nameParts[len(nameParts)-2], nameParts[len(nameParts)-3], nameParts[len(nameParts)-4]
+
+					r, rule := extractPatchedTargetFromEngineResponse(apiVersion, kind, name, ns, response)
+					ok, message, reason := checkResult(test, fs, resoucePath, response, *rule, *r)
+
+					success := ok || (!ok && test.Result == policyreportv1alpha2.StatusFail)
+					resourceRows := createRowsAccordingToResults(test, rc, &testCount, success, message, reason, strings.Replace(resource, ",", "/", -1))
+					rows = append(rows, resourceRows...)
+				}
+			}
+
+			if len(rows) == 0 && !resourceSkipped {
 				row := table.Row{
 					RowCompact: table.RowCompact{
 						ID:        testCount,
 						Policy:    color.Policy("", test.Policy),
 						Rule:      color.Rule(test.Rule),
-						Resource:  color.Resource(test.Kind, test.Namespace, resource),
+						Resource:  color.Resource(test.Kind, test.Namespace, strings.Replace(resource, ",", "/", -1)),
 						IsFailure: true,
 						Result:    color.ResultFail(),
 						Reason:    color.NotFound(),
@@ -261,6 +331,70 @@ func printTestResult(
 	return nil
 }
 
+func createRowsAccordingToResults(test v1alpha1.TestResult, rc *resultCounts, globalTestCounter *int, success bool, message string, reason string, resourceGVKAndName string) []table.Row {
+	resourceParts := strings.Split(resourceGVKAndName, "/")
+	rows := []table.Row{}
+	row := table.Row{
+		RowCompact: table.RowCompact{
+			ID:        *globalTestCounter,
+			Policy:    color.Policy("", test.Policy),
+			Rule:      color.Rule(test.Rule),
+			Resource:  color.Resource(strings.Join(resourceParts[:len(resourceParts)-1], "/"), test.Namespace, resourceParts[len(resourceParts)-1]),
+			Reason:    reason,
+			IsFailure: !success,
+		},
+		Message: message,
+	}
+	if success {
+		row.Result = color.ResultPass()
+		if test.Result == policyreportv1alpha2.StatusSkip {
+			rc.Skip++
+		} else {
+			rc.Pass++
+		}
+	} else {
+		row.Result = color.ResultFail()
+		rc.Fail++
+	}
+	*globalTestCounter++
+	rows = append(rows, row)
+
+	// if there are no RuleResponse, the resource has been excluded. This is a pass.
+	if len(rows) == 0 {
+		row := table.Row{
+			RowCompact: table.RowCompact{
+				ID:        *globalTestCounter,
+				Policy:    color.Policy("", test.Policy),
+				Rule:      color.Rule(test.Rule),
+				Resource:  color.Resource(strings.Join(resourceParts[:len(resourceParts)-1], "/"), test.Namespace, resourceParts[len(resourceParts)-1]), // todo: handle namespace
+				Result:    color.ResultPass(),
+				Reason:    color.Excluded(),
+				IsFailure: false,
+			},
+			Message: color.Excluded(),
+		}
+		rc.Skip++
+		*globalTestCounter++
+		rows = append(rows, row)
+	}
+	return rows
+}
+
+func extractPatchedTargetFromEngineResponse(apiVersion, kind, resourceName, resourceNamespace string, response engineapi.EngineResponse) (*unstructured.Unstructured, *engineapi.RuleResponse) {
+	for _, rule := range response.PolicyResponse.Rules {
+		r, _, _ := rule.PatchedTarget()
+		if r != nil {
+			if resourceNamespace == "" {
+				resourceNamespace = r.GetNamespace()
+			}
+			if r.GetAPIVersion() == apiVersion && r.GetKind() == kind && r.GetName() == resourceName && r.GetNamespace() == resourceNamespace {
+				return r, &rule
+			}
+		}
+	}
+	return nil, nil
+}
+
 func printFailedTestResult(out io.Writer, resultsTable table.Table, detailedResults bool) {
 	printer := table.NewTablePrinter(out)
 	for i := range resultsTable.RawRows {
diff --git a/cmd/cli/kubectl-kyverno/commands/test/test.go b/cmd/cli/kubectl-kyverno/commands/test/test.go
index ea543b59ed..cb4c453369 100644
--- a/cmd/cli/kubectl-kyverno/commands/test/test.go
+++ b/cmd/cli/kubectl-kyverno/commands/test/test.go
@@ -26,9 +26,16 @@ import (
 	engineapi "github.com/kyverno/kyverno/pkg/engine/api"
 	policyvalidation "github.com/kyverno/kyverno/pkg/validation/policy"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
 )
 
-func runTest(out io.Writer, testCase test.TestCase, registryAccess bool) ([]engineapi.EngineResponse, error) {
+type TestResponse struct {
+	Trigger map[string][]engineapi.EngineResponse
+	Target  map[string][]engineapi.EngineResponse
+}
+
+func runTest(out io.Writer, testCase test.TestCase, registryAccess bool) (*TestResponse, error) {
 	// don't process test case with errors
 	if testCase.Err != nil {
 		return nil, testCase.Err
@@ -75,6 +82,25 @@ func runTest(out io.Writer, testCase test.TestCase, registryAccess bool) ([]engi
 			fmt.Fprintln(out, "  warning: found duplicated resource", dup.Kind, dup.Name, dup.Namespace)
 		}
 	}
+
+	targetResourcesPath := path.GetFullPaths(testCase.Test.TargetResources, testDir, isGit)
+	targetResources, err := common.GetResourceAccordingToResourcePath(out, testCase.Fs, targetResourcesPath, false, results.Policies, results.VAPs, dClient, "", false, testDir)
+	if err != nil {
+		return nil, fmt.Errorf("error: failed to load target resources (%s)", err)
+	}
+
+	targets := []runtime.Object{}
+	for _, t := range targetResources {
+		targets = append(targets, t)
+	}
+
+	// this will be a dclient containing all target resources. a policy may not do anything with any targets in these
+	dClient, err = dclient.NewFakeClient(runtime.NewScheme(), map[schema.GroupVersionResource]string{}, targets...)
+	if err != nil {
+		return nil, err
+	}
+	dClient.SetDiscovery(dclient.NewFakeDiscoveryClient(nil))
+
 	// exceptions
 	fmt.Fprintln(out, "  Loading exceptions", "...")
 	exceptionFullPath := path.GetFullPaths(testCase.Test.PolicyExceptions, testDir, isGit)
@@ -164,7 +190,12 @@ func runTest(out io.Writer, testCase test.TestCase, registryAccess bool) ([]engi
 	// execute engine
 	var engineResponses []engineapi.EngineResponse
 	var resultCounts processor.ResultCounts
+	testResponse := TestResponse{
+		Trigger: map[string][]engineapi.EngineResponse{},
+		Target:  map[string][]engineapi.EngineResponse{},
+	}
 	for _, resource := range uniques {
+		// the policy processor is for multiple policies at once
 		processor := processor.PolicyProcessor{
 			Store:                     &store,
 			Policies:                  validPolicies,
@@ -177,16 +208,28 @@ func runTest(out io.Writer, testCase test.TestCase, registryAccess bool) ([]engi
 			NamespaceSelectorMap:      vars.NamespaceSelectors(),
 			Rc:                        &resultCounts,
 			RuleToCloneSourceResource: ruleToCloneSourceResource,
+			Cluster:                   false,
 			Client:                    dClient,
 			Subresources:              vars.Subresources(),
-			Out:                       out,
+			Out:                       io.Discard,
 		}
 		ers, err := processor.ApplyPoliciesOnResource()
 		if err != nil {
 			return nil, fmt.Errorf("failed to apply policies on resource %v (%w)", resource.GetName(), err)
 		}
+		resourceKey := generateResourceKey(resource)
 		engineResponses = append(engineResponses, ers...)
+		testResponse.Trigger[resourceKey] = ers
 	}
+	for _, targetResource := range targetResources {
+		for _, engineResponse := range engineResponses {
+			if r, _ := extractPatchedTargetFromEngineResponse(targetResource.GetAPIVersion(), targetResource.GetKind(), targetResource.GetName(), targetResource.GetNamespace(), engineResponse); r != nil {
+				resourceKey := generateResourceKey(targetResource)
+				testResponse.Target[resourceKey] = append(testResponse.Target[resourceKey], engineResponse)
+			}
+		}
+	}
+
 	for _, resource := range uniques {
 		processor := processor.ValidatingAdmissionPolicyProcessor{
 			Policies:             results.VAPs,
@@ -200,7 +243,13 @@ func runTest(out io.Writer, testCase test.TestCase, registryAccess bool) ([]engi
 		if err != nil {
 			return nil, fmt.Errorf("failed to apply policies on resource %s (%w)", resource.GetName(), err)
 		}
-		engineResponses = append(engineResponses, ers...)
+		resourceKey := generateResourceKey(resource)
+		testResponse.Trigger[resourceKey] = append(testResponse.Trigger[resourceKey], ers...)
 	}
-	return engineResponses, nil
+	// this is an array of responses of all policies, generated by all of their rules
+	return &testResponse, nil
+}
+
+func generateResourceKey(resource *unstructured.Unstructured) string {
+	return resource.GetAPIVersion() + "," + resource.GetKind() + "," + resource.GetNamespace() + "," + resource.GetName()
 }
diff --git a/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_tests.yaml b/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_tests.yaml
index 1357fd3002..14157d633b 100644
--- a/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_tests.yaml
+++ b/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_tests.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    controller-gen.kubebuilder.io/version: v0.15.0
+    controller-gen.kubebuilder.io/version: (devel)
   name: tests.cli.kyverno.io
 spec:
   group: cli.kyverno.io
@@ -182,6 +182,11 @@ spec:
               - result
               type: object
             type: array
+          targetResources:
+            description: Target Resources are for policies that have mutate existing
+            items:
+              type: string
+            type: array
           userinfo:
             description: UserInfo is the user info to be used in the test
             type: string
diff --git a/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_userinfoes.yaml b/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_userinfoes.yaml
index 6bd9aca6db..7820dd44f8 100644
--- a/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_userinfoes.yaml
+++ b/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_userinfoes.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    controller-gen.kubebuilder.io/version: v0.15.0
+    controller-gen.kubebuilder.io/version: (devel)
   name: userinfoes.cli.kyverno.io
 spec:
   group: cli.kyverno.io
diff --git a/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_values.yaml b/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_values.yaml
index b227d23d93..f14203c22a 100644
--- a/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_values.yaml
+++ b/cmd/cli/kubectl-kyverno/config/crds/cli.kyverno.io_values.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    controller-gen.kubebuilder.io/version: v0.15.0
+    controller-gen.kubebuilder.io/version: (devel)
   name: values.cli.kyverno.io
 spec:
   group: cli.kyverno.io
diff --git a/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_tests.yaml b/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_tests.yaml
index 1357fd3002..14157d633b 100644
--- a/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_tests.yaml
+++ b/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_tests.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    controller-gen.kubebuilder.io/version: v0.15.0
+    controller-gen.kubebuilder.io/version: (devel)
   name: tests.cli.kyverno.io
 spec:
   group: cli.kyverno.io
@@ -182,6 +182,11 @@ spec:
               - result
               type: object
             type: array
+          targetResources:
+            description: Target Resources are for policies that have mutate existing
+            items:
+              type: string
+            type: array
           userinfo:
             description: UserInfo is the user info to be used in the test
             type: string
diff --git a/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_userinfoes.yaml b/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_userinfoes.yaml
index 6bd9aca6db..7820dd44f8 100644
--- a/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_userinfoes.yaml
+++ b/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_userinfoes.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    controller-gen.kubebuilder.io/version: v0.15.0
+    controller-gen.kubebuilder.io/version: (devel)
   name: userinfoes.cli.kyverno.io
 spec:
   group: cli.kyverno.io
diff --git a/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_values.yaml b/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_values.yaml
index b227d23d93..f14203c22a 100644
--- a/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_values.yaml
+++ b/cmd/cli/kubectl-kyverno/data/crds/cli.kyverno.io_values.yaml
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   annotations:
-    controller-gen.kubebuilder.io/version: v0.15.0
+    controller-gen.kubebuilder.io/version: (devel)
   name: values.cli.kyverno.io
 spec:
   group: cli.kyverno.io
diff --git a/cmd/cli/kubectl-kyverno/fix/test.go b/cmd/cli/kubectl-kyverno/fix/test.go
index 1409aa2ea6..c6ab462e97 100644
--- a/cmd/cli/kubectl-kyverno/fix/test.go
+++ b/cmd/cli/kubectl-kyverno/fix/test.go
@@ -37,7 +37,7 @@ func FixTest(test v1alpha1.Test, compress bool) (v1alpha1.Test, []string, error)
 			messages = append(messages, "test result should not use both `resource` and `resources` fields")
 		}
 		if result.Resource != "" {
-			var resources []string
+			var resources []any
 			messages = append(messages, "test result uses deprecated `resource` field, moving it into the `resources` field")
 			resources = append(resources, result.Resources...)
 			resources = append(resources, result.Resource)
@@ -67,7 +67,13 @@ func FixTest(test v1alpha1.Test, compress bool) (v1alpha1.Test, []string, error)
 	if compress {
 		compressed := map[v1alpha1.TestResultBase][]string{}
 		for _, result := range results {
-			compressed[result.TestResultBase] = append(compressed[result.TestResultBase], result.Resources...)
+			resourcesAsStringArray := []string{}
+			for _, resource := range result.Resources {
+				if r, ok := resource.(string); ok {
+					resourcesAsStringArray = append(resourcesAsStringArray, r)
+				}
+			}
+			compressed[result.TestResultBase] = append(compressed[result.TestResultBase], resourcesAsStringArray...)
 		}
 		results = nil
 		for k, v := range compressed {
@@ -76,9 +82,13 @@ func FixTest(test v1alpha1.Test, compress bool) (v1alpha1.Test, []string, error)
 				messages = append(messages, "test results contains duplicate resources")
 				v = unique.UnsortedList()
 			}
+			anyArray := make([]interface{}, len(v))
+			for i, r := range v {
+				anyArray[i] = r
+			}
 			results = append(results, v1alpha1.TestResult{
 				TestResultBase: k,
-				Resources:      v,
+				Resources:      anyArray,
 			})
 		}
 	}
@@ -104,14 +114,25 @@ func FixTest(test v1alpha1.Test, compress bool) (v1alpha1.Test, []string, error)
 		if x := cmp.Compare(a.CloneSourceResource, b.CloneSourceResource); x != 0 {
 			return x
 		}
-		slices.Sort(a.Resources)
-		slices.Sort(b.Resources)
+		asArray1 := []string{}
+		for _, r := range a.Resources {
+			resourceString, _ := r.(string)
+			asArray1 = append(asArray1, resourceString)
+		}
+		asArray2 := []string{}
+		for _, r := range b.Resources {
+			resourceString, _ := r.(string)
+			asArray2 = append(asArray1, resourceString)
+		}
+		slices.Sort(asArray1)
+		slices.Sort(asArray2)
+
 		if x := cmp.Compare(len(a.Resources), len(b.Resources)); x != 0 {
 			return x
 		}
 		if len(a.Resources) == len(b.Resources) {
 			for i := range a.Resources {
-				if x := cmp.Compare(a.Resources[i], b.Resources[i]); x != 0 {
+				if x := cmp.Compare(asArray1[i], asArray2[i]); x != 0 {
 					return x
 				}
 			}
diff --git a/cmd/cli/kubectl-kyverno/processor/generate.go b/cmd/cli/kubectl-kyverno/processor/generate.go
index 7d6d5411e0..d311273237 100644
--- a/cmd/cli/kubectl-kyverno/processor/generate.go
+++ b/cmd/cli/kubectl-kyverno/processor/generate.go
@@ -122,6 +122,7 @@ func initializeMockController(out io.Writer, s *store.Store, gvrToListKind map[s
 		imageverifycache.DisabledImageVerifyCache(),
 		store.ContextLoaderFactory(s, nil),
 		nil,
+		nil,
 	))
 	return c, nil
 }
diff --git a/cmd/cli/kubectl-kyverno/processor/policy_processor.go b/cmd/cli/kubectl-kyverno/processor/policy_processor.go
index 5e00cd8fef..95308d4c5d 100644
--- a/cmd/cli/kubectl-kyverno/processor/policy_processor.go
+++ b/cmd/cli/kubectl-kyverno/processor/policy_processor.go
@@ -43,6 +43,7 @@ type PolicyProcessor struct {
 	MutateLogPath             string
 	MutateLogPathIsDir        bool
 	Variables                 *variables.Variables
+	Cluster                   bool
 	UserInfo                  *kyvernov2.RequestInfo
 	PolicyReport              bool
 	NamespaceSelectorMap      map[string]map[string]string
@@ -72,6 +73,7 @@ func (p *PolicyProcessor) ApplyPoliciesOnResource() ([]engineapi.EngineResponse,
 	if rclient == nil {
 		rclient = registryclient.NewOrDie()
 	}
+	isCluster := false
 	eng := engine.NewEngine(
 		cfg,
 		config.NewDefaultMetricsConfiguration(),
@@ -81,13 +83,14 @@ func (p *PolicyProcessor) ApplyPoliciesOnResource() ([]engineapi.EngineResponse,
 		imageverifycache.DisabledImageVerifyCache(),
 		store.ContextLoaderFactory(p.Store, nil),
 		exceptions.New(policyExceptionLister),
+		&isCluster,
 	)
 	gvk, subresource := resource.GroupVersionKind(), ""
 	resourceKind := resource.GetKind()
 	resourceName := resource.GetName()
 	resourceNamespace := resource.GetNamespace()
 	// If --cluster flag is not set, then we need to find the top level resource GVK and subresource
-	if p.Client == nil {
+	if !p.Cluster {
 		for _, s := range p.Subresources {
 			subgvk := schema.GroupVersionKind{
 				Group:   s.Subresource.Group,
@@ -377,6 +380,21 @@ func (p *PolicyProcessor) printOutput(resource interface{}, response engineapi.E
 		return fmt.Errorf("failed to marshal (%w)", err)
 	}
 
+	var yamlEncodedTargetResources [][]byte
+	for _, ruleResponese := range response.PolicyResponse.Rules {
+		patchedTarget, _, _ := ruleResponese.PatchedTarget()
+
+		if patchedTarget != nil {
+			yamlEncodedResource, err := yamlv2.Marshal(patchedTarget.Object)
+			if err != nil {
+				return fmt.Errorf("failed to marshal (%w)", err)
+			}
+
+			yamlEncodedResource = append(yamlEncodedResource, []byte("\n---\n")...)
+			yamlEncodedTargetResources = append(yamlEncodedTargetResources, yamlEncodedResource)
+		}
+	}
+
 	if p.MutateLogPath == "" {
 		resource := string(yamlEncodedResource) + string("\n---")
 		if len(strings.TrimSpace(resource)) > 0 {
@@ -384,6 +402,12 @@ func (p *PolicyProcessor) printOutput(resource interface{}, response engineapi.E
 				fmt.Fprintf(p.Out, "\npolicy %s applied to %s:", response.Policy().GetName(), resourcePath)
 			}
 			fmt.Fprintf(p.Out, "\n"+resource+"\n") //nolint:govet
+			if len(yamlEncodedTargetResources) > 0 {
+				fmt.Fprintf(p.Out, "patched targets: \n")
+				for _, patchedTarget := range yamlEncodedTargetResources {
+					fmt.Fprintf(p.Out, "\n"+string(patchedTarget)+"\n")
+				}
+			}
 		}
 		return nil
 	}
@@ -409,11 +433,14 @@ func (p *PolicyProcessor) printOutput(resource interface{}, response engineapi.E
 		file = f
 	}
 	if _, err := file.Write([]byte(string(yamlEncodedResource) + "\n---\n\n")); err != nil {
-		if err := file.Close(); err != nil {
-			log.Log.Error(err, "failed to close file")
-		}
 		return err
 	}
+
+	for _, patchedTarget := range yamlEncodedTargetResources {
+		if _, err := file.Write(patchedTarget); err != nil {
+			return err
+		}
+	}
 	if err := file.Close(); err != nil {
 		return err
 	}
diff --git a/cmd/cli/kubectl-kyverno/resource/resource.go b/cmd/cli/kubectl-kyverno/resource/resource.go
index 177dea42a4..fbc574a94f 100644
--- a/cmd/cli/kubectl-kyverno/resource/resource.go
+++ b/cmd/cli/kubectl-kyverno/resource/resource.go
@@ -59,7 +59,8 @@ func YamlToUnstructured(resourceYaml []byte) (*unstructured.Unstructured, error)
 	return resource, nil
 }
 
-func GetResourceFromPath(fs billy.Filesystem, path string) ([]*unstructured.Unstructured, error) {
+// should be able to specify a single resource in a multi yaml file, dont error out when there are multiple resource
+func GetResourceFromPath(fs billy.Filesystem, path string, apiVersion, kind, resourceNamespace, resourceName string) (*unstructured.Unstructured, error) {
 	var resourceBytes []byte
 	if fs == nil {
 		data, err := GetFileBytes(path)
@@ -83,10 +84,18 @@ func GetResourceFromPath(fs billy.Filesystem, path string) ([]*unstructured.Unst
 	if err != nil {
 		return nil, err
 	}
-	if len(resources) == 0 {
-		return nil, fmt.Errorf("no resources found")
+
+	for _, r := range resources {
+		name := r.GetName()
+		ns := r.GetNamespace()
+		apiv := r.GetAPIVersion()
+		k := r.GetKind()
+
+		if apiv == apiVersion && k == kind && name == resourceName && ns == resourceNamespace {
+			return r, nil
+		}
 	}
-	return resources, nil
+	return nil, fmt.Errorf("resource with name %s not found in manifest", resourceName)
 }
 
 func GetFileBytes(path string) ([]byte, error) {
diff --git a/cmd/cli/kubectl-kyverno/test/load.go b/cmd/cli/kubectl-kyverno/test/load.go
index 155d964bc7..6865c2cf69 100644
--- a/cmd/cli/kubectl-kyverno/test/load.go
+++ b/cmd/cli/kubectl-kyverno/test/load.go
@@ -84,9 +84,6 @@ func LoadTest(fs billy.Filesystem, path string) TestCase {
 func cleanTest(test *v1alpha1.Test) {
 	test.Policies = removeDuplicateStrings(test.Policies)
 	test.Resources = removeDuplicateStrings(test.Resources)
-	for index, result := range test.Results {
-		test.Results[index].Resources = removeDuplicateStrings(result.Resources)
-	}
 }
 
 func removeDuplicateStrings(strings []string) []string {
diff --git a/cmd/cli/kubectl-kyverno/test/load_test.go b/cmd/cli/kubectl-kyverno/test/load_test.go
index 17d90e544f..5f9661dad7 100644
--- a/cmd/cli/kubectl-kyverno/test/load_test.go
+++ b/cmd/cli/kubectl-kyverno/test/load_test.go
@@ -65,7 +65,7 @@ func TestLoadTests(t *testing.T) {
 						Result: policyreportv1alpha2.StatusPass,
 						Rule:   "only-allow-trusted-images",
 					},
-					Resources: []string{
+					Resources: []any{
 						"test-pod-with-non-root-user-image",
 						"test-pod-with-trusted-registry",
 					},
@@ -97,7 +97,7 @@ func TestLoadTests(t *testing.T) {
 						Rule:              "generate-limitrange",
 						GeneratedResource: "generatedLimitRange.yaml",
 					},
-					Resources: []string{"hello-world-namespace"},
+					Resources: []any{"hello-world-namespace"},
 				}, {
 					TestResultBase: v1alpha1.TestResultBase{
 						Kind:              "Namespace",
@@ -106,7 +106,7 @@ func TestLoadTests(t *testing.T) {
 						Rule:              "generate-resourcequota",
 						GeneratedResource: "generatedResourceQuota.yaml",
 					},
-					Resources: []string{"hello-world-namespace"},
+					Resources: []any{"hello-world-namespace"},
 				}},
 			},
 		}},
@@ -134,7 +134,7 @@ func TestLoadTests(t *testing.T) {
 						Result: policyreportv1alpha2.StatusPass,
 						Rule:   "only-allow-trusted-images",
 					},
-					Resources: []string{
+					Resources: []any{
 						"test-pod-with-non-root-user-image",
 						"test-pod-with-trusted-registry",
 					},
@@ -160,7 +160,7 @@ func TestLoadTests(t *testing.T) {
 						Rule:              "generate-limitrange",
 						GeneratedResource: "generatedLimitRange.yaml",
 					},
-					Resources: []string{"hello-world-namespace"},
+					Resources: []any{"hello-world-namespace"},
 				}, {
 					TestResultBase: v1alpha1.TestResultBase{
 						Kind:              "Namespace",
@@ -169,7 +169,7 @@ func TestLoadTests(t *testing.T) {
 						Rule:              "generate-resourcequota",
 						GeneratedResource: "generatedResourceQuota.yaml",
 					},
-					Resources: []string{"hello-world-namespace"},
+					Resources: []any{"hello-world-namespace"},
 				}},
 			},
 		}},
@@ -234,7 +234,7 @@ func TestLoadTest(t *testing.T) {
 						Result: policyreportv1alpha2.StatusPass,
 						Rule:   "only-allow-trusted-images",
 					},
-					Resources: []string{
+					Resources: []any{
 						"test-pod-with-non-root-user-image",
 						"test-pod-with-trusted-registry",
 					},
@@ -263,7 +263,7 @@ func TestLoadTest(t *testing.T) {
 						Result: policyreportv1alpha2.StatusPass,
 						Rule:   "only-allow-trusted-images",
 					},
-					Resources: []string{
+					Resources: []any{
 						"test-pod-with-non-root-user-image",
 						"test-pod-with-trusted-registry",
 					},
diff --git a/cmd/internal/engine.go b/cmd/internal/engine.go
index 4745e4c24d..777dbe3917 100644
--- a/cmd/internal/engine.go
+++ b/cmd/internal/engine.go
@@ -53,6 +53,7 @@ func NewEngine(
 		ivCache,
 		factories.DefaultContextLoaderFactory(configMapResolver, factories.WithAPICallConfig(apiCallConfig), factories.WithGlobalContextStore(gctxStore)),
 		exceptionsSelector,
+		nil,
 	)
 }
 
diff --git a/docs/user/cli/commands/kyverno_apply.md b/docs/user/cli/commands/kyverno_apply.md
index 582e6b7ab9..c1976beba2 100644
--- a/docs/user/cli/commands/kyverno_apply.md
+++ b/docs/user/cli/commands/kyverno_apply.md
@@ -60,6 +60,8 @@ kyverno apply [flags]
   -s, --set strings                        Variables that are required
   -i, --stdin                              Optional mutate policy parameter to pipe directly through to kubectl
   -t, --table                              Show results in table format
+      --target-resource strings            Path to individual files containing target resources files for policies that have mutate existing
+      --target-resources strings           Path to a directory containing target resources files for policies that have mutate existing
   -u, --userinfo string                    Admission Info including Roles, Cluster Roles and Subjects
   -f, --values-file string                 File containing values for policy variables
       --warn-exit-code int                 Set the exit code for warnings; if failures or errors are found, will exit 1
diff --git a/docs/user/cli/crd/index.html b/docs/user/cli/crd/index.html
index 2271866e61..6be608f0a2 100644
--- a/docs/user/cli/crd/index.html
+++ b/docs/user/cli/crd/index.html
@@ -112,6 +112,17 @@ This field is deprecated, use <code>metadata.name</code> instead</p>
 </tr>
 <tr>
 <td>
+<code>targetResources</code><br/>
+<em>
+[]string
+</em>
+</td>
+<td>
+<p>Target Resources are for policies that have mutate existing</p>
+</td>
+</tr>
+<tr>
+<td>
 <code>variables</code><br/>
 <em>
 string
@@ -655,6 +666,81 @@ Kubernetes meta/v1.APIResource
 </tbody>
 </table>
 <hr />
+<h3 id="cli.kyverno.io/v1alpha1.TestResourceSpec">TestResourceSpec
+</h3>
+<p>
+</p>
+<table class="table table-striped">
+<thead class="thead-dark">
+<tr>
+<th>Field</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>
+<code>group</code><br/>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
+<tr>
+<td>
+<code>version</code><br/>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
+<tr>
+<td>
+<code>kind</code><br/>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
+<tr>
+<td>
+<code>namespace</code><br/>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
+<tr>
+<td>
+<code>subresource</code><br/>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
+<tr>
+<td>
+<code>name</code><br/>
+<em>
+string
+</em>
+</td>
+<td>
+</td>
+</tr>
+</tbody>
+</table>
+<hr />
 <h3 id="cli.kyverno.io/v1alpha1.TestResult">TestResult
 </h3>
 <p>
@@ -706,7 +792,7 @@ TestResultDeprecated
 <td>
 <code>resources</code><br/>
 <em>
-[]string
+[]any
 </em>
 </td>
 <td>
diff --git a/docs/user/cli/crd/kyverno_kubectl.v1alpha1.html b/docs/user/cli/crd/kyverno_kubectl.v1alpha1.html
index 00fad5c552..61460d8278 100644
--- a/docs/user/cli/crd/kyverno_kubectl.v1alpha1.html
+++ b/docs/user/cli/crd/kyverno_kubectl.v1alpha1.html
@@ -193,6 +193,35 @@ This field is deprecated, use <code>metadata.name</code> instead</p>
   
     
     
+      <tr>
+        <td><code>targetResources</code>
+          
+          <span style="color:blue;"> *</span>
+          
+          </br>
+
+          
+          
+            
+              <span style="font-family: monospace">[]string</span>
+            
+          
+        </td>
+        <td>
+          
+
+          <p>Target Resources are for policies that have mutate existing</p>
+
+
+          
+
+          
+        </td>
+      </tr>
+    
+  
+    
+    
       <tr>
         <td><code>variables</code>
           
@@ -1475,7 +1504,7 @@ This field is deprecated, use <code>metadata.name</code> instead</p>
           
           
             
-              <span style="font-family: monospace">[]string</span>
+              <span style="font-family: monospace">[]any</span>
             
           
         </td>
diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go
index 8a1d0cb008..0dec3ebc49 100644
--- a/pkg/engine/engine.go
+++ b/pkg/engine/engine.go
@@ -31,6 +31,7 @@ type engine struct {
 	metricsConfiguration config.MetricsConfiguration
 	jp                   jmespath.Interface
 	client               engineapi.Client
+	isCluster            bool
 	rclientFactory       engineapi.RegistryClientFactory
 	ivCache              imageverifycache.Client
 	contextLoader        engineapi.ContextLoaderFactory
@@ -51,7 +52,12 @@ func NewEngine(
 	ivCache imageverifycache.Client,
 	contextLoader engineapi.ContextLoaderFactory,
 	exceptionSelector engineapi.PolicyExceptionSelector,
+	isCluster *bool,
 ) engineapi.Engine {
+	if isCluster == nil {
+		defaultCluster := true
+		isCluster = &defaultCluster
+	}
 	meter := otel.GetMeterProvider().Meter(metrics.MeterName)
 	resultCounter, err := meter.Int64Counter(
 		"kyverno_policy_results",
@@ -74,6 +80,7 @@ func NewEngine(
 		client:               client,
 		rclientFactory:       rclientFactory,
 		ivCache:              ivCache,
+		isCluster:            *isCluster,
 		contextLoader:        contextLoader,
 		exceptionSelector:    exceptionSelector,
 		resultCounter:        resultCounter,
@@ -107,8 +114,8 @@ func (e *engine) Mutate(
 	if internal.MatchPolicyContext(logger, e.client, policyContext, e.configuration) {
 		policyResponse, patchedResource := e.mutate(ctx, logger, policyContext)
 		response = response.
-			WithPolicyResponse(policyResponse).
-			WithPatchedResource(patchedResource)
+			WithPatchedResource(patchedResource).
+			WithPolicyResponse(policyResponse)
 	}
 	response = response.WithStats(engineapi.NewExecutionStats(startTime, time.Now()))
 	e.reportMetrics(ctx, logger, policyContext.Operation(), policyContext.AdmissionOperation(), response)
diff --git a/pkg/engine/fuzz_test.go b/pkg/engine/fuzz_test.go
index 64656e5be2..5ff73847f0 100644
--- a/pkg/engine/fuzz_test.go
+++ b/pkg/engine/fuzz_test.go
@@ -43,6 +43,7 @@ var (
 		imageverifycache.DisabledImageVerifyCache(),
 		factories.DefaultContextLoaderFactory(nil),
 		nil,
+		nil,
 	)
 	initter sync.Once
 )
@@ -126,6 +127,7 @@ func FuzzVerifyImageAndPatchTest(f *testing.F) {
 			imageverifycache.DisabledImageVerifyCache(),
 			factories.DefaultContextLoaderFactory(nil),
 			nil,
+			nil,
 		)
 
 		_, _ = verifyImageAndPatchEngine.VerifyAndPatchImages(
@@ -271,6 +273,7 @@ func FuzzMutateTest(f *testing.F) {
 			imageverifycache.DisabledImageVerifyCache(),
 			factories.DefaultContextLoaderFactory(nil),
 			nil,
+			nil,
 		)
 		e.Mutate(
 			context.Background(),
diff --git a/pkg/engine/handlers/validation/validate_cel.go b/pkg/engine/handlers/validation/validate_cel.go
index 49d9303354..f6c3c4e443 100644
--- a/pkg/engine/handlers/validation/validate_cel.go
+++ b/pkg/engine/handlers/validation/validate_cel.go
@@ -30,12 +30,14 @@ import (
 )
 
 type validateCELHandler struct {
-	client engineapi.Client
+	client    engineapi.Client
+	isCluster bool
 }
 
-func NewValidateCELHandler(client engineapi.Client) (handlers.Handler, error) {
+func NewValidateCELHandler(client engineapi.Client, isCluster bool) (handlers.Handler, error) {
 	return validateCELHandler{
-		client: client,
+		client:    client,
+		isCluster: isCluster,
 	}, nil
 }
 
@@ -140,7 +142,7 @@ func (h validateCELHandler) Process(
 		ns = ""
 	}
 	if ns != "" {
-		if h.client != nil {
+		if h.client != nil && h.isCluster {
 			namespace, err = h.client.GetNamespace(ctx, ns, metav1.GetOptions{})
 			if err != nil {
 				return resource, handlers.WithResponses(
diff --git a/pkg/engine/image_verify_test.go b/pkg/engine/image_verify_test.go
index 1bf2e51bbc..6d63988315 100644
--- a/pkg/engine/image_verify_test.go
+++ b/pkg/engine/image_verify_test.go
@@ -324,6 +324,7 @@ func testVerifyAndPatchImages(
 		imageverifycache.DisabledImageVerifyCache(),
 		factories.DefaultContextLoaderFactory(cmResolver),
 		nil,
+		nil,
 	)
 	return e.VerifyAndPatchImages(
 		ctx,
@@ -1059,6 +1060,7 @@ func testImageVerifyCache(
 		ivCache,
 		factories.DefaultContextLoaderFactory(cmResolver),
 		nil,
+		nil,
 	)
 	return e.VerifyAndPatchImages(
 		ctx,
diff --git a/pkg/engine/mutation_test.go b/pkg/engine/mutation_test.go
index 12d3c99064..fe3b5aca7e 100644
--- a/pkg/engine/mutation_test.go
+++ b/pkg/engine/mutation_test.go
@@ -42,6 +42,7 @@ func testMutate(
 		imageverifycache.DisabledImageVerifyCache(),
 		contextLoader,
 		nil,
+		nil,
 	)
 	return e.Mutate(
 		ctx,
diff --git a/pkg/engine/validation.go b/pkg/engine/validation.go
index 165343a713..7bdc087790 100644
--- a/pkg/engine/validation.go
+++ b/pkg/engine/validation.go
@@ -51,7 +51,7 @@ func (e *engine) validate(
 				} else if hasValidatePss {
 					return validation.NewValidatePssHandler()
 				} else if hasValidateCEL {
-					return validation.NewValidateCELHandler(e.client)
+					return validation.NewValidateCELHandler(e.client, e.isCluster)
 				} else {
 					return validation.NewValidateResourceHandler()
 				}
diff --git a/pkg/engine/validation_test.go b/pkg/engine/validation_test.go
index de2ec61c49..8a2a299ae7 100644
--- a/pkg/engine/validation_test.go
+++ b/pkg/engine/validation_test.go
@@ -41,6 +41,7 @@ func testValidate(
 		imageverifycache.DisabledImageVerifyCache(),
 		contextLoader,
 		nil,
+		nil,
 	)
 	return e.Validate(
 		ctx,
diff --git a/pkg/webhooks/resource/fake.go b/pkg/webhooks/resource/fake.go
index 51f7fbe677..09e2073c50 100644
--- a/pkg/webhooks/resource/fake.go
+++ b/pkg/webhooks/resource/fake.go
@@ -66,6 +66,7 @@ func NewFakeHandlers(ctx context.Context, policyCache policycache.Cache) *resour
 			imageverifycache.DisabledImageVerifyCache(),
 			factories.DefaultContextLoaderFactory(configMapResolver),
 			exceptions.New(peLister),
+			nil,
 		),
 	}
 }
diff --git a/pkg/webhooks/resource/validation_test.go b/pkg/webhooks/resource/validation_test.go
index f13c84abac..d0a28167d1 100644
--- a/pkg/webhooks/resource/validation_test.go
+++ b/pkg/webhooks/resource/validation_test.go
@@ -2086,6 +2086,7 @@ func TestValidate_failure_action_overrides(t *testing.T) {
 		imageverifycache.DisabledImageVerifyCache(),
 		factories.DefaultContextLoaderFactory(nil),
 		nil,
+		nil,
 	)
 	for i, tc := range testcases {
 		t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
@@ -2188,6 +2189,7 @@ func Test_RuleSelector(t *testing.T) {
 		imageverifycache.DisabledImageVerifyCache(),
 		factories.DefaultContextLoaderFactory(nil),
 		nil,
+		nil,
 	)
 	resp := eng.Validate(
 		context.TODO(),
diff --git a/test/cli/test-mutate/add-default-resources/kyverno-test.yaml b/test/cli/test-mutate/add-default-resources/kyverno-test.yaml
index a31438600c..343ba724b3 100644
--- a/test/cli/test-mutate/add-default-resources/kyverno-test.yaml
+++ b/test/cli/test-mutate/add-default-resources/kyverno-test.yaml
@@ -7,13 +7,6 @@ policies:
 resources:
 - resource.yaml
 results:
-- kind: Pod
-  patchedResources: patchedResource1.yaml
-  policy: add-default-resources
-  resources:
-  - nginx-demo1
-  result: pass
-  rule: add-default-requests
 - kind: Pod
   patchedResources: patchedResource3.yaml
   policy: add-default-resources
@@ -21,6 +14,13 @@ results:
   - nginx-demo3
   result: pass
   rule: add-default-requests
+- kind: Pod
+  patchedResources: patchedResource1.yaml
+  policy: add-default-resources
+  resources:
+  - nginx-demo1
+  result: pass
+  rule: add-default-requests
 - kind: Pod
   patchedResources: patchedResource2.yaml
   policy: add-default-resources
diff --git a/test/cli/test-mutate/global-anchor/kyverno-test.yaml b/test/cli/test-mutate/global-anchor/kyverno-test.yaml
index e413c72631..57d1fba0b7 100644
--- a/test/cli/test-mutate/global-anchor/kyverno-test.yaml
+++ b/test/cli/test-mutate/global-anchor/kyverno-test.yaml
@@ -7,13 +7,6 @@ policies:
 resources:
 - resources.yaml
 results:
-- kind: Pod
-  patchedResources: patchedResource.yaml
-  policy: add-safe-to-evict
-  resources:
-  - pod-with-emptydir-hostpath
-  result: pass
-  rule: annotate-empty-dir
 - kind: Pod
   patchedResources: patchedResourceWithVolume.yaml
   policy: add-safe-to-evict
@@ -21,6 +14,13 @@ results:
   - pod-with-emptydir-hostpath-1
   result: pass
   rule: annotate-empty-dir
+- kind: Pod
+  patchedResources: patchedResource.yaml
+  policy: add-safe-to-evict
+  resources:
+  - pod-with-emptydir-hostpath
+  result: pass
+  rule: annotate-empty-dir
 - kind: Pod
   policy: add-safe-to-evict
   resources:
diff --git a/test/cli/test-mutate/karpenter-annotations-to-nodeselector/kyverno-test.yaml b/test/cli/test-mutate/karpenter-annotations-to-nodeselector/kyverno-test.yaml
index 6d88fcb8a4..241eadfaa2 100644
--- a/test/cli/test-mutate/karpenter-annotations-to-nodeselector/kyverno-test.yaml
+++ b/test/cli/test-mutate/karpenter-annotations-to-nodeselector/kyverno-test.yaml
@@ -7,6 +7,12 @@ policies:
 resources:
 - resource.yaml
 results:
+- kind: Pod
+  policy: karpenter-annotations-to-nodeselector
+  resources:
+  - soft-pod-antiaffinity-1-copy
+  result: pass
+  rule: hard-nodeselector-lifecycle-on-demand
 - kind: Pod
   patchedResources: patched.yaml
   policy: karpenter-annotations-to-nodeselector
@@ -14,9 +20,3 @@ results:
   - soft-pod-antiaffinity-1
   result: pass
   rule: hard-nodeselector-lifecycle-on-demand
-- kind: Pod
-  policy: karpenter-annotations-to-nodeselector
-  resources:
-  - soft-pod-antiaffinity-1-copy
-  result: pass
-  rule: hard-nodeselector-lifecycle-on-demand
diff --git a/test/cli/test-mutate/kyverno-test.yaml b/test/cli/test-mutate/kyverno-test.yaml
index df8be89492..fc70882001 100644
--- a/test/cli/test-mutate/kyverno-test.yaml
+++ b/test/cli/test-mutate/kyverno-test.yaml
@@ -14,13 +14,6 @@ results:
   - mydeploy
   result: pass
   rule: add-label
-- kind: Pod
-  patchedResources: patchedResource3.yaml
-  policy: add-label
-  resources:
-  - production/same-name-but-diff-namespace
-  result: pass
-  rule: add-label
 - kind: Pod
   patchedResources: patchedResource6.yaml
   policy: add-label
@@ -35,6 +28,13 @@ results:
   - testing/same-name-but-diff-namespace
   result: pass
   rule: add-label
+- kind: Pod
+  patchedResources: patchedResource3.yaml
+  policy: add-label
+  resources:
+  - production/same-name-but-diff-namespace
+  result: pass
+  rule: add-label
 - kind: Pod
   patchedResources: patchedResource1.yaml
   policy: add-label
diff --git a/test/cli/test-mutate/mutate-existing-fail/kyverno-test.yaml b/test/cli/test-mutate/mutate-existing-fail/kyverno-test.yaml
new file mode 100644
index 0000000000..37619aba43
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing-fail/kyverno-test.yaml
@@ -0,0 +1,18 @@
+apiVersion: cli.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: kyverno-test.yaml
+policies:
+- policy.yaml
+resources:
+- trigger-cm.yaml
+results:
+- kind: ""
+  patchedResources: mutated-secret.yaml
+  policy: mutate-existing-secret
+  resources:
+  - secret-1
+  result: fail
+  rule: mutate-secret-on-configmap-create
+targetResources:
+- raw-secret.yaml
diff --git a/test/cli/test-mutate/mutate-existing-fail/mutated-secret.yaml b/test/cli/test-mutate/mutate-existing-fail/mutated-secret.yaml
new file mode 100755
index 0000000000..51e4b6ab0b
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing-fail/mutated-secret.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  labels:
+    otherlabel: bar
+  name: secret-1
+  namespace: staging
diff --git a/test/cli/test-mutate/mutate-existing-fail/policy.yaml b/test/cli/test-mutate/mutate-existing-fail/policy.yaml
new file mode 100755
index 0000000000..00731ebc95
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing-fail/policy.yaml
@@ -0,0 +1,27 @@
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: mutate-existing-secret
+spec:
+  rules:
+  - match:
+      any:
+      - resources:
+          kinds:
+          - ConfigMap
+          names:
+          - dictionary-1
+          namespaces:
+          - staging
+    mutate:
+      mutateExistingOnPolicyUpdate: false
+      patchStrategicMerge:
+        metadata:
+          labels:
+            foo: bar
+      targets:
+      - apiVersion: v1
+        kind: Secret
+        name: secret-1
+        namespace: staging
+    name: mutate-secret-on-configmap-create
diff --git a/test/cli/test-mutate/mutate-existing-fail/raw-secret.yaml b/test/cli/test-mutate/mutate-existing-fail/raw-secret.yaml
new file mode 100644
index 0000000000..935cb1be92
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing-fail/raw-secret.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: secret-1
+  namespace: staging
diff --git a/test/cli/test-mutate/mutate-existing-fail/trigger-cm.yaml b/test/cli/test-mutate/mutate-existing-fail/trigger-cm.yaml
new file mode 100755
index 0000000000..b458868bc4
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing-fail/trigger-cm.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+data:
+  foo: bar
+kind: ConfigMap
+metadata:
+  name: dictionary-1
+  namespace: staging
diff --git a/test/cli/test-mutate/mutate-existing/kyverno-test.yaml b/test/cli/test-mutate/mutate-existing/kyverno-test.yaml
new file mode 100644
index 0000000000..c446c3a4a3
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing/kyverno-test.yaml
@@ -0,0 +1,17 @@
+apiVersion: cli.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: kyverno-test.yaml
+policies:
+- policy.yaml
+resources:
+- trigger-cm.yaml
+results:
+- kind: ""
+  patchedResources: mutated-secret.yaml
+  policy: mutate-existing-secret
+  resources: []
+  result: pass
+  rule: mutate-secret-on-configmap-create
+targetResources:
+- raw-secret.yaml
diff --git a/test/cli/test-mutate/mutate-existing/mutated-secret.yaml b/test/cli/test-mutate/mutate-existing/mutated-secret.yaml
new file mode 100755
index 0000000000..769daa4ab5
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing/mutated-secret.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+data:
+  foo: bar
+kind: ConfigMap
+metadata:
+  name: dictionary-1
+  namespace: staging
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  labels:
+    foo: bar
+  name: secret-1
+  namespace: staging
diff --git a/test/cli/test-mutate/mutate-existing/policy.yaml b/test/cli/test-mutate/mutate-existing/policy.yaml
new file mode 100755
index 0000000000..00731ebc95
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing/policy.yaml
@@ -0,0 +1,27 @@
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: mutate-existing-secret
+spec:
+  rules:
+  - match:
+      any:
+      - resources:
+          kinds:
+          - ConfigMap
+          names:
+          - dictionary-1
+          namespaces:
+          - staging
+    mutate:
+      mutateExistingOnPolicyUpdate: false
+      patchStrategicMerge:
+        metadata:
+          labels:
+            foo: bar
+      targets:
+      - apiVersion: v1
+        kind: Secret
+        name: secret-1
+        namespace: staging
+    name: mutate-secret-on-configmap-create
diff --git a/test/cli/test-mutate/mutate-existing/raw-secret.yaml b/test/cli/test-mutate/mutate-existing/raw-secret.yaml
new file mode 100644
index 0000000000..935cb1be92
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing/raw-secret.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: secret-1
+  namespace: staging
diff --git a/test/cli/test-mutate/mutate-existing/trigger-cm.yaml b/test/cli/test-mutate/mutate-existing/trigger-cm.yaml
new file mode 100755
index 0000000000..b458868bc4
--- /dev/null
+++ b/test/cli/test-mutate/mutate-existing/trigger-cm.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+data:
+  foo: bar
+kind: ConfigMap
+metadata:
+  name: dictionary-1
+  namespace: staging
diff --git a/test/cli/test-mutate/same-name-mutate-existing/cm.yaml b/test/cli/test-mutate/same-name-mutate-existing/cm.yaml
new file mode 100755
index 0000000000..b458868bc4
--- /dev/null
+++ b/test/cli/test-mutate/same-name-mutate-existing/cm.yaml
@@ -0,0 +1,7 @@
+apiVersion: v1
+data:
+  foo: bar
+kind: ConfigMap
+metadata:
+  name: dictionary-1
+  namespace: staging
diff --git a/test/cli/test-mutate/same-name-mutate-existing/kyverno-test.yaml b/test/cli/test-mutate/same-name-mutate-existing/kyverno-test.yaml
new file mode 100644
index 0000000000..656eaa0316
--- /dev/null
+++ b/test/cli/test-mutate/same-name-mutate-existing/kyverno-test.yaml
@@ -0,0 +1,20 @@
+apiVersion: cli.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: kyverno-test.yaml
+policies:
+- policy.yaml
+resources:
+- cm.yaml
+results:
+- kind: ""
+  patchedResources: mutated-resources.yaml
+  policy: mutate-existing-secret
+  resources:
+  - staging/secret-1
+  - prod/secret-1
+  result: pass
+  rule: mutate-secret-on-configmap-create
+targetResources:
+- secret-1.yaml
+- secret-2.yaml
diff --git a/test/cli/test-mutate/same-name-mutate-existing/mutated-resources.yaml b/test/cli/test-mutate/same-name-mutate-existing/mutated-resources.yaml
new file mode 100755
index 0000000000..e8515724f4
--- /dev/null
+++ b/test/cli/test-mutate/same-name-mutate-existing/mutated-resources.yaml
@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  labels:
+    foo: bar
+  name: secret-1
+  namespace: staging
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  labels:
+    foo: bar
+  name: secret-1
+  namespace: prod
+
diff --git a/test/cli/test-mutate/same-name-mutate-existing/policy.yaml b/test/cli/test-mutate/same-name-mutate-existing/policy.yaml
new file mode 100755
index 0000000000..4fc8b6afa0
--- /dev/null
+++ b/test/cli/test-mutate/same-name-mutate-existing/policy.yaml
@@ -0,0 +1,26 @@
+apiVersion: kyverno.io/v1
+kind: ClusterPolicy
+metadata:
+  name: mutate-existing-secret
+spec:
+  rules:
+  - match:
+      any:
+      - resources:
+          kinds:
+          - ConfigMap
+          names:
+          - dictionary-1
+          namespaces:
+          - staging
+    mutate:
+      mutateExistingOnPolicyUpdate: false
+      patchStrategicMerge:
+        metadata:
+          labels:
+            foo: bar
+      targets:
+      - apiVersion: v1
+        kind: Secret
+        name: secret-1
+    name: mutate-secret-on-configmap-create
diff --git a/test/cli/test-mutate/same-name-mutate-existing/secret-1.yaml b/test/cli/test-mutate/same-name-mutate-existing/secret-1.yaml
new file mode 100644
index 0000000000..935cb1be92
--- /dev/null
+++ b/test/cli/test-mutate/same-name-mutate-existing/secret-1.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: secret-1
+  namespace: staging
diff --git a/test/cli/test-mutate/same-name-mutate-existing/secret-2.yaml b/test/cli/test-mutate/same-name-mutate-existing/secret-2.yaml
new file mode 100644
index 0000000000..00f314554d
--- /dev/null
+++ b/test/cli/test-mutate/same-name-mutate-existing/secret-2.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: secret-1
+  namespace: prod
diff --git a/test/cli/test/mutate-keda-scaled-object/kyverno-test.yaml b/test/cli/test/mutate-keda-scaled-object/kyverno-test.yaml
index 4e44f2a671..bcf45a4156 100644
--- a/test/cli/test/mutate-keda-scaled-object/kyverno-test.yaml
+++ b/test/cli/test/mutate-keda-scaled-object/kyverno-test.yaml
@@ -7,13 +7,6 @@ policies:
 resources:
 - resources.yaml
 results:
-- kind: ScaledObject
-  patchedResources: patchedResource1.yaml
-  policy: keda-prometheus-serveraddress
-  resources:
-  - service-1
-  result: pass
-  rule: keda-prometheus-serveraddress
 - kind: ScaledObject
   patchedResources: patchedResource2.yaml
   policy: keda-prometheus-serveraddress
@@ -21,6 +14,13 @@ results:
   - service-2
   result: pass
   rule: keda-prometheus-serveraddress
+- kind: ScaledObject
+  patchedResources: patchedResource1.yaml
+  policy: keda-prometheus-serveraddress
+  resources:
+  - service-1
+  result: pass
+  rule: keda-prometheus-serveraddress
 - kind: ScaledObject
   policy: keda-prometheus-serveraddress
   resources: