function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Sandra WicketSandra Wicket 

Controller Test Class Best Practise

Hello guys, 
i created a controller with following methodes. I have 96% code coverage and want to deploy my controller..

- m1 - returns a list of a wrapper class object1
- m2 - returns a list of a wrapper class object2
- m3 - creates records with values releated to m1 & m2 

So, i have created for each methode more test methodes in my test class.

for m1: 
- positive -- the list returns some records
- null - the list doesen't return some recrods
- bulk - the list shows 100 records 

for m2: 
- positive -- the list returns some records
- null - the list doesen't return some recrods
- bulk - the list shows 100 records 

for m3:
- positiv - the methode creates one record
- Null - the methode creates no record
- bulk - the methode creates 100 records

i have checked each methode with system.assertEquals.

Now, my question(s).
- is this a good strategy for my test class ?
- i have created new test data for each test methode --- is this necessary ? 
- my test class has more than 300 lines -- is this too much ? 

thanks for your time. I really want to learn how to write good test classes.


Sandra 



 
Best Answer chosen by Sandra Wicket
Amit Chaudhary 8Amit Chaudhary 8
I will recommend you to start using trailhead to learn about test classes
1) https://trailhead.salesforce.com/modules/apex_testing

Pleasse check below post sample test class
1) http://amitsalesforce.blogspot.com/2015/06/best-practice-for-test-classes-sample.html

Also please check below post
1) https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_qs_test.htm
2) https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_example.htm


You write a test class for this the same way that you would any other:
- Set up some data for the Controller to access
- Execute a method/methods:-
- Verify the behaviour with asserts.

Please follow below salesforce Best Practice for Test Classes :-

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 .


Please let us know if this post will help you
 

All Answers

Raj VakatiRaj Vakati
This links are worthy to check the best practises 


https://www.slideshare.net/jitendrazaa/apex-testing-and-best-practices
http://www.sfdc99.com/2013/11/02/principles-of-a-good-test-class/
https://prosenjit-sarkar-sfdc.blogspot.com/2017/09/salesforce-best-practices-apex-test.html

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_best_practices.htm
https://help.salesforce.com/articleView?id=000041398&type=1
http://blog.shivanathd.com/2013/11/Best-Practices-Test-Class-in-Salesforce.html
https://sfdcpanther.wordpress.com/2017/09/25/apex-test-class-best-practices/
Amit Chaudhary 8Amit Chaudhary 8
I will recommend you to start using trailhead to learn about test classes
1) https://trailhead.salesforce.com/modules/apex_testing

Pleasse check below post sample test class
1) http://amitsalesforce.blogspot.com/2015/06/best-practice-for-test-classes-sample.html

Also please check below post
1) https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_qs_test.htm
2) https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_testing_example.htm


You write a test class for this the same way that you would any other:
- Set up some data for the Controller to access
- Execute a method/methods:-
- Verify the behaviour with asserts.

Please follow below salesforce Best Practice for Test Classes :-

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 .


Please let us know if this post will help you
 
This was selected as the best answer
Sandra WicketSandra Wicket
Thanks for your help guys. I appreciate your answers, but could you give me a advice for my controller ? I already created a testclass with 300 lines and 96% code coverage. I tested each methode like i mentioned in my post.  For each methode i have checked the output. 

After your post i have deleted the test data in each methode and created a testSetup methode to reduce the test execution time.

If you want, i can post my test class.
Amit Chaudhary 8Amit Chaudhary 8
Please post your test class
Sandra WicketSandra Wicket
Thanks for your help Amit ! I owe you a beer !
 
@isTest
private class TestCreateMultiExtraBoostItems {
    
