Webinar FAQ: Apex Code Testing
This is an FAQ for Webinar: Apex Code -Testing and Code Coverage
if you do a testmethod in a normal class does that count toward your code limits?
Yes, only classes annotated with @isTest are not counted towards your limit.
Is there a way to run only the test for your class that you are writing without having to run every test in the entire org? This is very time consuming for us.
Yes, you can run tests for just one class in the standard UI by navigating to the class and clicking the Run Test button. This will only execute tests within the given class. The IDE also allows running tests for a given class or set of classes. In deployment, however all tests are always run to assure that code and declarative changes in your metadata are still consistent with all the tests in the production environment.
RunAs seems no longer useful because the default user models are no longer allowed to play with custom objects. What is the plan for runAs at this point?
RunAs is necessary for any code that forks on various user level attributes such as the user's profile. While standard profiles are no longer automatically granted access to custom objects, custom profiles are, and therefore, RunAs continues to be necessary when conditionals are based on user attributes and in any case where row access is managed from code, such as standard or custom object oriented.
I have installed managed package and the test classes from the package are failing due to validation rules configured in my instance. How do I correct failures from a managed package?
You can catch the exception in your setup methods and then bypass execution of the test to avoid the failure. This is not recommended for the runtime portion of the test as the running of tests on install is intended to catch incompatibilities between the application being installed and the configuration of the account into which the code is being installed. In other words, do not catch validation rule exceptions within the start/stop blocks.
We ran into an issue when we created a test user as UK-based user to test UK date formats. But the managed package was released, it failed on the deployment as the test user needed to be a US user.
This is where RunAs can help. Assumptions about the test running user should not be made. If you have locale/language specific logic you need to assure that the test runs as a user with these settings.
Setting up a test user won't work if your org's licences are all used up, will it? or has that changed in Spring 11? our test user workaround is to instantiate a User record (but not insert it) and then go System.runAs(thatUser) {} and it pops into existence
That was a bug that was fixed in the past. You may need to upgrade the API version of your class to a newer version.
Any tips to manage hardcoded string values (e.g. 'Software Opportunity') in code? Do these hardcoded values make it difficult or impossible to change the values in custom field picklists?
The best way to manage this today is to create an explicit test for this using describe methods to assert the expected string is still one of the values available.
In what cases should I use "insert sObj;" vs. "Database.insert(sObj);"?
Database.insert() should be used when inserting collections of SObjects because you can pass in an allOrNone boolean which dictates if a single row fails on insert, should the whole insert fails, or just the specific rows with errors.
Can you create your test Users/Accounts in one test class and call them in another class?
Yes, you can create test utilities in other classes and call them from a test method.
Quick question: what happens if the "stopTest()" method is not called? Can it be left as startTest() and execute? Or will it put an error?
No, it will not error but any methods you invoke after the startTest method will be measured and reported against the runtime segmentation of the execution. Without a stopTest statement, any asynchronous methods will not be executed, and thus, assertions may fail erroneously.
Do you have any suggestions for writing tests that don't inadvertently get and run on production data?
Use unique identifiers when creating test data and querying for test data.
Do you have recommendations of getting test coverage for catch blocks in try/catches?
For save exceptions, one common way to trigger the exception is to either omit a system required field value or specify a value that is invalid, e.g. a value that is too long.
I created dummy data in my test methods, but the batch process that I am testing picks up production code and I have had significant issues with this.
Make sure that you write your batch class in such a way that you can pass in a string that represents the query you want to run to find your data to operate on. That way you can pass it a string when you're running tests that will cause it to only find your test data.
"In test example you are inserting account before test.testStart(). If I have a trigger on before or after insert what happens? When will my trigger code run?"
Your trigger code will always run regardless of whether or not it is between startTest() / stopTest() or not.
Do comments in my code count towards the 2MB limit?
No, they do not.
Will future development help with the debug log and filter out SF log entries?
Yes.
Is there a way for me to get Field Id from with in Apex code. This would enable me to populate custom fields though the URL and would be very helpful.
No, there is not. Also, solutions that reverse-engineer the salesforce UI are not supported and are subject to failure with any release of Salesforce because the behavior is neither versioned nor guaranteed.
How many records are needed for bulk testing?
Technically at least 2, but I'd recommend testing with as many as you can.
Any plans to force non-code changes to run test methods? For example, when new workflows or validations break triggers or other code.
Yes. With the changes we're making around asynchronous testing we may look to extend test execution and validation against test methods.
Can we get an option in the full sandbox to simulate production deployments? Right now, full sandboxes don't enforce the 75% rule; we'd like to be able to do a dry run of our deployment
Thank you, that is a great suggestion! Product management will look to add this item to the roadmap. Please add this to the idea exchange so we can get more feedback on this idea.
Does 75% test code coverage refer to each individual class or the overall coverage of all classes?
Overall coverage of all classes. you also need to run each trigger at least once as well.
How do I test my batch Apex programs? How do I make sure batch program completes before I can assert the results?
Surround your batch invocation with Test.StartTest() and Test.StopTest(). When you call Test.StopTest() the batch job will be forced to execute and you can assert the results after. There are examples in the Apex documentation.
Are there any plans to provide more robust tools for creating test data fixtures (i.e. loading up CSV files with test data, etc., setting standard object data signatures in the web UI, etc.)
Yes, that is something we're looking into in the future.
Is there a best practice for checking to see if the expected exception was thrown? We've looked for specific error messages before and have gotten burned when the error message changes.
Changes to standard Force.com error message should be versioned. To prevent this from happening with your own error messages, abstract the error messages into their own class and refer it when throwing and checking the error message. Using and asserting on error codes instead of the message would be another possible way accomplish this.
Any plans to implement an IstTest flag to the ApexClass object for classes that have the @IsTest annotation? https://sites.secure.force.com/success/ideaView?id=08730000000K8ppAAC
Good idea, however not on our roadmap.
Will future development help with the debug log and filter out SF log entries?
Yes, this is on our dev tooling roadmap.
Any tips to manage hard coded string values (e.g. 'Software Opportunity') in code. Doesn't these hard coded values make it very difficult or impossible to change the values in custom field picklists?
You can try using custom settings for these, or custom labels. Allows you to have externally available strings that code can access.
I'd like to learn how to get more test coverage on error and exception handling code. Also, how do we add tests for code injected by SF? These two areas reduce our overall coverage to just over 76% which is close to the limit.
This link has a an example of how to test for negative conditions : How to Write Good Unit Tests
Can you provide a link that explains what Governor Limits are please?
Here is the doc page
Can you create your test Users/Accounts in one test class and call them in another class?
Yes, you can use @isTest and static methods to create test data and hand it back to other classes.
Is it possible that both a future call and other code make changes on data at same time?
Yes, although the future call's timing cannot be insured, so "at the same time" may not be reliable.
How do future calls work?
The future call takes place asynchronously -- it goes on a queue and is executed when there are spare resources.
How do we test code that's dependent on an approval process or workflow field update?
Workflow field updates should operate within the test method if the workflow is in place within the dev environment. You can control some approval process in Apex, which may let you duplicate the scenario you need.
Is it possible to create a utility class that can be used for creating test data for the various test method/classes you might create?
Yes.
I have complex test scenarios that depend on specific data sets in the development org. When installing the package, the user has to check "Ignore Apex failures while installing this package" because the data sets are missing in the installed org. What is the best way to handle this during installation?
Creating the data sets within the test class helps ensure the portability of tests.
Are there any plans to create a mock framework from within Apex so that callouts, queues, async Apex, batch Apex, etc. can be "mock" executed so the calling test method can continue executing as if that callout actually happened?
Yes, there are plans to do this in the future.
How do we get code coverage for a class generated by importing a wsdl?
You will need to create your own test classes which assert the behavior.
Where is the test data stored? In memory?
It is stored in the database temporarily, but is never committed and the transaction is rolled back.
I am running into Run Failures not on my code or test class but on other test classes that have been deployed already to Salesforce. How do I get around these errors?
Re-write the tests. They are probably failing due to relying on data in your production instance that is no longer there.
If code coverage is 100% in production and after one year, we re-run the code coverage and it falls to 65%, does that mean that Apex code is not running anymore?
It means that either there are tests failing due to other modifications made (example: added new validation rules) or that your tests were dependent on data in your production instance that has since changed.
Can you create public test classes for use as a utility test data creation class so it does not contribute to your org Apex limit?
Not at this time.
Can a test class delete production data?
No