In the course of building automated tests, it’s always good practice to pepper your test code with Assert statements to ensure your code is functioning as you would expect throughout. But, as I’ve seen more than one example of the specific behaviour in the first code section below, I think it’s something I should point out.
On first glance, it looks like the assertion is doing the right thing. But if you think about it, it’s not a real test. It only tests that the in-memory variable testAcc.Name has the value originally assigned to it a couple of lines back.
// Example 1. An in-memory-based test
Account testAcc = new Account();
testAcc.Name = 'Testing 123';
insert testAcc;
System.assertEquals('Testing123',testAcc.Name);
What it really needs to do, so that it becomes a “real” test is for the test method to query the database record just inserted and to retrieve the Name value from the record, then check it against the expected value, as shown below.
// Example 2. A database-based test
Account testAcc = new Account();
testAcc.Name = 'Testing 123';
insert testAcc;
Account checkAcc = [SELECT Name FROM Account WHERE Id = :testAcc.Id];
System.assertEquals(checkAcc.Name,testAcc.Name);
This example is, perhaps, not a great real-world scenario but I feel it illustrates the problem well.
“The internet is not working.”
“My computer isn’t working.”
“That program doesn’t work properly.”.
If you’re asking someone for help and you think this is useful information, then you really need to try harder. Most of those who have spent time supporting others will have heard lines similar to these at least once. It’s the equivalent of someone throwing their arms in the air and say “I don’t care how you do it, just fix it”, and it’s hard to take. This is bad enough when it comes from self-confessed, even proud, Luddites. But when it comes from other technicians, it is hard to forgive.
Often it’s because they have no experience of supporting users themselves and cannot perceive of the viewpoint of the person coming to their rescue. It screams loudly “I am not prepared to invest a moment into this, I just want it to work”, and much of technology just isn’t like that. If it’s man-made, it’s fallible and things go wrong.
Consider the first phrase above: “the internet is not working”. Apart from displaying a high degree of ignorance, it isn’t helpful in the slightest. You can glean from that phrase that someone has a problem browsing the web. Because the “web” and the “internet” are the same thing, right? There’s the first problem. Let’s assume there’s a problem browsing the web; how does the problem manifest itself? Is the web page slow to load? Does it load at all? Is there a visible error message anywhere? Before wasting your support person’s time, look closely at the problem. If the web browser says “HTTP error 404”, pass on that information. What web page are you trying to access? Pass that information along. What web browser are you using, Internet Explorer, Chrome, Firefox? Tell the man! It’s all useful information. Are you able to access another web page, one you know works, e.g. http://www.bbc.co.uk? Let him know. Is your WiFi connection active? Can you access any other internet services, e.g. email? Can you send messages? Can you receive? This is all useful information and accelerates your support person’s ability to resolve your problem.
Where To Start
From the support point of view, it’s all about having a decent starting point. A succinct, clear description of the problem, some supporting information. From there, it’s a game of elimination. There are many components in this problem; the technician has to think about “the chain”. What is the chain?
Computer -> browser/email client -> firewall -> wifi, if any -> cables, if any -> router -> incoming cabling -> ISP -> DNS servers -> web server
This is a simplified chain to make the point. Look at any one of those points of failure and think about how many possible faults there are. The number is quite large. It needs to be reduced. Giving additional information like “I cannot access my email” or “I can see the BBC news web site but site X pages aren’t loading” is very useful. It shows that the computer, browser, connection, router, incoming cables, ISP and DNS servers are all working and that the problem may lie at the web server side or email server of things. The techie asks “what URL did you type”, “how are you trying to access the web site” or “show me your POP3/SMTP settings” and discovers that the user has typed in the wrong URL or has a misconfigured email client. Without this extra detail, the user has to check each component above until he discovers the point of failure. Each link in the chain could force many questions and take a lot of time.
Summary
The central message of this post is not just for users of technology, it’s for designers too, at all levels. Give users the visibility they need to help you to help them. Consider how they have visibility of your system and how they can extract useful information from it to help you support them. Everyone stands to gain from this.
Soft coded = good. Hard coded = bad. That’s difficult to argue against and I doubt there’s much dissent in any programming community.
Define it once, use it many times; this is part of the reusability principle that applies to code segments and text literals. When you define an input field in a Visualforce page, more often than not it is based on a field that exists somewhere in the database. It makes a whole lot of sense to take as many attributes from the original field definition as possible, so below are some examples of how you might do that.
(1) When defining a field on a page, prefix it with its label. Use this syntax:
$ObjectType.ObjectName__c.Fields.FieldName__c.Label
…where ObjectName__c and FieldName__c should be replaced as appropriate.
(2) Use the field’s own help text by referring to the InlineHelpText attribute, as shown below in this syntax:
$ObjectType.ObjectName__c.Fields.FieldName__c.InlineHelpText
…where ObjectName__c and FieldName__c should be replaced as appropriate.
(3) Limit the field length in HTML during data entry by using this syntax:
$ObjectType.ObjectName__c.Fields.FieldName__c.Length
…where ObjectName__c and FieldName__c should be replaced as appropriate.
The above code works well for text input fields. If you need information on numeric or other input field types check out the $ObjectType schema information page.
When building a custom Visualforce page with input fields, one common requirement is to place the cursor at the first input field on the page. You would think this would be a simple matter and Salesforce itself manages the task quite well. But when the platform’s default behaviour kicks in and overrides your page’s behaviour, it doesn’t always work smoothly. Or if you want to position on an input field that is not a text entry field it doesn’t always slide into place. Or perhaps you wish to show a dialog box where you wish to conditionally position the cursor to a Confirm or Cancel button depending on prior processing.
In this piece, I’m offering a foolproof way to enable your page to behave exactly as you want it to, in an easy, maintainable way. Here is the step by step way to do this.
First, download a copy of the JQuery library from jquery.com. The minimised (compressed) version is just fine.
…making sure to replace the JQueryJS text with the name you specified during the Static Resource upload step.
The code below assumes that the page is aware of a “mode” or action passed to it, perhaps as a querystring parameter and parsed separately into a variable called wrkAction.
Given that any page element will probably exist in the hierarchy of page elements, the Visualforce page is rendered with the implicit force.com naming applied i.e. the full “pathname” to the element is implied in the name, with colons separating each branch in the tree. For example, an HTML id such as j_id0:j_id1:j_id192:j_id193:j_id196:j_id230:j_id231:j_id232:4:j_id236 would not be unusual.
The above code brings a “best practice” tip to mind – always use page-unique ID values for input fields, buttons and all other page components. Specifying the ID tag also ensures that the force.com implicit naming conventions are not applied.
The JQuery code in the positionCursorToFirstField javaScript method above provides a major advantage: you are now effectively freed from having to worry about the naming hierarchy. The JQuery selector finds the field ending with a colon character followed by the specified unique fieldname. This also means you can move it around on the page and within the page element hierarchy (DOM) and not have to worry about this code failing or needing to be modified.
There’s just one more piece of code needed to ensure the force.com standard processing doesn’t happen i.e. that the platform itself doesn’t try to be too clever and preempt what you’re trying to do. This code masks the effect of the standard “first input field positioning” processing:
<script language="JavaScript">
//--------------------------------------------------------------------------------------------------------------
// This empty function overrides the SFDC standard function, and enables us to control initial field positioning
//--------------------------------------------------------------------------------------------------------------
function setFocusOnLoad() {
}
</script>
With this post I am, strictly speaking, stepping outside of the pure topic of style. It’s one of those grey areas.
It’s that whole idea of whether to use Array or List data structures in your code. If, like me, you come from a background of programming languages where the first element of an array is element # 1, rather than element # 0, then you may also find List structures a little more intuitive because you usually don’t have to worry about element numbers when you iterate.
From the Apex language viewpoint, arrays and lists are interchangeable; you can declare a list and treat it as an array and vice-versa. Try it yourself if you don’t believe me:
public class BlogStyleGuide5 {
// -----------------------------------------------------
// The first method declares and populates an Array,
// then iterates through it as a List.
// -----------------------------------------------------
void iterateOLI1() {
OpportunityLineItem[] arrOLI = [
SELECT Id, Quantity
FROM OpportunityLineItem
];
for (OpportunityLineItem iOLI : arrOLI) {
Id wrkId = iOLI.Id;
Decimal wrkQty = iOLI.Quantity;
// Do something
}
}
// -----------------------------------------------------
// The second method declares and populates a List,
// then iterates through it as an Array.
// -----------------------------------------------------
void iterateOLI2() {
List<OpportunityLineItem> lstOLI = [
SELECT Id, Quantity
FROM OpportunityLineItem
];
for (
Integer i = 0;
i < lstOLI.size();
i++
) {
Id wrkId = lstOLI[i].Id;
Decimal wrkQty = lstOLI[i].Quantity;
// Do something
}
}
}
If you were to adopt my preference for List structures rather than Arrays, you might end up having to re-code. That’s why I mentioned that this topic steps a little outside the realm of style. Therefore, please use care if you take this route. Ensure you test your changes thoroughly according to standard “good practice”.
From time to time, you will come across a scenario where one structure will need to be copied to another, and there’s no option but to do it “the hard way”, as in the example below. But do you want it to look good?
Here, I’m going to take a look at the condition part of the if statement. In particular, how best to write a complex condition to allow for readability and easy code maintenance. Sometimes even just a small number of ANDs and ORs can be easy to write but difficult to untangle later. Add in some brackets for changes in operator priority and the picture becomes even worse. I will refrain from filling up this post with words because I think the example below will provide most of the colour and information I’m trying to impart on the topic.
When you substitute the conditions for real-world variables, function/method calls or complex structure sub-fields, the results can be less than legible. But, apply a little indentation and split your conditions up and you suddenly have some clarity.
This article deals with the humble if/then/else statement, specifically the executable part of the statement. As before, I’m writing in Apex code, so there may be minimal syntactical differences between this and similar, related languages e.g. C & variants, Java, etc.
We can start with a simple, common binary use of the if statement:
if (a == b) runSomething();
else runSomethingElse();
Figure 1, above, is a simple case of “if a = b then run something, otherwise run something else“. It looks perfectly fine.
if (a == b)
runSomething();
else
runSomethingElse();
Figure 2, above, is almost identical to Figure 1 except that the executable part of the if and else clauses are on separate lines and indented. A little better. More readable, perhaps, and functionally identical.
if (a == b) {runSomething(); } else { runSomeThingElse(); }
Figure 3, above, has expanded on Figure 1. The addition of block braces around the executable sections serve to demarcate the runnable parts of the code.
if (a == b) {runSomething(); andSomethingElse(); } else { runSomeThingElse(); andRunAFourthThing(); }
Figure 4, above, is an example of where the programmer has added some extra method calls into the two executable blocks. This would not be possible for Figure 1 and Figure 2 above without the addition of braces.
if (a == b) {
runSomething();
}
else {
runSomethingElse();
}
Figure 5, above, is where we FINALLY come to the version that I’m happy with. The if and else clauses are on their own lines, block braces surround the executable sections of both clauses and indentation completes the picture.
if (a == b) {
runSomething();
andRunSomethingElse();
}
else {
runSomethingElse();
andRunAFourthThing();
}
Figure 6, above, is a clear illustration of how easy it is to add two method calls without upsetting any of the surrounding lines of code in Figure 5. No braces need to be added because they are already there. The value of this style is that you may wish to add multiple lines within any of the code blocks; this makes it very easy to do and retains code legibility.
As ever, please feel free to post your comments, whether you agree with me or not.
Style, in any artistic or professional endeavour, is impossible to quantify, define or measure. It’s highly subjective and can often be controversial. So I’m going to push my own opinions in this, the first of several posts on the subject of coding styles. They won’t be complex articles, merely a look at what I think is poorly-written code versus how I believe it would be better presented. There will be no attempt to discuss whether the code in question is inherently “correct”; merely that it looks difficult to read and is hard to maintain. The aim is to turn both of these problems around, thus making the code easy to read and maintain.
In cases where there may be several variants, I will present them, and give a synopsis of how “stylish” I think it is.
Your comments, as always, are very welcome on this topic.
Example 1, SOQL Queries in Apex:
Let’s start with a common code segment whereby a SOQL Query is run and the resultant record set is returned into a list data structure.
List<Custom_Object__c> lstRecords = [select id, field1__c, name, number_field__c from custom_object__c where name like 'Smith%' order by lastname, firstname limit 100];
Figure 1, above, shows how an “undisciplined” programmer might put together a code segment that retrieves a record set from a SOQL query. In an IDE or other editor, this might well appear as a single line and you would have to scroll right to see the full detail.
List<Custom_Object__c> lstRecords = [select id, field1__c, name, number_field__c, an_additional_field__c, and_another__c from custom_object__c where name like 'Smith%' order by lastname, firstname limit 100];
Figure 2, above, would show the result of adding two additional fields to be retrieved by the query. Not very pretty.
List<Custom_Object__c> lstRecords = [
SELECT
Id
, Field1__c
, Name
, Number_Field__c
FROM Custom_Object__c
WHERE Name LIKE 'Smith%'
ORDER BY FirstName, LastName
LIMIT 100
];
Figure 3, above, is how I would put this snippet together. I find this more professional-looking, much easier to read and far easier to modify. The following improvements have been made:
the outer data structure is separated from the inner SOQL statement
code is indented in a useful way
keywords are uppercase for readability
query clauses are split onto separate lines
fields are also split onto distinct lines and vertically-aligned to enable simple editing
field names have been retyped with appropriate letters in uppercase
You may not agree with the word “improvement”; please let me know if you don’t, and the all-important reason why.
List<Custom_Object__c> lstRecords = [
SELECT
Id
, Field1__c
, Name
, Number_Field__c
, An_Additional_Field__c
, And_Another__c
FROM Custom_Object__c
WHERE Name LIKE 'Smith%'
ORDER BY FirstName, LastName
LIMIT 100
];
Figure 4, above, shows the result of adding the same two additional fields as in Figure 2. The results speak for themselves.
More code examples to follow soon. Why not follow the blog to get email notification of new posts?
Acronyms used above:
SOQL = Salesforce Object Query Language (a proprietary variant of SQL)
IDE = Integrated Development Environment (e.g. Eclipse, MS Visual Studio, NetBeans, JDeveloper, Xcode, etc.)