    @testSetup static void setup () {
        
        Id pricebookId = Test.getStandardPricebookId();
        
        Product2 pro = new Product2();
        pro.name = 'test';
        pro.Produktbeschreibung_detailliert__c = 'test';
        pro.Family = 'Extra Boost'; 
        pro.IsActive = true;
        insert pro;
        
        Product2 pro1 = new Product2();
        pro1.name = 'test1';
        pro1.Produktbeschreibung_detailliert__c = 'test';
        pro1.Family = 'Sonstiges'; 
        pro1.IsActive = true;
        insert pro1;
                    
        PricebookEntry pEntry = new PricebookEntry (); 
        pEntry.Product2Id = pro.id;
        pEntry.UseStandardPrice = false;
        pEntry.UnitPrice = 600; 
        pEntry.Pricebook2Id = pricebookId;
        pEntry.IsActive = true;
        insert pEntry; 
        
        PricebookEntry pEntry1 = new PricebookEntry (); 
        pEntry1.Product2Id = pro1.id;
        pEntry1.UseStandardPrice = false;
        pEntry1.UnitPrice = 600; 
        pEntry1.Pricebook2Id = pricebookId;
        pEntry1.IsActive = true;
        insert pEntry1; 
 
        Opportunity opp = new Opportunity ();
        opp.Name = 'test';
        opp.StageName = '40 - Demo Termin vereinbart';
        opp.Override_Region__c = 'München';
        opp.CloseDate = System.today();
        insert opp;
   
        OpportunityLineItem oli = new OpportunityLineItem ();
        oli.TotalPrice = 500;
        oli.Quantity = 4;
        oli.OpportunityId = opp.Id;
        oli.Product2Id = pro.id;
        oli.ON_Produktbeschreibung_detailliert__c = 'test';                            
        oli.PricebookEntryId = pEntry.id;
        insert oli;
          
        OpportunityLineItem oli1 = new OpportunityLineItem ();
        oli1.TotalPrice = 600;
        oli1.Quantity = 4;
        oli1.OpportunityId = opp.Id;
        oli1.Product2Id = pro1.id;
        oli1.ON_Produktbeschreibung_detailliert__c = 'test';                            
        oli1.PricebookEntryId = pEntry1.id;
        insert oli1;
        
        OpportunityLineItem oli2 = new OpportunityLineItem ();
        oli2.TotalPrice = 1000;
        oli2.Quantity = 4;
        oli2.OpportunityId = opp.Id;
        oli2.Product2Id = pro.id;
        oli2.ON_Produktbeschreibung_detailliert__c = 'test';                            
        oli2.PricebookEntryId = pEntry.id;
        insert oli2;
        
        List<ExtraBoost__c> exbo = new List <ExtraBoost__c>();
        for(Integer i=0; i<100; i++ ){
            ExtraBoost__c e = new ExtraBoost__c (Name='Portal'+i);
            exbo.add(e);        
            }    
        insert exbo;    
    }
    
     // test Constructor 
    @isTest private static void CreateMultiExtraBoostItemsTests(){
   
        Opportunity opp = new Opportunity ();
        opp.name = 'test';
        opp.StageName = '40 - Demo Termin vereinbart';
        opp.CloseDate = System.today();
        insert opp;
        
        PageReference testPage = Page.VF_CreateMultiExtraBoost;
        testPage.getParameters().put('id', opp.id);
        Test.setCurrentPage(testPage); 
        CreateMultiExtraBoostItems tstCtrl = new CreateMultiExtraBoostItems ();        
    } 
   	// Liste gibt einen Wert zurück
    @isTest static void testGetOlipositiv () {
        
        List<CreateMultiExtraBoostItems.oppProduct> productListTest = new List <CreateMultiExtraBoostItems.oppProduct>();         
        Id pricebookId = Test.getStandardPricebookId();
        CreateMultiExtraBoostItems tstCtrl = new CreateMultiExtraBoostItems();
        
 		Opportunity opp = [Select Id FROM Opportunity];
        OpportunityLineItem o = [Select Id, ON_product_family__c FROM OpportunityLineItem WHERE TotalPrice = 500];    
        system.assertEquals('Extra Boost', o.ON_product_family__c);
         
        Test.startTest();
                       
        if (productListTest == Null){
            productListTest = tstCtrl.getOli();
            for(OpportunityLineitem olip : 
                    [select Id, Quantity, Produkt__c, UnitPrice ,OpportunityId, ON_product_family__c, Product2.Name, ON_Produktbeschreibung_detailliert__c From OpportunityLineitem 
                            WHERE OpportunityId = :opp.Id
                            AND ON_product_family__c = 'Extra Boost']){  
                                
                            productListTest.add(new CreateMultiExtraBoostItems.oppProduct(olip));                
                            system.assertEquals('Extra Boost', olip.ON_product_family__c);
                            }
            system.assertEquals(1, productListTest.size());
        }     
        Test.stopTest();
    }
    
