Ask Search:
Martijn ReekmansMartijn Reekmans 

Trigger testing: how to?

Ok, so I am trying to create my first simple trigger. What I've done so far:

 

1. Created the trigger in my sandbox

 

trigger getUsableEventDueDate on Event(before insert, before update) 
{ Event[] checkEvents= Trigger.new; for(Event e : checkEvents){ e.UsableDueDate__c = e.StartDateTime;}}

 

2. Downloaded Eclipse 3.6 & installed the Force.com IDE

 

3. Created a new Force.com project & downloaded the trigger from my sandbox in Eclipse

 

 

I know that now I have to test the trigger first (and get a 75% coverage) before i can deploy it to my production environnement, but that is exactly my problem.
 

I have consulted several manuals and have read mutliple topics on the internet, but I just can't figure out how to test a trigger..

 

 

What should I do next? Can anyone help me with the next and final steps in deploying my trigger to production?

 

 

Thanks very much in advance!

  

Matt BrownMatt Brown
Ok you might be better served by posting this on the Apex Developer Discussion Board.
Martijn ReekmansMartijn Reekmans

I did. But maybe there was someone here who could help me out as well.

Tom FoxTom Fox
Here you go, this should work.....

/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 *
 * Unit tests are class methods that verify whether a particular piece
 * of code is working properly. Unit test methods take no arguments,
 * commit no data to the database, and are flagged with the testMethod
 * keyword in the method definition.
 *
 * All test methods in an organization are executed whenever Apex code is deployed
 * to a production organization to confirm correctness, ensure code
 * coverage, and prevent regressions. All Apex classes are
 * required to have at least 75% code coverage in order to be deployed
 * to a production organization. In addition, all triggers must have some code coverage.
 *
 * The @isTest class annotation indicates this class only contains test
 * methods. Classes defined with the @isTest annotation do not count against
 * the organization size limit for all Apex scripts.
 *
         // TO DO: implement unit test
        /**

        /*
 * See the Apex Language Reference for more information about Testing and Code Coverage.
 */
        //COMMENT: Every test class starts with "@isTest" so that SF knows it is a test class and doesn't count against your org's limits
@isTest
private class EventTester {

    static testMethod void myUnitTest() {
        //COMMENT: First, prepare Dummy Account for relating to Event
        Account acct1 = new Account(name='test account1',Type='Customer');
        insert acct1;

        //COMMENT: First, prepare Dummy Event
        Event EventToCreate = new Event(WhatId=acct1.Id,Subject='TESTING',StartDateTime=Today());
           insert EventToCreate;

//COMMENT: Inserting the event with a start date value should have caused your trigger to fire which means you can move on to the verification steps
//Cont'd: however, if you have a trigger based on updating or something, be aware that you would perform that action before verification and AFTER
//Cont'd: inserting your dummy records inside of the test class.
       
//COMMENT:  Verify correct action using System asserts (these make sure your trigger did what it is supposed to)
    //COMMENT:  first, we locate the Event that has been updated (as opposed to the event that was inserted, because the trigger has changed that origianl event
        Event EvtUpd = [select UsableDueDate__c, StartDateTime from Event where id = :EventToCreate.Id];
    //COMMENT:  then we assert that the field we updated equals the field it was updated from
        System.assert(EvtUpd.UsableDueDate__c == EventToCreate.StartDateTime);
    }
}

You might have to tweak it a bit but this should do the trick.  READ THE COMMENTS, they are designed to help you understand what is happening so you can do this for yourself in the future. 
Tom FoxTom Fox
One other note (aside from seconding @Mattybme1's point that Developerforce is a better place for Apex issues).  Why are you doing this via Apex?  You could perform this same action via a workflow.  You are only updating a value on an Event record based on another value on an Event record.  

It's fine to do this via Apex (and a good exercise since Apex is AWESOME SAUCE), but the power of SF is all of the ways that configuration can eliminate the need for code.  It's what allows Salesforce to beat lesser CRM's like rented mules.  Well, that and the fact that and it's Community Contributors... ...;).
Martijn ReekmansMartijn Reekmans
Hehe well crmninja, be my guest... ;-)

