Search
Twitter

Entries in unit tests (2)

Friday
Dec072012

Apex Unit Test

 

SALESFORCE APEX CODE LIMITS

I’ve been developing code on various platforms for years, but lately I’ve been working on Saleforce’s proprietary language apex.  If you know java then apex should not be that strange to you at all.  That is pretty much where the similarities end.  Being a cloud based company, Salesforce enforces all sorts of rules and limits on your code. You’ll quickly learn how to be a smarter developer when you have to think about these limits. 

 Salesforce requires that you have 75% coverage on all code you write.  If you fall below this number then you cannot deploy any of the code you have written.  Coverage just means that if you have piece of code that says “hello” you must test it and verify that it says hello.  If not, every line is counted against your overall number.  You cover your code by writing the infamous unit tests.

Rewind to last month and it is really easy to forget or ignore writing test cases.  You can only get away with this for so long before your coverage starts gradually depleting.  After much effort I did a good job addressing a lot of missing coverage.  One thing that became really evident is that I was failing to do a negative test.  A negative test is just what it sounds like.  You pass in junk data and expect a failure.  This proves that your code not only works, but it handles exceptions correctly.  Below I have some sample code that illustrates both a positive and a negative test case.

 

           static testMethod void testremoveFormulaFieldsSchema()

           {

             

              //Negative Test of formula field schema

              Map<String, Schema.SObjectField> targetSchemaFieldMap = null;

              targetSchemaFieldMap = removeFormulaFieldsSchema(targetSchemaFieldMap);

              system.assert(targetSchemaFieldMap == null, 'We did not get a null schema ');

             

              //Positive Test of formula field schema

              targetSchemaFieldMap = Schema.SObjectType.Account.fields.getMap();

              targetSchemaFieldMap = removeFormulaFieldsSchema(targetSchemaFieldMap);

              system.assert(targetSchemaFieldMap != null, 'We failed to get the account schema ');

             

     }

As you can see above I call the same method “removeFormulaFieldsSchema” in both scenarios but in the first test I am passing null as a parameter.  This will test our code on how I handle exceptions and I expect nothing back after the code is executed.  In the second example I would expect data to be returned to me.  I also included the actual method I was testing for clarity below.  These two tests gave me 100% coverage in my new method and I was a happy person.

 

       public static Map<String, Schema.SObjectField> removeFormulaFieldsSchema(Map<String, Schema.SObjectField> schemaMap)

       {

         Map<String, Schema.SObjectField>  resultschema = new Map<String, Schema.SObjectField>();

 

              try

              {   

                for(String field : schemaMap.keyset())

                {

      

                  Schema.DescribeFieldResult desribeResult = schemaMap.get(field).getDescribe();

      

                  if (!desribeResult.isCalculated())

                  {

                    //Field is not a formula field so it is added to the schema.

                    Schema.SObjectField fieldS = schemaMap.get(field); 

                    resultschema.put(field,fieldS);

                  }

               }

                 return resultschema;

              }catch(exception e)

                {

                     return schemaMap;

                }

}

I hope this helps some apex coders out there to understand the importance of getting your unit test written with your new code.  It was a lot of effort to go back and fix all the omissions but it paid off.  I even found some bugs in the code that I didn’t expect.  Who would have thought that unit testing actually works and isn’t just some evil chore Salesforce imposes on us.

 

photo credit: <a href="http://www.flickr.com/photos/epospisil/5596869376/">epospisil</a> via <a href="http://photopin.com">photopin</a> <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/">cc</a>

Friday
Jun242011

Unit Tests on the Salesforce Development Platform, Force.com

The Salesforce development platform, Force.com, requires that at least 75% of Apex code in an org be executed in unit tests before the code can be deployed in a production environment.  These tests are important because they allow you to ensure that your code works as expected and planned, and enable you to build a functioning foundation and grow from there.  Such tests also help to keep your code clean as you continue developing it, and they can provide you with a history of that development process should you need it for other tasks or purposes.

When writing your unit test, be sure that they create their own data to execute against.  Doing so will ensure that your tests can be run time and time again and that they aren’t dependent on a particular configuration and setup.  Moving beyond such a setup can lead to failure.

When writing your unit tests, be sure they are thorough.  The 75% coverage is a minimum set by Salesforce, but best practices dictate that you should always strive for the highest possible coverage.  Your guide should be your own level of confidence that your unit tests fully verify that your code works as it is supposed and that you can convey that confidence to any users.

Like the scientific method whereby experiments and their results should be repeatable, your unit tests and their results should always be consistent and repeatable.  Once you’re confident that your tests can be run with consistency, you can trust that if they fail, they’ve found true bugs that need your attention.   Salesforce reports that some common mistakes that can stop unit tests from being repeated are relying on hardcoded URLs (unit tests are written in dev or sandbox orgs, which will have different URLs than production orgs), and relying on hardcoded records IDs (records IDs are specific to the org the records resides in).

Lastly, unit tests should be laser-focused on a specific and single aspect of your code.  Each test needs to be independent from all other tests that are run in your code.

I’ve learned to follow these steps in developing my code, and they’ve served me well.