    // Liste gibt keine Werte zurück
     @isTest static void testGetOliNull () {
        
        CreateMultiExtraBoostItems tstCtrl = new CreateMultiExtraBoostItems();
        List<CreateMultiExtraBoostItems.oppProduct> productListTest = new List <CreateMultiExtraBoostItems.oppProduct>();         
       
         Opportunity opp = [Select Id FROM Opportunity];
         OpportunityLineItem oli = [Select Id, Quantity, Produkt__c, UnitPrice , ON_product_family__c, Product2.Name, ON_Produktbeschreibung_detailliert__c From OpportunityLineitem WHERE ON_product_family__c != 'Extra Boost'];
         
         Test.startTest();
         
         if (productListTest == Null){
             productListTest = tstCtrl.getOli();
             for(OpportunityLineitem olip : 
                    [select Id, Quantity, Produkt__c, UnitPrice , ON_product_family__c, Product2.Name, ON_Produktbeschreibung_detailliert__c From OpportunityLineitem 
                            WHERE OpportunityId = :opp.Id
                            AND ON_product_family__c = 'Extra Boost']){
                                
                            productListTest.add(new CreateMultiExtraBoostItems.oppProduct(olip)); 
                                
                            system.assertEquals(Null, olip.ON_product_family__c);
                            }
        }
         
         Test.stopTest();
         system.assertEquals(0,productListTest.size());   
    }
    // Liste gibt Werte zurück
    @isTest static void testGetBoostsbulk () {

        List<CreateMultiExtraBoostItems.cBoost> cmeCBlist = new List <CreateMultiExtraBoostItems.cBoost> ();
        List<ExtraBoost__c> exbo = [Select Id, Name FROM ExtraBoost__c];

        Test.startTest();
        
            for(ExtraBoost__c ex : exbo){
                CreateMultiExtraBoostItems.cBoost cbo = new CreateMultiExtraBoostItems.cBoost(ex);
                cmeCBlist.add(cbo);
        }
        system.assertEquals(100,cmeCBlist.size());
        
        CreateMultiExtraBoostItems tstCtrl = new CreateMultiExtraBoostItems();
        tstCtrl.getBoosts();
        
        Test.stopTest();       
    }
    
    // Liste gibt keine Werte zurück
    @isTest static void testGetBoostsNull () {

        List<CreateMultiExtraBoostItems.cBoost> cmeCBlist = new List <CreateMultiExtraBoostItems.cBoost> ();
        List<ExtraBoost__c> exbo = new List <ExtraBoost__c>();
        insert exbo; 

        Test.startTest();
           
            for(ExtraBoost__c ex : exbo){
                CreateMultiExtraBoostItems.cBoost cbo = new CreateMultiExtraBoostItems.cBoost(ex);
                cmeCBlist.add(cbo);
        }
        system.assertEquals(0,cmeCBlist.size());
        
        CreateMultiExtraBoostItems tstCtrl = new CreateMultiExtraBoostItems();
        tstCtrl.getBoosts();
        Test.stopTest();       
    }
    
    // positiver Test
   @isTest static void testSavepositiv(){
       
       CreateMultiExtraBoostItems tstCtrl = new CreateMultiExtraBoostItems(); 
      
       List<ExtraBoost_Item__c> xboItems = new List <ExtraBoost_Item__c>(); 
       List<CreateMultiExtraBoostItems.cBoost> cboItems = tstCtrl.getBoosts();
       List<CreateMultiExtraBoostItems.oppProduct> testopoItems = tstCtrl.getOli();            
       List<CreateMultiExtraBoostItems.oppProduct> oposelecteItems = new List <CreateMultiExtraBoostItems.oppProduct>(); 
            
       ExtraBoost__c fbo = new ExtraBoost__c (name='test');
       insert fbo;
       
       ExtraBoost__c fbo1 = new ExtraBoost__c (name='test2');
       insert fbo1;
       
       OpportunityLineItem oli = [Select Id, OpportunityId, Quantity, Produkt__c, UnitPrice , ON_product_family__c, Product2.Name, ON_Produktbeschreibung_detailliert__c FROM OpportunityLineItem WHERE TotalPrice = 500];
       system.assertEquals('Extra Boost', oli.ON_product_family__c);

       CreateMultiExtraBoostItems.oppProduct cmeOP = new CreateMultiExtraBoostItems.oppProduct(oli);
       cmeOP.selected = true;
       testopoItems.add(cmeOP);
               
       system.assertEquals(1, testopoItems.size());
     
       for(CreateMultiExtraBoostItems.oppProduct opo: testopoItems){
           if(opo.selected == true){
               
               tstCtrl.oppLineitemId = opo.oli.id;
               tstCtrl.opportunityId = opo.oli.OpportunityId;
               tstCtrl.ProductName = opo.oli.Product2.Name;
               tstCtrl.quantity = opo.oli.Quantity;
               oposelecteItems.add(opo);            
           }
       }
       
       CreateMultiExtraBoostItems.cBoost cmeCB = new CreateMultiExtraBoostItems.cBoost (fbo);
       cmeCB.selected = true; 
       cboItems.add(cmeCB);
       
       CreateMultiExtraBoostItems.cBoost cmeCB1 = new CreateMultiExtraBoostItems.cBoost (fbo1);
       cmeCB1.selected = false; 
       cboItems.add(cmeCB1);
             
       for(CreateMultiExtraBoostItems.cBoost cbo : cboItems){
           if(cbo.selected == true){
               
               ExtraBoost_Item__c boost = new ExtraBoost_Item__c  ();
               boost.ExtraBoost__c = cbo.ext.Id;
               boost.Opportunity__c = tstCtrl.opportunityId;
               boost.OpportunityLineItem__c = tstCtrl.oppLineitemId;
               boost.Quantity__c =  tstCtrl.quantity;
               boost.Available__c =  tstCtrl.quantity;
               boost.Product_Name__c =  tstCtrl.productName;
               xboItems.add(boost);}   
       }
       
       Test.startTest();
       Pagereference oppPage = tstCtrl.save();
       PageReference testpage = new PageReference('/' + tstCtrl.opportunityId);              
       Test.StopTest();
       system.assertEquals(testpage.getUrl(), oppPage.getUrl());

    }
    