Trust me, I've already tried that! What I want to do is create a custom formula field which calculates the number of days between the LastModifiedDate of an event and the date at which the event is actually planned (ActivityStartDate).

Only problem is that it is not possible to reference to the ActivityStartDate, neither in formula's nor in workflow rules! (http://sites.force.com/ideaexchange/ideaView?id=08730000000BqMeAAK).
So that's why I'm creating a custom field which copies the ActivityStartDate using an apex trigger.


Anyway, thanks a lot for the information concerning the tests. I'll get through it next week and hopefully I'll manage to test my trigger and deploy it to the production environnement!
Martijn ReekmansMartijn Reekmans
Ok, so I wanted to test the code you gave me last week crmninja, but I'm totally lost here lol!

Today I started Eclipse and I noticed that I couldn't access my UsableDueDate-event anymore.
So I tried creating it again, but now I don't have the possibility anymore to create a new Force.com IDE project (see below)..


User-added image

Do you happen to know what is wrong?

Thx.
Tom FoxTom Fox
You might check your password settings in properties but you don't really need eclipse to do this.  You just need a Sandbox copy of your production system.  Create a sandbox, go to Setup->App Setup->Develop-Apex Classes and you can create this class there.  Then, when it works, you can use Change Sets to migrate the code to production.  

If you really want use Eclipse, you should go to Developerforce.com to troubleshoot this (it's really a different question all together).
Martijn ReekmansMartijn Reekmans

Damn why do they make it so hard! The trigger is working in my sandbox ffs! How difficult can it be to deploy it to production!! :-)

Ok, so let's skip Eclipse for the moment and do it via the apex class in my sandbox.

@isTest
private class EventTester {
static testMethod void myUnitTest() {
Account acct1 = new Account(name='test account1',Type='Customer');
insert acct1;

Event EventToCreate = new Event(WhatId=acct1.Id,Subject='TESTING',StartDateTime=Today());
insert EventToCreate;

Event EvtUpd = [select UsableDueDate__c, StartDateTime from Event where id = :EventToCreate.Id];

System.assert(EvtUpd.UsableDueDate__c == EventToCreate.StartDateTime);

    }
}


When I create a new apex class with the above, I get the following error message:

Error: Compile Error: Method does not exist or incorrect signature: Today() at line 12 column 81


I would really appreciate it if you could help me out with this crmninja!

Tom FoxTom Fox
try replacing "Today()" with "date.today()".  Let's see how that works.

Don't fret about SF.  Once you get the hang of it, you will realize how easy they have made it.
Martijn ReekmansMartijn Reekmans
-

Yea I know. Salesforce is a great tool, but it's just frustrating that for these kind of things (triggers, apex, visualforce..) I just don't have enough knowledge, experience..and I seem to have no clue at all of what I'm doing :s

Anyway I changed today () in date.today () and managed to save the test class.


I did a test run, and this is the result I get:

User-added image
 

Tom FoxTom Fox
I hear where you are coming from.  It's the classic "Pain Funnel", right?  And at the moment, you are in the thinnest portion of it.  But, keep reminding yourself of two things.  First of all, Thomas Edison's classic axiom about a thousand failures actually being a thousand successful eliminations of obstacles.  Secondly, 
"Turn off the lights and I'll glow
To the extreme I rock a mic like a vandal
Light up a stage and wax a chump like a candle "

which has no bearing on this issue whatsoever, but, I promise, if you rap that under your breath, you'll feel better about overcoming any issue in front of you.  Vanilla Ice will NEVER let you down!

So, onto your issue.  This actually ties to the first quote. SF is telling you exactly what is wrong and this is exactly why we make test classes.  You have a required field on the Event object that needs to have a value before we can insert it.  Thankfully, SF has been kind enough to give you the name of the field so copy that value and the paste it into the following section of our Test Class....

Event(WhatId=acct1.Id,Subject='TESTING',StartDateTime=Today(),PutFieldHere=PutValueHere);

Then you need to put some sort of value in that field.  I don't work with Events ever so, I'm going to take a shot in the dark here but that sounds like some sort of numberic field (days? minutes? seconds?) so we can probably just replace "
PutValueHere" with 1)  ....author's note: I looked at the "Event Fields" section of App Setup/Activities and found the Duration field.  I confirmed that it is a number field so putting 1 in it SHOULD work.  If that doesn't, you might try some sort of 15 min or 30 min increment.

