You need to sign in to do that
Don't have an account?
Andrea Ianni
Trailhead: Coverage 100% but challenge failed
I have this very simple class..
When I run the Test class from the Developer Console I get 100% of coverage on the RestrictContactByName class but, when I check the challenge on the trailhead it returns the error:
Challenge not yet complete... here's what's wrong: The 'RestrictContactByName' class did not achieve 100% code coverage via your test methods
Has someone had my same issue?
trigger RestrictContactByName on Contact (before insert, before update) { //check contacts prior to insert or update for invalid data For (Contact c : Trigger.New) { if(c.LastName == 'INVALIDNAME') { //invalidname is invalid c.AddError('The Last Name "'+c.LastName+'" is not allowed for DML'); } } }.. and the corresponding Test Class:
@isTest private class TestRestrictContactByName { @isTest static void metodoTest() { List listaContatti = new List(); Contact c1 = new Contact(FirstName='Francesco', LastName='Riggio'); Contact c2 = new Contact(LastName = 'INVALIDNAME'); listaContatti.add(c1); listaContatti.add(c2); //insert listaContatti; // Perform test Test.startTest(); Database.SaveResult [] result = Database.insert(listaContatti, false); Test.stopTest(); c1.LastName = 'INVALIDNAME'; update c1; } }
When I run the Test class from the Developer Console I get 100% of coverage on the RestrictContactByName class but, when I check the challenge on the trailhead it returns the error:
Challenge not yet complete... here's what's wrong: The 'RestrictContactByName' class did not achieve 100% code coverage via your test methods
Has someone had my same issue?
Please try below Test Class :-
With Above test class i got all 500 Point.
Note:- Before submitting the challenge you need to run your test class and need to check code coverage on trigger like below
To Run Test class please check on below button
After Click on Run Test Check code coverage on Trigger.
Then only Submit the exam.
Please mark this as solution if this will help you. So that if some one have same issue this post can help
Thanks
Amit Chaudhary
amit.salesforce21@gmail.com
All Answers
.... but, it doesn't "cover" the class to 100%.
"Install a simple Apex trigger, write unit tests that achieves 100% code coverage for the trigger, and run your Apex tests.The Apex trigger to test is called 'RestrictContactByName', and the code is available here. Copy and paste this trigger into your Developer Edition via the Developer Console.
'RestrictContactByName' is a trigger which blocks inserts and updates to any contact with a last name of 'INVALIDNAME'.
The unit tests must be in a separate Apex class called 'TestRestrictContactByName'.
The unit tests must cover scenarios for all lines of code included in the Apex trigger, resulting in 100% code coverage.
Run your test class at least once (via the Developer Console) before attempting to verify this challenge."
Error: Challenge not yet complete... here's what's wrong:
The 'RestrictContactByName' class did not achieve 100% code coverage via your test methods
Please try below Test Class :-
With Above test class i got all 500 Point.
Note:- Before submitting the challenge you need to run your test class and need to check code coverage on trigger like below
To Run Test class please check on below button
After Click on Run Test Check code coverage on Trigger.
Then only Submit the exam.
Please mark this as solution if this will help you. So that if some one have same issue this post can help
Thanks
Amit Chaudhary
amit.salesforce21@gmail.com
I tried to see if I had Validation Rules but I didn't. I tried all the possible issues.
At the end I connected another ORG to my trailhead and... I passed the challenge!
I'm sorry I didn't understand why I couldn't pass it but... at least the code is right! Thank you for your time!
Andrea
public class TestRestrictContactByName {
public static testmethod void contacttest(){
contact c =new contact ();
c.LastName='INVALIDNAME';
insert c;
}
}
Hi Andrea, thanks for posing the question!
Hi Amit, thanks for writing a solution!
It is true that Amit's solution passes the Trailhead test, in this case because running his test gives 100% code coverage. However, his test code itself is not actually a test written in the sense of a unit test (please take this as constructive, Amit!). A good way to think of unit testing is with the three A's: Arrange, Act, Assert. We first set up the test (Arrange), then we carry out the calculations (Act), then we check if what we expected to happen really happened (Assert). If you would like to know more about unit testing, look up books by Robert Martin (Uncle Bob) or Kent Beck or search for the test "test-driven development".
Below I've given an example of a unit test to solve this trailhead challenge. In general, I don't think it's necessarily good to write whole solutions in the discussion forums (because people can then copy and paste without understanding), but I think in this case it's passable because unit testing is such an important concept in modern software development. You will see that the inputs for the tests are first arranged (Arrange), then the calculations are carried out (Act), then we check if we got what we expected ((Assert) . If you look in the Class that you are testing, you should be able to work out what you are testing and what you expect to get. Ideally, for a full test solution, you should also write a second test for the case when the LastName is not invalid.
Happy Testing!
David.
This is easily fixed by adding at the 9th line, and under the 13th line of his code. Essentially just making sure the test spits out at least one 'fail' and one 'pass'.
Install a simple Apex trigger, write unit tests that achieves 100% code coverage for the trigger, and run your Apex tests.The Apex trigger to test is called 'RestrictContactByName', and the code is available here. Copy and paste this trigger into your Developer Edition via the Developer Console.
'RestrictContactByName' is a trigger which blocks inserts and updates to any contact with a last name of 'INVALIDNAME'.
The unit tests must be in a separate Apex class called 'TestRestrictContactByName'.
The unit tests must cover scenarios for all lines of code included in the Apex trigger, resulting in 100% code coverage.
Run your test class at least once (via 'Run All' tests the Developer Console) before attempting to verify this challenge.
My TestClass code:
@isTest
public class TestRestrictContactByName {
@isTest static void TestInUpRestrictContactByName()
{
contact cont=new contact(LastName='INVALIDNAME');
upsert cont;
Test.startTest();
Database.UpsertResult result=Database.upsert(cont,false);
Test.stopTest();
System.assert(!result.isSuccess());
System.assert(result.getErrors().size() > 0);
System.assertEquals('Cannot insert or update a record with INVALIDNAME as lastname',
result.getErrors()[0].getMessage());
}
}
can anyone help me....??? guys
@isTest
private class TestRestrictContactByName {
@isTest static void test1(){
contact c = new Contact();
c.LastName = 'INVALIDNAME';
// Perform test
Test.startTest();
insert c;
Test.stopTest();
}
@isTest static void test2(){
contact c = new Contact();
c.LastName = 'Devi';
// Perform test
Test.startTest();
insert c;
Test.stopTest();
}
}
Try this one:
@isTest
public class TestRestrictContactByName {
@isTest static void TestInsertContactWithInvalidLastName() {
// Test data setup
// Create a contact with the last name INVALIDNAME
Contact cont = new Contact(FirstName = 'John ', LastName = 'INVALIDNAME');
// Perform test
Test.startTest();
Database.SaveResult result = Database.insert(cont, false);
Test.stopTest();
// Verify
// In this case the insert operation should have been stopped by the trigger,
// so verify that we got back an error.
System.assert(!result.isSuccess());
System.assert(result.getErrors().size() > 0);
System.assertEquals('The Last Name "INVALIDNAME" is not allowed for DML',
result.getErrors()[0].getMessage());
}
}
@isTest
public class TestRestrictContactByName {
@isTest static void testInvalidName(){
List<contact> con=new List<Contact>();
Contact c1=new Contact(LastName='@@');
Contact c2=new Contact(LastName='Mahi');
Contact c3=new Contact(LastName='INVALIDNAME');
con.add(c1);
con.add(c2);
con.add(c3);
Test.startTest();
try{
insert con;
}
catch(DMLException de){
string Expectedmessage1 = 'the last name "'+c1.lastname+' "is not allowed for DML';
string Expectedmessage3 = 'the last name "'+c3.lastname+' "is not allowed for DML';
system.assertEquals(Expectedmessage1, de.getDMLMessage(0));
system.assertEquals(Expectedmessage3, de.getDMLMessage(0));
}
Test.stopTest();
}
}
@isTest
private class TestRestrictContactByName
{
@isTest static void testInsert()
{
Contact d=new Contact(LastName='INVALIDNAME', FirstName='Error');
Test.startTest();
try{
insert d;
}
catch(Exception e) { }
Test.stopTest();
}
}
While most of the suggested test classes will let you achieve 100% code coverage and pass the module; the suggested code will not test the DML: this is worse than no code coverage!
Example of bad code: Why:
1) this returns nothin to validate;
2) checks only 'insert' operation. The test must validate both insert and update operations. You can't use 'upsert' because such record should not exist in your instance and test code will always go to "insert" branch of the method.
3) The test must check the actual parameters returns; I believe checking success or failure is enough:
Or we can assert the size of like below
And we should also follow below best pratice in test class
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
@isTEST
public class TestRestrictContactByName {
@IStest
Public static void MethodtoInsert()
{
Contact C=new Contact(Lastname='INVALIDNAME');
Database.saveresult Res= database.insert(c,False);
System.assertEquals('The Last Name "'+c.LastName+'" is not allowed for DML', res.getErrors()[0].getmessage());
}
@istest
public static void methodtoUpdate()
{
COntact C=new contact(Lastname='INALIDNAME' );
database.SaveResult Res=database.update(C, False);
System.assertEquals('The Last Name "'+c.LastName+'" is not allowed for DML', res.getErrors()[0].getmessage());
}
}
@isTest
public class TestRestrictContactByName {
public static Contact c1=new Contact();
@isTest static void TestLastNameOfContact()
{
c1.LastName='INVALIDNAME';
//insert c1;
Test.startTest();
Database.SaveResult r=Database.insert(c1,false);
Test.stopTest();
System.assertEquals(c1.LastName,'error');
}
}
@isTest
public class TestRestrictContactByName
{
private static testMethod void myMethod1()
{
List<Contact> cons=new List<Contact>();
Contact c1=new Contact();
c1.FirstName='Test';
c1.LastName='InvalidName';
cons.add(c1);
try{
insert c1;
}
Catch(DMLexception e)
{
System.assertEquals('The Last Name "'+c1.LastName+'" is not allowed for DML',e.getDmlMessage(0));
}
}
Public static testMethod void myMethod2()
{
List<Contact> cons=new List<Contact>();
Contact c2=new Contact();
c2.FirstName='Test';
c2.LastName='Name';
cons.add(c2);
insert cons;
System.assertEquals(c2.LastName, 'Name');
}
}
System.AssertException: Assertion Failed
Class.TestRestrictContactByName.TestLastNameIsvalid: line 35, column 1
I've spent hours trying to figure out why but couldn't. I wonder if any of you was able to help and provide me with some insights here? Your help will be much appreciated!
Hi guys,
I finished the challenge, but I was really disappointed because I'm sure I didn't really tested every options...
Here is my code :
Do you know why it worked ?
How can I improve it ?
I tried to interrogate the size of the errors on my list, but I think I still have an issue understanding how works the Database.SaveResult (or Database.UpsertResult) objects ... Is there a list of lists, in which there are couples (objectToUpsert, SuccessOrNot) ?
Nb : I don't know if I should open my own topic for asking this ?
Sorry, I'm learning :)
Message to Salesforce Training developers: The Unit needs work! You don't explain any of that in the unit - we follow your lead for how it's presented in the unit, but you have left too much out for this unit. If it weren't for this forum it would take tons of research to work it out!
Below is the snippet code :
@istest
public class TestRestrictContactByName {
public static testmethod void TestContact(){
List<contact> con = new list<contact>();
contact c1= new contact(FirstName='Sohan',LastName='V');
contact c2= new contact(FirstName='V',Lastname='INVALIDNAME');
con.add(c1);
con.add(c2);
Test.startTest();
try{
upsert con;
}
catch(exception e){
}
Test.stopTest();
}
}
@isTest
public class TestRestrictContactByName {
@isTest static void TestGoodContactInsertion() {
Contact cntc = new Contact(LastName='Vasilij');
insert cntc;
}
@isTest static void TestBadContactInsertion() {
Contact cntc = new Contact(LastName='INVALIDNAME');
insert cntc;
}
}
Always try to run new test after modifying test class then it will only show you 100% coverage.
Reason: Coz when you rerun test already contact is created with name provided by you during new run. And when you run new test it will first delete older one and insert new one with provided name.
@isTest
private class TestRestrictContactByName {
@isTest static void CheckContact(){
Contact con = new Contact(FirstName='testDemo',LastName= 'Singh');
insert con;
con.LastName = 'INVALIDNAME';
Test.startTest();
try{
update con;
}
catch (DmlException e {
String expectedMessage = 'The Last Name INVALIDNAME is not allowed for DML';
System.assertEquals(expectedMessage, e.getDmlMessage(0));
}
Test.stopTest();
}
}
@isTest
public class TestRestrictContactByName {
@isTest static void TestGoodContactInsertion() {
Contact cntc = new Contact(LastName='Vasilij');
insert cntc;
}
@isTest static void TestBadContactInsertion() {
Contact cntc = new Contact(LastName='INVALIDNAME');
insert cntc;
}
@isTest static void TestBadContactInsertion1() {
List<Contact> conList = new List<Contact> {
new Contact(FirstName='Joe',LastName='Smith',Department='Finance'),
new Contact(FirstName='Kathy',LastName='Smith',Department='Technology'),
new Contact(FirstName='Caroline',LastName='Roth',Department='Finance'),
new Contact(FirstName='Kim',LastName='Shain',Department='Education')};
// Bulk insert all contacts with one DML call
insert conList;
}
}
I have passed this challenge with 100% code coverage .
Below are the screen shots & the code snippet.
@isTest
private class TestRestrictContactByName
{
public static Contact c1=new Contact();
@isTest static void TestLastNameOfContact()
{
c1.LastName='INVALIDNAME';
insert c1;
Test.startTest();
Database.SaveResult r=Database.insert(c1,false);
Test.stopTest();
System.assertEquals(c1.LastName,'error');
}
}
@isTest
public class TestRestrictContactByName {
@isTest static void TestContactLastName(){
Contact cnt = new Contact(LastName='Nagpal', FirstName='Namit');
Contact cnt1 = new Contact(LastName='INVALIDNAME', FirstName='Hardik');
// Insert Valid record
insert cnt;
// Perform test
Test.startTest();
// Perform test - Update contact with LastName = 'INVALIDNAME'
cnt.LastName = 'INVALIDNAME';
try{
update cnt;
}
catch(DMLException e){
System.assertEquals('The Last Name "'+cnt.LastName+'" is not allowed for DML',e.getDMLmessage(0));
}
// Perform test - Insert contact with LastName = 'INVALIDNAME'
try{
insert cnt1;
}
catch(DMLException e){
System.assertEquals('The Last Name "'+cnt1.LastName+'" is not allowed for DML',e.getDMLmessage(0));
}
Test.stopTest();
}
}
Please let me know if above solution resolved your problem.
Not Sure , why so many big lines of code were proposed when the ask in the challenge is pretty simple .
Please try below ,save and Run the test. This will work.
@isTest
public class TestRestrictContactByName {
public static testmethod void contacttest(){
contact c =new contact ();
c.LastName='INVALIDNAME';
insert c;
}
}
Following is my code..
@isTest
public class TestRestrictContactByName {
@isTest static void testInsUpContact()
{
contact ct=new contact(LastName='INVALIDNAME');
upsert ct;
Test.startTest();
Database.UpsertResult supsertresult= Database.upsert(ct,false);
Test.stopTest();
system.assert(!supsertresult.isSuccess());
system.assert(supsertresult.getErrors().size()>0);
system.assertEquals('cannot upsert contact with lastname as INVALIDNAME', supsertresult.getErrors()[0].getMessage());
}
}
Friends I had coded the class given below, I got 100% code coverage and cleared trailhead too.
@isTest
public class TestRestrictContactByName {
@isTest public static void contacttest()
{
contact c =new contact ();
c.LastName='INVALIDNAME';
try{
Upsert c;
}
catch (Exception e)
{
system.debug('The following error is' +e);
}
}
}
@isTest
public class TestRestrictContactByName {
@isTest static void TestInvalidName(){
Contact con = new Contact(LastName = 'INVALIDNAME');
Test.startTest();
try{
insert con;
}
catch (DmlException dmlEx){
System.assertEquals('The Last Name "'+ con.LastName+'" is not allowed for DML', dmlEx.getDmlMessage(0));
}
Test.stopTest();
}
}
@isTest
public class TestRestrictContactByName {
@isTest static void TestRestrictContactByName(){
// List<Contact> conList = new List<Contact>();
//Contact con = new Contact(LastName='Vishwakarma');
Contact con = new Contact(LastName='INVALIDNAME');
// conList.add(con);
// conList.add(con1);
insert con;
Test.startTest();
Database.SaveResult result = Database.insert(con, false);
Test.stopTest();
System.assert(!result.isSuccess());
System.assert(result.getErrors().size() > 0);
System.assertEquals('Cannot insert account with related opportunities.',
result.getErrors()[0].getMessage());
}
}
Thank you each and everyone. please be more helpful.
@isTest
public class TestRestrictContactByName {
static testmethod void RestrictContact(){
Contact ct = new Contact(LastName='INVALIDNAME');
insert ct;
}
}
one method to test with valid input and another is to test with invalid input.