    @isTest static void testSaveNull(){
       
       CreateMultiExtraBoostItems tstCtrl = new CreateMultiExtraBoostItems(); 
      
       List<ExtraBoost_Item__c> xboItems = new List <ExtraBoost_Item__c>(); 
       List<CreateMultiExtraBoostItems.cBoost> cboItems = tstCtrl.getBoosts();
       List<CreateMultiExtraBoostItems.oppProduct> testopoItems = tstCtrl.getOli();            
       List<CreateMultiExtraBoostItems.oppProduct> oposelecteItems = new List <CreateMultiExtraBoostItems.oppProduct>(); 
            
       ExtraBoost__c fbo = new ExtraBoost__c (name='test');
       insert fbo;
       
       ExtraBoost__c fbo1 = new ExtraBoost__c (name='test2');
       insert fbo1;
       
       OpportunityLineItem oli = [Select Id, OpportunityId, Quantity, Produkt__c, UnitPrice , ON_product_family__c, Product2.Name, ON_Produktbeschreibung_detailliert__c FROM OpportunityLineItem WHERE TotalPrice = 500];
       system.assertEquals('Extra Boost', oli.ON_product_family__c);

       CreateMultiExtraBoostItems.oppProduct cmeOP = new CreateMultiExtraBoostItems.oppProduct(oli);
       cmeOP.selected = false;
       testopoItems.add(cmeOP);
               
       system.assertEquals(1, testopoItems.size());
     
       for(CreateMultiExtraBoostItems.oppProduct opo: testopoItems){
           if(opo.selected == true){
               
               tstCtrl.oppLineitemId = opo.oli.id;
               tstCtrl.opportunityId = opo.oli.OpportunityId;
               tstCtrl.ProductName = opo.oli.Product2.Name;
               tstCtrl.quantity = opo.oli.Quantity;
               oposelecteItems.add(opo);            
           }
       }
        
       system.assertEquals(0, oposelecteItems.size());
        
       CreateMultiExtraBoostItems.cBoost cmeCB = new CreateMultiExtraBoostItems.cBoost (fbo);
       cmeCB.selected = false; 
       cboItems.add(cmeCB);
       
       CreateMultiExtraBoostItems.cBoost cmeCB1 = new CreateMultiExtraBoostItems.cBoost (fbo1);
       cmeCB1.selected = false; 
       cboItems.add(cmeCB1);
             
       for(CreateMultiExtraBoostItems.cBoost cbo : cboItems){
           if(cbo.selected == true){
               
               ExtraBoost_Item__c boost = new ExtraBoost_Item__c  ();
               boost.ExtraBoost__c = cbo.ext.Id;
               boost.Opportunity__c = tstCtrl.opportunityId;
               boost.OpportunityLineItem__c = tstCtrl.oppLineitemId;
               boost.Quantity__c =  tstCtrl.quantity;
               boost.Available__c =  tstCtrl.quantity;
               boost.Product_Name__c =  tstCtrl.productName;
               xboItems.add(boost);}   
       }
       
       Test.startTest();
       Pagereference oppPage = tstCtrl.save();
       PageReference testpage = new PageReference('/' + tstCtrl.opportunityId);              
       Test.StopTest();
       system.assertEquals(testpage.getUrl(), oppPage.getUrl());
       system.assertEquals(0, xboItems.size());
    }
    
