Professional Documents
Culture Documents
1. Single Records:
This includes testing to verify that a single record produces the correct,
expected result
2. Bulk Records:
Any apex code, whether a triggers, a class or on extension may be used
for 1to 200 records we must test not only the single record case, but the bulk
cases as well.
3. Positive scenarios:
This type of component testing expect a system to save a record without error.
4. Negative scenarios:
This type of component testing expect a system to give error.
5. Restricted User:
Test whether a user with restricted access to the objects used in code sees
the expected behavior, i.e whether they can run the code or receive error
messages.
How is a test method defined?
A test method is defined as mentioned below:-
Syntax:
One advantage to creating a separate class for testing is that classes defined
with isTest don’t count against our organization limit of 6 MB for all Apex
code.
Methods of a test class can only be called from a running test, that is, a test
request.
Test methods can’t be used to test Web service callouts. Instead, use mock
callouts
non-test request.
@testSetup annotation?
Methods that are annotated with @testSetup are used to create test records once
and then access them in every test method in the test class.
Test setup methods enable us to create common test data easily and efficiently.
By setting up records once for the class, we don’t need to re-create records for each
test method.
Example: For example, we have a test class, It has two test methods and each
test method required 5 account records.So without creating 5 records for each
test method, we will create a new method with annotation @testSetup then
create only 5 account records. These records can access all test methods using
SOQL query in that test class.
What are the things to remember when we use @testSetup method?
All database changes are rolled back at the end of a test. We can’t use this method
on records that existed before the test executed. We also can’t use setCreatedDate
in methods annotated with @isTest(SeeAllData=true), because those methods have
access to all data in the org. The both parameters (Id recordId, Datetime
createdDatetime) of this method are mandatory.
What is the difference between testMethod and @isTest?
@isTest annotation is used to define the test classes which contains code to test
our application and these classes does not count against our overall code
coverage.
testmethod keyword is used to define apex test methods. Also test methods can
be defined in any apex class.
@testVisible annotation?
Some methods are declared as private so we won’t be able to call them outside
the class. However, sometimes we really want to be able to invoke it from a unit
test method.
To resolve this, we can mark the method with a @TestVisible annotation. Then
although it is still private, it is invokable from our unit test methods.
How is a class defined as a test class ?
Use @isTest annotation to define a test class.
What is the use of System.runAs() method?
All Apex code runs in system mode, where the permissions and record sharing of
the current user are not taken into account. The system method runAs enables
us to write test methods that change the user context to an existing user or a
new user so that the user’s record sharing is enforced. The runAs method doesn’t
enforce user permissions or field-level permissions, only record sharing.
The following items use the permissions granted by the user specified with runAs
running as a specific user:
Dynamic Apex Methods using with sharing or without sharing
Shared records
The original permissions are reset after runAs completes.The runAs method
ignores user license limits.
Can we use system.run as in all the methods?
System.runAs() must be used only in a test method
Can runAs help in solving mixed DML error?
We can also use the runAs method to perform mixed DML operations in our test
by enclosing the DML operations within the runAs block. In this way, we bypass
the mixed DML error that is otherwise returned when inserting or updating setup
objects together with other sObjects. The moment we do System.Runas(User u),
all the permissions of the user u are re-read form the database and re-applied to
the running context
What is Test.isRunningTest() method?
The Test.isRunningTest() method is used to identify, if the piece of code being
executed is invoked from a Test class execution or from other artefacts such as a
Trigger, Batch Job etc. Returns true if the code being executed is invoked from a
test class otherwise returns a false.
Example:
Performing web service callouts in Apex are not supported within Test
Code. Hence we could use the Test.isRunningTest() to conditionally identify and
route the execution of a code block that calls the Test Mock framework to simulate
a mock, callout response.
Use Case of Test.isRunningTest() method
When we are setting up test data from Apex test method, we need a way to
disable the triggers that will fire. It might cause “LimitException: “Too many
SOQL
queries: 101″. In this case, the triggers are not the target of the test case, hence
this scenario will cause the test method to fail. It is not necessary to disable the
trigger for every test case, instead we can use isRunningTest().
Setup up the trigger by leveraging isRunningTest(). isRunningTest() – Returns true
if the currently executing code was called by code contained in a test method,
false otherwise. Use this method if we need to run different code depending on
whether it was being called from a test
Other Usage scenarios
1. To ensure the trigger doesn’t execute the batch if Test.IsRunningTest() is true,
and then test the batch class with it’s own test method.
2. Testing callouts – in our callout code we check to see if we‘re executing within a
unit test context by checking Test.isRunningTest() and instead of getting your
callout response from an HttpResponse.send() request, you return a pre-built test
string instead.
What is the use of System.Assert/System.AssertEquals Methods?
These methods are used to ensure that the Apex code executes and returns the
expected value.
System.Assert: It accepts two parameter: First one (mandatory) is the condition
test and the second one is used to display a message in case the condition fails.
Syntax: System.assert(var1 == var2,”msg”)
System.AssertEquals: It accepts three parameters; the first two (mandatory) are
the variables that will be tested for equality or inequality, and the third (optional)
one is used to display a message in case the condition fails.
Syntax: System.assertEquals(var1, var2,”msg”);
What is the use of Test.startTest/Test.stopTest method?
Test.startTest and Test.stopTest are used for asynchronous apex, like Batch Apex
and Future calls. Calling method(s) between Test.startTest and Test.stopTest
ensure that any asynchronous transactions finish executing before Test.stopTest()
exits.
startTest()
Marks the point in our test code when our test actually begins. Use this method
when we are testing governor limits.
Usage
We can also use this method with stopTest to ensure that all asynchronous calls
that come after the startTest method are run before doing any assertions or
testing. Each test method is allowed to call this method only once.
stopTest()
Marks the point in our test code when our test ends. Use this method in
conjunction with the startTest method.
Usage
Each test method is allowed to call this method only once. Any code that executes
after the stopTest method is assigned the original limits that were in effect before
startTest was called.
Example: if our class makes 98 SOQL queries before it calls startTest, and the
first significant statement after startTest is a DML statement, the program can
now make an additional 100 queries. Once stopTest is called, however, the
program goes back into the original context, and can only make 2 additional
SOQL queries before reaching the limit of 100
Why would a developer use Test.startTest() and Test.stopTest()?
1. To avoid Apex code coverage requirements for the code between these lines.
2. To start and stop anonymous block execution when executing anonymous Apex
code
3. To indicate test code so that it does not impact Apex line count governor limits
4. To create an additional set of governor limits during the execution of a single
test class
Test.setCreatedDate?
Set the Created date field value is used to test records in Salesforce test classes
By design, test classes do not have access to our org’s data unless we explicitly set
SeeAllData=true
tests.
Know exactly what is present with regards to good and bad data
Can help improve our testing by having proper edge cases tested
How to test class for batch apex making http apex callouts?
We should be able to do this using HttpCalloutMock and Test.startTest/stopTest.
1. Test class must start with @isTest annotation if class class version is more than
25
2. Test environment support @testVisible , @testSetUp as well
3. Unit test is to test particular piece of code working properly or not .
4. Unit test method takes no argument ,commit no data to database ,send no
email ,flagged with testMethod keyword .
5. To deploy to production at-least 75% code coverage is required
6. System.debug statement are not counted as a part of apex code limit.
7. Test method and test classes are not counted as a part of code limit
9. We should not focus on the percentage of code coverage ,we should make sure
that every use case should covered including positive, negative,bulk and single
record .
Single Action -To verify that the the single record produces the correct an expected
result .
Bulk action -Any apex record trigger ,class or extension must be invoked for 1-200
records .
Positive behavior : Test every expected behavior occurs through every expected
permutation , i,e user filled out every correctly data and not go past the limit .
Negative Testcase :-Not to add future date , Not to specify negative amount.
Restricted User :-Test whether a user with restricted access used in your code .10.
Test class should be annotated with @isTest .
11 . @isTest annotation with test method is equivalent to testMethod keyword .
12. Test method should static and no void return type .
13. Test class and method default access is private ,no matter to add access
specifier .
14. classes with @isTest annotation can’t be a interface or enum .
15. Test method code can’t be invoked by non test request .
16. Stating with salesforce API 28.0 test method can not reside inside non test
classes .
17. @Testvisible annotation to make visible private methods inside test classes.
18. Test method can not be used to test web-service call out . Please use call out
mock .
19. You can’t send email from test method.
20.User, profile, organization, AsyncApexjob, Corntrigger, RecordType,
ApexClass, ApexComponent ,ApexPage we can access without (seeAllData=true) .
21. SeeAllData=true will not work for API 23 version eailer .
22. Accessing static resource test records in test class e,g List<Account>
accList=Test.loadData(Account,SobjectType,’ResourceName’).
23. Create TestFactory class with @isTest annotation to exclude from organization
code size limit .
24. @testSetup to create test records once in a method and use in every test
method in the test class .
25. We can run unit test by using Salesforce Standard UI,Force.com
IDE ,Console ,API.
26. Maximum number of test classes run per 24 hour of period is not grater of 500
or 10 multiplication of test classes of your organization.
27. As apex runs in system mode so the permission and record sharing are not
taken into account . So we need to use system.runAs to enforce record sharing .
28. System.runAs will not enforce user permission or field level permission .
29. Every test to runAs count against the total number of DML issued in the
process .
After developing an apex class or apex trigger we should write the unit tests and ensure that we are
able to execute at least 75% of the lines of code.
If you are moving the code from sandbox to sandbox regarding code coverage you won't face any
issue.
If you are moving the code from sandbox to production, you need to include all the test classes at the
time of deployment and salesforce will run all the test classes which you included for the deployment as
well as test classes which are already present in production, if the code coverage is less than
75% deployment will fail.
3. Syntax of testMethod?
@isTest
private class MyTestClass {
Before you can deploy your code or package it for the Force.com AppExchange, the following must be
true:
• 75% of your Apex code must be covered by unit tests, and all of those tests must complete
successfully.
Note the following:
- When deploying to a production organization, every unit test in your organization namespace is
executed.
- Calls to System.debug are not counted as part of Apex code coverage in unit tests.
- While only 75% of your Apex code must be covered by tests, your focus shouldn't be on the percentage
of code that is covered.
- Instead, you should make sure that every use case of your application is covered, including positive and
negative cases, as well as bulk and single record.
- This should lead to 75% or more of your code being covered by unit tests.
• Every trigger has some test coverage.
• All classes and triggers compile successfully.
Note:
Salesforce runs all tests in all organizations with Apex scripts to verify that no behavior has been altered
as a result of any service upgrades.
.When we are moving code from sandbox to production org we need to write a test class.
.Whatever code we have written we need to ensure that each and every condition is correct
Points to remember.
1)Test class does not have access to organization data but if we write
@isTest(seeAllData=true),
2)As every organization have code limit by writing @isTest above test class, the limit will
not be considered.
3)Every test class has a method declared with testmethod keyword and is static.
Syntax:
.Each test method can call the start test and stop test only once.
==>seeAllData=true
If we are defining a test class with @isTest(SeeAllData=true) then we can access data in test
class from the database under all method present in the test class. Under this case
annotating a method with @isTest(SeeAllData=false) would be ignored and you can access
database data inside this method as well.
@isTest(SeeAllData=true)
contact obj = [SELECT Id, Name from contact where name='test' LIMIT 1];
//Accessing contact from database
@isTest(SeeAllData=false)
contact obj1 = [SELECT Id, Name from contact where name='test' LIMIT 1];
==>@isTest(SeeAllData=false)
If we are defining a test class with @isTest(SeeAllData=false) then we cannot access data in
test class from the database under all method present in the test class. Under this case
annotating a method with @isTest(SeeAllData=true) would not be ignored and you can
access database data inside this method.
contact obj = [SELECT Id, Name from contact where name='test' LIMIT 1];
obj.name='test';
insert obj;
@isTest(SeeAllData=true)
contact obj1 = [SELECT Id, Name from contact where name='test' LIMIT 1];
}
}
2) We Should test "test cases" for both positive and negative test scenario.
3) Avoid using (SeeAllData=true) in test class because it might happen that the test class
pass in sandbox but fails in production if data is not present in production.
6) What is @testSetup?
Method that are annotated with @testSetup are used to create test data and we can this test
data inside every method of the test class. The testSetup method is executed first in any test
class before other methods.
7) Let say i have a test class in which i have created a testSetup method in which
i am creating a contact record. Let say i have two test method inside my test
class which is accessing this contact record. If i access this contact record in
testmethod1() and made a update to the contact record from testSetup method
and now i am accessing this contact in testmethod2(), so will i get the updated
contact record or the original unmodified contact record in testmethod2()?
testMethod2() will gets access to the original unmodified state of record, this is because
changes are rolled back after each test method finishes execution.
Using @TestVisible annotation before variable or methods or inner classes inside apex class
allows test class to access them. This annotation does not change the visibility of variable or
methods or inner classes if accessed by non-test class.
Apex class:
Test class:
@isTest
Integer rollNo=apexClassExample.rollNo;
Sometimes it may happen that in test class you are not able to satisfy certain condition in
apex class
so under this case, we can bypass this condition by writing test.isrunningtest() in apex class.
Syntax:
if(a=3 || test.isrunningtest())