This is the part of Apex coding that takes a little getting used to.  Now that you have the first save taken care of, you have to keep running the Test Class and seeing what SF tells you.  As with the example above, it's going to do a good job of walking you through the issues.  You just have to learn how to talk "computer"

Martijn ReekmansMartijn Reekmans
I really appreciate you trying to help me with this!!

I already was about to adjust the DurationInMinutes when I received your email with the confirmation.


The next error message that I get now is less clear to me:

System.AssertException: Assertion Failed
Class.EventTester.myUnitTest: line 19, column 1 External entry point


It's the last line of code in the test class so I think that once this is solved, it should be ok!


Any idea what is wrong with the assertion?
Tom FoxTom Fox
Perfect, you are correct, that is the last thing that can trip us up.  

The good news is you don't even have to have this line in.  You could comment it out (by adding doubl-backslashes before the line and probably be on your merry way.

However, the bad news is that this line is what validates that your trigger is doing what it should.  What I would do if I was in your shoes is add to system debug lines and then look at the debug logs in the sandbox.  I would do this b/c the notification message that we are receiving is saying that the value we are trying to add to the custom field is not matching the value of the field we should be deriving it from. 

Here is a revision to put in your code....

    //COMMENT:  then we assert that the field we updated equals the field it was updated from
                                    System.debug('updated events date'+EvtUpd.UsableDueDate__c);
                                    System.debug('source events date'+EventToCreate.StartDateTime);

        System.assert(EvtUpd.UsableDueDate__c == EventToCreate.StartDateTime);

then, go to administration setup->monitoring->debug logs and add a debug log for your user.  Then, in the front end of salesforce, enter an event.  Then you can go to the debug log and search for "Updated Events Date" or "Source Events Date"

Martijn ReekmansMartijn Reekmans
New day, same frustrations :)

Ok so I changed the code and replaced the assert line with the debug lines.

Then I did a test run of the class and everything looked ok: no failure, 100% of code covered

User-added image


I successfully managed to upload the outbound change with the apex trigger to production.
When validating the inbound change set I get the following message:

User-added image


How is this possible? I have no idea what went wrong..
Tom FoxTom Fox
Was there any other information provided?  I would expect some sort of message that notes the nature of the failure.  Common causes are fields in the trigger that are not in production, object permissions, user rights.  

You could setup your debug logging in production and see if the test run by the change set causes logging to occur (i'm not sure if it does or not).
Martijn ReekmansMartijn Reekmans
No, that's the only information I get.

All the rest should be fine in production: field is created, workflow is ok, no specific object permissions..

Setting up debug logs in production results in nothing.


If in the sandbox 100% of the code is covered, why on earth do I get 0% in production? :s


Maybe I should log a case at Salesforce?
Tom FoxTom Fox
Calling support never hurts but this is definitely something on the config side and not some sort of bug, at least, I feel confident that it's not a bug.  

You could try uploading the test class first and THEN the trigger, though I doubt that will do the trick.  There is something that the trigger/test class is expecting that is not in place and is causing the failure.  You've tested the workflow and field in production, correct? 
Martijn ReekmansMartijn Reekmans
Ow...do I also have to upload the test class to production because I only uploaded the trigger itself...?
Tom FoxTom Fox
Yes, I suppose I should have covered that to begin with because it's not really intuitive, now that I think about it.  Production will not know about a test class unless you upload it to production, so it needs to be included with the trigger/class being uploaded.
Martijn ReekmansMartijn Reekmans
Hmm strange...I posted a few hours ago but now my comment is gone! :o

Anyway, the trigger is deployed to production and is working perfectly.
Including the test class in the outbound change set dit the trick!

Conclusion after all this:
1. Triggers are not my cup of tea
2. I still have a lot to learn before i will be able talk 'computer'
3. Without your help I would have been nowhere!

So thanks for your patience and help in guiding me through this!

Much appreciated!
Tom FoxTom Fox
No problem.  Do not be discouraged by triggers, it's actually quite awesome that you completed your first.  Congratulations and I hope this makes for a Happier "Festivus" for you.  Keep at it and soon you'll be answering questions here for others.