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
Colin LoretzColin Loretz 

Deploying Apex using Force IDE or 'ant deploy'

I'm trying to deploy Apex code for the first time and I've run into an issue.

I've tried using both the Force.com IDE and Apache Ant/CMD line methods for deployment and I can't deploy to a live production environment.

When I run "ant deploy" with my connection info setup for a developer account, the build is successful. When I change the connection info to represent a live environment, I get the following error:
Code:
BUILD FAILED
C:\Documents and Settings\cloretz\Desktop\salesforce_ant\sample\build.xml:12: Fa
iled:
testcase in class 'compileAndTest' method 't1' failure:System.DmlException: Inse
rt failed. First exception on row 0; first error: INVALID_FIELD_FOR_INSERT_UPDAT
E, Account: bad field names on insert/update call: Name: [Name]
stack-trace:
Class.compileAndTest.t1: line 7, column 9

Code coverage error on phoneSetter: Test coverage of selected Apex Trigger is 0%
, at least 1% test coverage is required
Code coverage error: Test coverage of selected Apex Class and Trigger is 25%, at
 least 75% test coverage is required


JonPJonP
In order to deploy your Apex code into a production environment, all of the following must be true:
  • 75% of your Apex scripts are covered by unit tests, and all of those test complete successfully.

    Note that when deploying to a production organization, every unit test in your organization namespace is executed.

  • Every trigger has some test coverage.
  • All classes and triggers compile successfully.
It looks like your Apex code only has test coverage of 25%, and that at least one of your unit tests is failing.

See the Apex Developer Guide under Getting Started > Introducing Apex > What is the Apex Development Process? > Deploying Apex to a Salesforce Production Organization.
Vijay RautVijay Raut
Hi,

I think on your live environment, person account is setup and it is default record type of account. Hence it throwing exception for setting name field. Check that. Because Name field is not available for the person account.

And if this is the case then till deployment, change your account default record type to business account.

Regards
V.R.
Colin LoretzColin Loretz
Excellent. I know the tests were failing but I didn't know why. The live environment does in fact use person accounts.

Thanks for the tip.
Colin LoretzColin Loretz
Still no luck.

The error is still a test coverage problem:
Code:
deploy:
[sf:compileAndTest] compileAndTest on https://www.salesforce.com/services/Soap/u
/10.0, compiling 1 classes and 0 triggers, deleting 0 classes and 0 triggers

BUILD FAILED
C:\Documents and Settings\cloretz\Desktop\salesforce_ant\massNotes\build.xml:12:
 Failed:
Code coverage error: Test coverage of selected Apex Class and Trigger is 0%, at
least 75% test coverage is required

 

Here is my build.xml
Code:
1. <project name="Mass Notes deploy" default="deploy" basedir="." xmlns:sf="antlib:com.salesforce">
2.
3.    <property file="build.properties"/>
4.   <property environment="env"/>
5.    
6.    <target name = "deploy">
7.    <sf:compileAndTest
8.    username="${sf.username}"
9.    password="${sf.password}"
10. server="${sf.serverurl}"
11. apiversion="10.0" 12. basedir="."> 13. </sf:compileAndTest> 14. </target> 15. 16. 17. </project>

 The following is my apex code, which is from Mass Notes in the Apex Cookbook.
Code:
global class MassNoteInsert{

WebService static Integer insertNotes(String iTitle, String iBody, Id[] iParentIds) {
Note[] notes = new Note[0];
for(Id iParentId : iParentIds) {
notes.add(new Note(parentId = iParentId, title = iTitle, body = iBody));
}
insert notes; //bulk insert
return notes.size();
}
}

 


JonPJonP
Colin,

I don't see any Apex unit tests defined in the code you've posted, which is why the Ant deployment is reporting 0% code coverage.  You need to create TestMethods that exercise at least 75% of your lines of code before you can deploy to a production environment.

Jon
Colin LoretzColin Loretz
Thanks JonP,

Everything makes sense now. I've been trying to piece the process together from the force.com cookbook and everything works without a hitch in development. I'll get on those unit tests.

Cheers.
Colin LoretzColin Loretz
My new code, with a unit test, is as follows:

Apex Code:
global class MassNoteInsert {

WebService static Integer insertNotes(String iTitle, String iBody, Id[] iParentIds) {

  Note[] notes = new Note[0];
      for(Id iParentId : iParentIds) {
        notes.add(new Note(parentId = iParentId, title = iTitle, body = iBody));
      }
    
    insert notes; //bulk insert
    return notes.size();
}


static testMethod void testAll() {
//Unit test

Id[] testIds = new Id[] {'0015000000L4tMv'};

System.assertEquals(1, insertNotes('Test','Test note', testIds));

}

}

 This allowed me to deploy but now I'm getting this error:



The s-control that calls the webservice and the apex code are from the Apex cookbook I believe.
Code:
{!REQUIRESCRIPT("/soap/ajax/10.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/10.0/apex.js")}

var idsToInsert = {!GETRECORDIDS( $ObjectType.Account ) };

var noteTitle = "Enter a note title";
var noteBody = "Enter a note body";

noteTitle = prompt("Please enter the title of the note");
noteBody = prompt("Please enter the body of the note");

if (idsToInsert.length) {

var result = sforce.apex.execute("MassNoteInsert", "insertNotes", {iTitle : noteTitle, iBody : noteBody, iParentIds : idsToInsert } );

alert(result[0] + " notes inserted!");
}
else if (idsToInsert.length == 0) {
alert("Please select the accounts to which you would like to add notes.");
}

 The code works and inserts multiple notes from the list view, however that above error is displayed before the script prompt in IE only and if you hit the cancel button in both IE and Firefox.]

Unfortunately, our org uses IE alot.

Thanks for all the help!




Message Edited by Colin Loretz on 01-31-2008 10:45 AM
JonPJonP
This is just a Javascript issue.  If the user clicks cancel on the prompt() dialog, the function returns null.  Your code needs to check for this case, and also for a blank string.

A very simple solution would be:

Code:
...
noteTitle = prompt("Please enter the title of the note");
while (noteTitle=="") {
  // user clicked OK, but response was blank
  noteTitle = prompt("You must supply a title for the note.")
}
if (noteTitle==null) {
  // user clicked cancel
  return;
}

noteBody = prompt("Please enter the body of the note");
while (noteBody =="") {
  // user clicked OK, but response was blank
  noteBody = prompt("You must supply a body for the note.")
}
if (noteBody ==null) {
  // user clicked cancel
  return;
}
...


You will want to refine the behavior further--such as applying a trim() to the response to remove whitespaces before checking if it's an empty string. One caveat--I'm not sure if "return" will work here, so you may need to enclose the subsequent code in big if statements that ensure noteTitle, and then noteBody, are not null.

But this code will at least protect you against the two most likely user actions that would result in an error.