From looking at your code, it appears to me that when you insert new records in your test class, your trigger fires causing an update of Opportunity. if (Trigger.isInsert){ .... for (Opportunity o : insertedOpps){ ..... } else if (o.Ramp_Profile__c == 'Standard'){ // set different values } } // ==> update oppsToUpdate; When the above happens, this causes the trigger to fire again in the same execution context. Unless you add a boolean flag of some kind to prevent it, the trigger will fire again and do an after update in this execution context. When that happens, you'll see the same `trigger.old`as existed the first time the trigger fired in the `AfterInsert` context. This happens **before** you ever do the update in your test class and may be what you're seeing in your debug logs. This same recursion will occur in your `AfterUpdate` handler code if you don't do something to prevent it. More than anything, I recommend you add debug statements in your test class to obtain the values of your important variables after insertion of `Opportunities1` and following your query to get list `opportunities`. You'll also benefit from inserting debug statements in your code after `update opportunities;` (can be placed after `Test.stopTest();` if you prefer). Once you have things sorted, your class should include assertions of what you expect those values to be instead of the debug statements following `Test.stopTest();`