Dumb humor runs in the family

December 14th, 2008


Snow Day from Steve Andersen on Vimeo.

Testing Best Practices

December 9th, 2008

I’ve said it before–I’m not a software developer. I’m a hacker who got into this line of work via a circuitous route that never went through a comp sci class room. OK, that’s not true. I took one C class at the UW and quit midway through.

So now I’m writing lots of Salesforce code and as our complexity has increased I’ve had to get systematic about it. Part of the puzzle I had to learn from scratch was Testing.

Here are my top testing best practices with Salesforce.com that I learned on the job. Please comment if I’m misguided or skipping something of import.

Write fully portable tests

When you write your tests, you do so in the context of a Developer or Sandbox org. You can write tests that rely on specific pieces of data, user accounts, server names, etc. If you do that, however, your tests will fail on deployment because those things will be different in the destination organization.

Use relative URLs and query for names of data records rather than their specific Ids. Then if your tests pass in the sandbox, they are more likely to behave as expected no matter where you put them.

Don’t use production data in your tests

On a related note, if you do SOQL statements in your tests, those queries will return results from the Salesforce instance. So, if you SOQL “Id from Account where Name =’Microsoft’”, you will get one result in Sandbox and another in Production. When you set up test data, make sure to use names that will never show up in production, like “Microsoft_for_tests” as an example Account Name.

Test expected behavior first, then test unexpected behavior

Start with testing simple cases, and test to make sure that what what you expect to happen is indeed happening. Then make sure to add test cases for behavior you don’t expect, but could happen. This is why they tell developers never to write their own tests, because we all believe our code will behave as expected. Fight that urge, and test around the edges to make sure you’re covering yourself.

If you find a bug, write a test to expose it before you fix it

When someone reports unexpected behavior in your code or UI, write a test that will find the bug and fail. Then fix the code until the test passes, and leave the test in. By putting the test in there first, you’re doing test-driven development for this fix, which is a great practice to get into. If you leave the test in there, you’ve also now got a regression test in case you accidentally reintroduce that bug later.

Shoot for 100% coverage

Try to test everything. It’s not always fun or even possible, but try.

Don’t rely on Today()

If you are using dates in your code, don’t build your dates on Today(). Rather, use something like Date.newInstance(2005,10,10). By putting a date in the past, you don’t have to worry about what will happen to your test when you try to run it on February 29th, or the instant we hit daylight savings time. If you think those cases will affect your code materially, you should specifically test those cases, but most of the time you’re safe to ignore that by not using Today().

Put your tests on the controller and class, not in separate classes

We’ve found it easier to ship code around when the test methods are on the controller classes. It’s fewer files to keep track of, and when you deploy to production, you’re tests are automatically included in the package, ensuring code coverage.

Please comment if you’re interested in having a discussion about testing in Salesforce.com. I love and hate that they require 75% code coverage for deployment to production–it sure pays off in the end, but it can be quite a drag when I’m struggling with a stupid syntax problem in a test.

Salesforce, Google and Python

December 8th, 2008

Salesforce.com today released a toolkit for Google’s Appengine. Since Appengine is a Python-only environment, the key component of this integration is a Python toolkit to communicate with Salesforce.com APIs. My favorite line in the whole package is this one:

self.serverUrl = "https://www.salesforce.com/services/Soap/u/14.0"

That line of code shows that the Python toolkit is up to speed with the latest Salesforce API version, although there isn’t complete coverage yet. Our Plone integration has been using an older version of the toolkit, and we’ve been slowly working on upgrading it. Having Ron Hess upgrade it is a much better result!

Also in the Python toolkit is the ability to connect to the Metadata API, the API for creating objects, fields, and code. We’ll have to think about how we might use that in our integration.

I hope this brings more Python developers to Salesforce–this may get more people using our open source Plone/Salesforce integration, and help it to advance more rapidly.

Balsamiq nice mockups

December 3rd, 2008

I downloaded Balsamiq’s Mockup tool last week and have played with it a bit. I’m pretty impressed as it smartly hits a sweet spot between quick and dirty and presentation ready.

Mockups is an Air app for doing interface designs very quickly. There is a library of common interface elements: web browser chrome, input field, google map, tabs, etc. You simply drag these onto your mockup and go. Most have some simple configuration: title bar of the browser chrome, value showing in the drop down, etc.

Yesterday a user of mine asked for a specific feature in Salesforce.com. I used Mockups to draw it for my post, and for my Salesforce.com Idea post. I think the image speaks volumes in support of the idea.

I’ve tried lots of other mockup tools: Visio, Denim, Illustrator, Pencil, and many more that are now defunct. I like Balsamiq’s product a lot and I think you’ll see it in my posts for the foreseeable future.

I only wish someone would build some Salesforce.com widgets (like object lookups) and a Trac integration, I’d be in heaven!

Campaign Inclusion Reports

December 3rd, 2008

When you’re doing complex relationship management, you’ve got a number of outreach activities going on. Parties, one-on-one meetings, special nurture tracks, etc. It can be very bad for the relationship you’re trying to develop if these activities are in conflict. You need to make sure they all play nice together as far a content, timing, and execution goes.

You also need a system to help you grab people depending on which activities they have been a part or, or have not been a part of. Example: give me everyone who attended our luncheon and isn’t on our special VIP nurture track. It’s these people who I want to reach out to with some special information. But I don’t want the VIPs to get this info, because they’re getting something in a couple weeks that is more in-depth.

Right now Salesforce.com can’t do this kind of reporting. I can look at inclusion on certain campaigns, but can’t look across campaigns. I wish I had a report with this kind of interface:

This way I could pull out people based on what they have and haven’t done. If you agree that this is a worthwhile feature, please vote for this idea!

Thankful for my family

December 1st, 2008

Anderspotts

I hope everyone had a nice Thanksgiving!

Ideas–fishing for votes

December 1st, 2008

Here are Ideas I’ve posted that I’d love to get implemented. I’d love your vote if you agree!

Allow APEX triggers on junction tables like CampaignMember

Make CampaignMember, Partner, and ContactRole tables Customizable

Show the Report Data Type on the saved Report

Show CampaignMember Related List on Campaign Layouts

Use VisualForce email templates in Mass Emails and in Apex Outbound email method

Sites: Allow Unauthenticated Users to Edit Standard Objects

Fields marked Read Only on Layouts shouldn’t be editable for Sysadmins

Allow VisualForce Detail Page to be an edit form

First and Last in Rollup Summary fields

Help Text for Standard Fields

Make Opportunity Contact Roles RecordType Specific

Allow Reporting on Full Activity History

“Subtract from a Campaign” Button on Reports

The next generation…

November 21st, 2008

will see the world differently.

smart president

Maildrop 2 beta released

November 20th, 2008

The brilliant Simon Fell, father of the Salesforce.com API but apparently not the father of Applescript, has just thrown a new beta release of Maildrop, his Mac application for getting emails into Salesforce.

If you’re a beta-testing kind of person, give it a shot and give Simon feedback!

Dave Manelski on Vertical Response Integration

November 18th, 2008

My co-worker Dave Manelski wrote some Apex to help the Salesforce.com / Vertical Response integration record bounced emails better. His code just got posted on the Vertical Response blog.

Nice work Dave!

Gokubi.com is written by me, Steve Andersen

I'm a CRM consultant at ONE/Northwest implementing Salesforce.com for environmental nonprofits in the Northwest United States and British Columbia. I've been working with Salesforce.com since 2005 and working with nonprofits since 2001. We're at a point in time where agents of social change can get access to the same quality technology systems that large corporations can. I do what I do because I want to help people take advantage of this amazing opportunity.