    // postiviter Bulk Test
    @isTest static void testSaveBulk(){
        
        CreateMultiExtraBoostItems tstCtrl = new CreateMultiExtraBoostItems();  
        List<ExtraBoost_Item__c> xboItems = new List <ExtraBoost_Item__c>(); 
        List<CreateMultiExtraBoostItems.cBoost> cboItems = tstCtrl.getBoosts();
        List<CreateMultiExtraBoostItems.oppProduct> testopoItems = tstCtrl.getOli();
        List<CreateMultiExtraBoostItems.oppProduct> oposelecteItems = new List <CreateMultiExtraBoostItems.oppProduct>(); 
       
        List<ExtraBoost__c> xtrabo = [SELECT Id, Name FROM ExtraBoost__c]; 
        
        OpportunityLineItem oli = [Select Id,OpportunityId, Quantity, Produkt__c, UnitPrice , ON_product_family__c, Product2.Name, ON_Produktbeschreibung_detailliert__c FROM OpportunityLineItem WHERE TotalPrice = 500];
        OpportunityLineItem oli1 = [Select Id,OpportunityId, Quantity, Produkt__c, UnitPrice , ON_product_family__c, Product2.Name, ON_Produktbeschreibung_detailliert__c FROM OpportunityLineItem WHERE TotalPrice = 1000];
        system.assertEquals('Extra Boost', oli.ON_product_family__c);
        system.assertEquals('Extra Boost', oli1.ON_product_family__c);
        
        CreateMultiExtraBoostItems.oppProduct cmeOP = new CreateMultiExtraBoostItems.oppProduct(oli);
        cmeOP.selected = true;
        testopoItems.add(cmeOP);
       
        CreateMultiExtraBoostItems.oppProduct cmeOP1 = new CreateMultiExtraBoostItems.oppProduct(oli1);
        cmeOP1.selected = false;
        testopoItems.add(cmeOP1); 
       
       system.assertEquals(2, testopoItems.size());
     
       for(CreateMultiExtraBoostItems.oppProduct opo: testopoItems){
           if(opo.selected == true){
               
               tstCtrl.oppLineitemId = opo.oli.id;
               tstCtrl.opportunityId = opo.oli.OpportunityId;
               tstCtrl.ProductName = opo.oli.Product2.Name;
               tstCtrl.quantity = opo.oli.Quantity;
               oposelecteItems.add(opo);            
           }
       }
        for(ExtraBoost__c e: xtrabo){
            CreateMultiExtraBoostItems.cBoost cmeCB = new CreateMultiExtraBoostItems.cBoost(e);
            cmeCB.selected = true;
            cboItems.add(cmeCB);
        }

        for(CreateMultiExtraBoostItems.cBoost cbo : cboItems){
           if(cbo.selected == true){
         
               ExtraBoost_Item__c boost = new ExtraBoost_Item__c  ();
               boost.ExtraBoost__c = cbo.ext.Id;
               boost.Opportunity__c = tstCtrl.opportunityId;
               boost.OpportunityLineItem__c = tstCtrl.oppLineitemId;
               boost.Quantity__c = tstCtrl.quantity;
               boost.Available__c = tstCtrl.quantity;
               boost.Product_Name__c =  tstCtrl.productName;
               xboItems.add(boost);}   
       }
        
        Test.startTest();
        Pagereference oppPage = tstCtrl.save();
        PageReference testpage = new PageReference('/' + tstCtrl.opportunityId);              
        Test.StopTest();
        
        system.assertEquals(100,xboItems.size());
        system.assertEquals(testpage.getUrl(), oppPage.getUrl());
    }
    
   @isTest static void testBack(){
       CreateMultiExtraBoostItems cme = new CreateMultiExtraBoostItems();
       cme.windowBack();  
    }   
    
}

 
Amit Chaudhary 8Amit Chaudhary 8
Your test class look good to me.
Sandra WicketSandra Wicket
Thanks for your feedback Amit. It is hard to get one :) I am will deploy my controller finally