Salesforce Mobile Developer Week – TCDUG will be there!

Capture

Hello everyone!  Salesforce is kicking off an incredible “Mobile Developer Week” from April 21st to April 27th, 2013.  The Salesforce.com Twin Cities Developer Group is excited to be part of this!

Please come and share in the fun!  Josh Birk will be in person to demo some new technologies as well as answer your questions.

Check out our Meetup.com group for more information.

See you there!

Expanding your Brain and Taking a Risk

brain-power-imagejan2013-programHello again everyone!

If you follow me on here or on Twitter, you are probably wondering where the heck I went for the last three months.  For the last year, I’ve been VERY active on many fronts, but then I pretty much went silent.  Timing was unfortunate as right in the middle of this transition, I was honored with the Force.com MVP designation by the Salesforce.com community.  Fret not everyone, your faith in me is not misplaced.  =)

Why should you keep reading?

Because Salesforce is awesome and by the end of the post, you’ll see why it’s always important to try new things to expand your brain, even if it seems a little odd.  (tl;dr at the bottom)

Ok, I’m in, what’s the scoop?

I was approached last year by a group of people that I’ve known for some time that had a successful and profitable business but were looking to take the company to that next level.  Without miring you in the details of the company history, it needed some very focused energy and fresh blood to get it there rapidly.

They were of course looking for technical direction, leadership, and knowledge, but more so they were looking for someone who could strategize and think further out to “what’s next in technology?”.

This company does lead generation – not exactly in the development / deployment wheelhouse of Salesforce that I have been heavily invested in for the last five years, but it’s that space that we developers and technical people rarely go – the actual real-world execution of “marketing and sales”.  Questions like:

  • “How do we best position web traffic and optimize web pages to capture the highest number and best quality leads, track them through the conversion process, and then further monetize them on the front and back end?”
  • “If a lead contacts us through multiple channels, how do we best maintain a single lead record by capturing and combining all data to best capitalize on opportunity?”
  • “How do we choose the best program or product for this lead in real-time based on their usage habits?”

Normally, it’s the “HOW” that we architects and techies tackle.  Enter the “WHO”, “WHAT”, “WHERE”, “WHEN”, and “WHY” that happen before the “HOW” hits your desk as a smattering of emails and pre-set timeline expectations.

picard-facepalm-300x260So, role-playing for a minute…how many of you have been in the situation where the business comes to you with “ok!  We’ve done our research, here’s what we need to do…”?  Inevitably, the next thing that comes out of your mouth is, “well you know, if you do [x], you’ll be able to far better [monetize / report / enable other opportunities]?”

If you haven’t raised your hand, nodded your head, or smirked at that last part – hold tight, you’ll experience that soon enough.

So how does Salesforce tie back into this?

Salesforce is Customer Relationship Management at its roots.  Everything that is done starts and trying to make money, and finishes with making more money through customer satisfaction, retention, and product innovation.

(C’mon, let’s not beat around the bush – that is truly why we all do what we do)

I firmly believe that Salesforce has proven themselves in the market as the leading platform by at least two laps.  There are a lot of things it does well just as much as there are things it doesn’t necessarily rock at.  I’ve struggled with this for a long time – trying to figure out “why” that specific sales rep wants “that feature”.  Is it because they are on to something I haven’t heard of yet or maybe they’re just weird – who knows?

Unless you actually work in that Sales and Marketing world – do you truly know why “they” do what they do?  Why does lead status really matter?  Why is certain data so valuable to certain people?  I fancy myself to be rather insightful as to a lot of it, but without ACTUALLY living it, it’s all really just conjecture.

Serious question – apart from the SFDC product team, who really knows all of the features that Salesforce can offer?  How do you even know what really to ask if it handles?  The answer is you will never know unless you get your hands dirty – be a fly on the wall in the sales strategy meeting, take a new position that allows you to think differently, really anything that gets you away from only staring at code and admin screens all day.  Get out, talk to the users, get engaged at a strategic level.  Leave your “ooo! ooo! I can solve that with [x]” technical brain home for the day and just listen.  There is always time for you to hit your Ballmer’s Peak later that night.  =)

Ok, tl;dr.  Why am I reading this?

Never become complacent with your level of knowledge.  Always strive to look into the haze to understand the “WHY” behind the “HOW”.  For a technical person, taking the time (and sometimes risk) to step out and immerse yourself into the “uncomfortable” to better understand why the business world does what it does is an incredible opportunity.

Check back to my previous post, “Developers are the new Kingmakers” to get some background on this – and never be afraid to take a risk.

Thanks for reading!  I know it was a bit of a rambling post, but it’s been far too long to keep it to a simple technical article. =)

Questions?  Comments?  Hit me up below or connect with me on Twitter @andyboettcher.

Developers are the new Kingmakers

Kingmaker:  In game theory, a kingmaker is a player who lacks sufficient resources or position to win at a given game, but possesses enough remaining resources to decide which of the remaining viable players will eventually win.

Reid Carlberg posted on Twitter today a link to a speaker at the IBM Impact Unconference.  James Governor speaks to the room about how “developers are the new kingmakers”.

Great video.

Then, the last 3 minutes totally nailed it home.

“Look at the skill shortage we are facing, if you are willing to learn new skills, you are going to be very employable. This isn’t a biased market.”

I have been so fortunate in who I’ve known, who I’ve worked for/with, and what I have been able to do throughout my career where all eyes have always been on the prize. That said, there are a lot of people I know that are working in technology *jobs* where they are pigeon-holed or brow-beat into just contributing to some exec’s grand view of something.  Stress, the feeling of hopelessness or being trapped in their current job drags on you, your family, and your friends more than you realize.  Even those who aren’t primarily in technology need to really stand up here, watch the video, and take notice!

This couldn’t be more valid today. We are DEEP in a new world of technology, promise, and hope.  The technology work environment of the 90s and honestly even the early 2000s was “big machine, big project, big code, big <insert buzz word here>.  The tools and technologies available back then while awesome – are tiny and weak in comparison to the tools and technologies of today – and those of today are going to be tiny and weak in comparison to those of tomorrow.

There’s the old adage that “as soon as I buy a computer, it’s obsolete as soon as I get it home”.  To be honest, it was obsolete as soon as it rolled off the assembly line – but the same is true of any skill, especially today!  Look at what technology has really come to the mainstream in the last 5 years – Google, Facebook, Amazon, Netflix, Microsoft’s XBOX line, I could go on and on.  Did any of this exist in their present form 5 years ago?  No.  Are they going to exist in their present form even a year from now?  Absolutely not.

There has always been this mystical cloud around technology.  People who aren’t in technology right now just see it as a near vertical learning curve that requires tens of thousands of dollars and going back to college for years  to gain any foothold.  Even those people who are in the field are tentative about learning new languages and approaches out of fear that they won’t be regarded as “the expert” anymore or even the more ridiculous “some guy on a blog said that (language A) is horrible compared to (language B)”, or even worse “(insert language name) isn’t for REAL programmers.”  WHAT A LOAD OF BS.  Worse yet – at least in my experience, it’s nearly impossible to dislodge that crap from someone’s head once they hear it…even if they heard it from some random blog somewhere.

Come on in everyone!  The water is FINE!  =)

All you have to do is take that leap, take a weekend away from everything that draws your attention and give it back to yourself. Talk to your peers, get on some blogs and find out where people aren’t just making great money – find out where people are making great money AND ENJOYING EVERY MINUTE OF IT.  Once you find that thing – dive in.  If you find out that you don’t like it, don’t give up hope – find the next thing!  You’ll eventually find something, I promise!

I was incredibly fortunate to come across Salesforce.  I have been able to take my love for figuring out puzzles and creating awesome things and apply it to an area where 1) a platform exists to answer most questions without code, 2) what can’t be answered without code can be done so without having to worry about if a server is up or not, and 3) what I can’t figure out – an incredibly active and forthcoming community exists and helps at the drop of a hat.

So why this long rambling post?

Yeah, you’ve read a lot – some of it may have made sense, maybe none of it you think applies to you.  This blog is aimed at those of you who want more; those of you who may feel stuck in your current lot in life and don’t think you could ever take advantage of the amazing levels of personal gratification and honestly – cash – that comes with being involved with and being good at technology.

Right now, I know of over 50 positions for different kinds of developers that people ask me if I know of anyone looking for a cool opportunity.  Local, remote, relocation, you name it – the kicker is that either the people I know are 1) truly happy where they are at, 2) don’t think they could do it would take to make a move, or 3) still have the “I’m thankful to have ANY job” mentality.

I don’t want to offend those of you who are un/under-employed, but there are a few people that I’ve had conversations with who have been looking for work for over a year – or those who are underemployed doing things they never had a single thought they’d ever be doing to feed their families.  Technology is so embedded in every single thing we do – I struggle to think of ANYTHING that anyone does that modern technology didn’t have an effect on in one way or another.

We live and breathe technology – if you think you can’t do it, you’re just flat wrong.  You are so much more valuable and talented than you are giving yourself credit for.  Are you going to be an ace developer in 6 months?  No.  Could you potentially have the skills to get your foot in the door?  Without a doubt.

Get out there and learn – meet people, go fast, fail fast.

“Fail Fast?!?  What do you mean FAIL??!?”  Yes!  Earlier in this ramble, I mentioned that people have this mystical cloud surrounding technology – that they don’t think unless they played with a keyboard in their crib, that they just don’t have any chance.  That, and the corporate mantra of the 80s, 90s, and early 00s was “Never tolerate failure!”

Either one of those mindsets, let alone having both – are just motivation killers.  Everyone fails.  Honestly, I hope to fail every single darn day of my life – that’s the ONLY way that we learn.  If we never failed, we’d never take risks, and it would take FOREVER to get anything done.

Think about it – how many times have you failed today?  I put my shirt on backwards this morning because I was in a rush – that’s an example of a fail.  (abeit a strongly abstract one).  What counts is how you react to it, learn from it, and make something even better than what you were thinking of originally.

IMHO, that’s one of the biggest things that I try to help people to understand and overcome.  Fail – fail often, fail fast.  Take for instance Facebook…(from http://bit.ly/TvabX2)

Facebook’s culture of “fail fast” is one of its greatest assets:

“Move fast and break things” has continued to drive the company’s evolution. Instead of extensively focus-grouping new features, Facebook just rolls them out. Then it listens to users’ screams and makes modifications as appropriate. This technique has produced a lot of duds. It has led, on many occasions, to Zuckerberg having to apologize to his users. It has also produced some of the features that, in the minds of users, today are Facebook—such as News Feed. What the critics miss when they blast Facebook for “mistakes” is that the process is deliberate. And it works.

That’s exactly it – the world goes SO fast now and so many cool and exciting new technologies are constantly being rolled out, improved, and enhanced – you can’t apply the same old approach of “never fail” to this new world.

Get out there, learn something you haven’t done before, make it better.  Rinse and repeat.

What’s coming in the “next release”?

This is a great link to see what Salesforce Ideas are due out in the “next release” – I love parsing through this a few weeks before release. I had no idea about the new Contact Layout pilot – looks AWESOME!

https://sites.secure.force.com/success/search?type=Idea&sort=2&pageNo=1&filter=Coming+in+the+Next+Release

Come see me at Dreamforce 2012!

Good morning!

I am excited to announce that I will be speaking at two sessions at Dreamforce this year!

Enhancing the User Experience with jQuery

jQuery is a JavaScript library that enables easy access, traversal, and manipulation of the Document Object Model (DOM) in web applications. Join us to learn how jQuery can enable you to realize the full potential of rich internet applications that leverage HTML5. From table sorting to animated transitions, from Ajax interactions to accelerated JavaScript development, this session will provide the foundation for changing the way that you write JavaScript.

For those of you that read my blog, you’ll notice that I did a very similar presentation at Cloudforce San Francisco in March this year.  I’ve expanded / improved the presentation and added a really cool new “drag and drop” section that deals with Opportunities and Opportunity Products.  I’m excited to show it off!  After the presentation, I’ll post it all up on GitHub for everyone to share.

Bringing the Salesforce Platform to the local level with Developer User Groups

I am the Minneapolis Salesforce.com Developer User Group leader, and was invited to share my experiences and perspective on how awesome user groups are and why you need to be part of one.  =)

Haven’t signed up for Dreamforce yet?  I can help you out on the cost.  Use the code “SPKREF” to save 20% on the registration fee.  Hope to see you all there!  Let me know if you are coming and we can connect up.

Salesforce Test Classes

(if you haven’t realized that most of my pictures are tongue-in-cheek, let it be know now…LOL)

For any of you that have come from previous Object-Oriented languages to APEX, you have undoubtedly taken on the mantle that is APEX programming with whatever learning curve you had to go through.  We all have come to one single unifying rally point – being grumpy with Unit Tests.

Let me be the first to say that I fully support the concept behind Salesforce requiring Unit Tests for their code – wholeheartedly.  Anything that can help support their uptime metrics and keeping users from calling me repeatedly to ask “when will the system be back up?” is A-OK on my list.

Salesforce has also done a pretty darned good job at providing the developer masses with neat tools to achieve  that magical minimum 75% coverage.  I’ll also be the first to admit that Unit Tests were definitely a brain-bender for me to fully understand how to do RIGHT.

In this blog post, I’m going to try and line out some of the major Unit Test tenets that I’ve learned of and been burned by – please feel free to comment/reply down below if you have any more to add or if I’m just totally off my rocker on anything here.

Item #1 – Comment Your Code!

Please, please, please….comment your code.  It doesn’t count against any limits and it only helps everyone in the long run.  I hope and wish everyone with the most stable and long-term job endeavors, but realistically people come and go.  You will move projects, responsibilities, even companies – and the code you leave behind is your legacy.  As a consultant, I swear one of my responsibilities is to be thrown under the bus when something goes wrong (hey, I’ll take it) but the less you shoot yourself in the foot, the better.

This applies for BOTH regular code (APEX and VF) as well as your Unit Test Classes.  Go out for the weekend, knock a few too many back, then come back Monday and try to read your code.  (please don’t write any…) Stumble a bit?  Add more comments after you sober up, then add more after that.  I’ve never cursed a developer’s name because they commented too much.  Honestly I don’t care if you can’t spell either.  =P

Item #2 – Consolidate and Reuse your Code!

This is another core design tenet from Object Oriented programming.  If you have to go to another class to “see how you created that”, that code should be in a public utility class so it’s just written once.  Nothing gets me worse than fixing code in one place, and then watching my code fail compilation because the previous developer copied and pasted it in ten other places.

Salesforce to the rescue!  As of Winter ’12, they now allow us to have public Test Classes.  Awesome to the max, like totally dude.

The first thing that comes to mind when wanting to create truly good test classes is that you should never test against your organization’s data.  (See Item #3!)  Prior to Winter ’12, that meant unfortunately copying and pasting a litany of script and DML statements in each of your test classes (subsequently violating the title of this section, but I digress…) and falling prey to update hell when a rogue admin goes and makes a field readonly at the FLS level.

Enter Public Test Classes.  My typical implementation is to create a standalone “@isTest public class” to house the creation of data.  Break it out if you want into multiple methods, or have it be one big one:

@isTest
public class SharedResources_UnitTest {

//////////////////////////////////
// Don't forget your comments!
// Get a header in here!
//////////////////////////////////

public static void createAccount(String strAccountName) {

Account a = new Account();
a.Name = strAccountName;
insert a;

}

}

After that – it’s easy enough just to call it from your regular Test Class:

@isTest
private class createContact_UnitTest {

//////////////////////////////////
// Don't forget your comments!
// Get a header in here!
//////////////////////////////////

static testMethod void testCreatingContact() {

// Create Account via Shared Unit Test Class
SharedResources_UnitTest.createAccount('Test Account');

// Test Creation via System.Assert!
Account acct = [SELECT Id FROM Account WHERE Name = 'Test Account' LIMIT 1];
System.Assert(acct != null, 'createContact_UnitTest.testCreatingContact FAIL: Account was not inserted properly!);

// Create Contact
Contact conNew = new Contact();
conNew.Firstname = 'PeeWee';
conNew.LastName = 'Herman';
conNew.AccountId = acct.Id;
insert conNew;

// Test Creation via System.Assert!
Contact conTest = [SELECT Id FROM Contact WHERE LastName = 'Herman' AND AccountId = :acct.Id LIMIT 1];
System.Assert(acct != null, 'createContact_UnitTest.testCreatingContact FAIL: Contact was not inserted properly!);

}

}

Item #3 – Never test against the Organization’s Data

Yeah, it sure seems easy enough – and it was actually the default to do so back before Spring ’12 to be honest.  Heck, I’ve even tested against the Organization’s data before I got burned on it one too many times.

I think it’s great that Salesforce made it the default that you can’t see Organizational data.  Just as much as you created the classes and triggers to manipulate data, you should create the data that feeds them.  To be honest, it is just easier that way if you think about it.  =)

Getting burned – you have just written your version of Mr. Holland’s Opus in code, and you just deployed it with 100% test coverage.  You say, “meh, no one will ever delete that big account out of the system”.

You just sealed your fate.  Tomorrow an intern will be given the task to realign the accounts.  Boink goes your data, but you have no idea yet.

Enter yourself two months down the road and you have to tweak your code for the National Sales Meeting in the morning.  “Deployment Failed”.  Now you’re stuck up all night either being snakey and undeleting / recreating that account (perpetuating the problem) – or rewriting your Unit Tests properly to create your own data.  Either way, fail = you.

Yeah, it’ll take a little more time upfront to physically write the code, but you’ll pay yourself back in spades.

Item #4 – Use System.Assert!

Yeah, at first blush I didn’t either.  “I have coverage, why would I screw around with that now?”  For development in your own / corporate org, honestly you don’t need to use it.  You should, but you don’t HAVE to.

Why you should:  System.Assert (and the siblings AssertEquals / AssertNotEquals) validate that what you are doing equals what it should be at that point in your code.  It provides a hard fail / break in your code so that if something does go awry, you know exactly where and why – so you don’t end up troubleshooting somewhere way down the line.

@isTest
private class demoSystemAssert_UnitTest {

//////////////////////////////////
// Don't forget your comments!
// Get a header in here!
//////////////////////////////////

static testMethod void testSystemAssert() {

// Declare variables
Boolean bolValueOne = true;
Boolean bolValueTwo = false;

// Test 1 - the values should NOT match
System.Assert(bolValueOne != bolValueTwo, 'demoSystemAssert_UnitTest.testSystemAssert 1 FAIL: The values are EQUAL!);

// Set bolValueTwo to true
bolValueTwo = true;

// Test 2 - the values SHOULD match
System.Assert(bolValueOne == bolValueTwo, 'demoSystemAssert_UnitTest.testSystemAssert 2 FAIL: The values are NOT equal!);

// Set bolValueTwo back to false
bolValueTwo = false;

// Test 3 - the values do NOT match, but we are testing that they DO match (this will fail the test)
System.Assert(bolValueOne == bolValueTwo, 'demoSystemAssert_UnitTest.testSystemAssert 3 FAIL: The values are EQUAL!);

}

}

Think of your recent Unit Test class – how many lines you have in there and having something fail…at the end…and then backtracking up your code to see what the heck isn’t calculating properly.  System.Assert to the rescue.

That’s a good start, anyone have other ideas?

Comment below…

How to write a basic APEX Trigger

Does this picture have anything directly to do with an APEX Trigger? Of course not. However, it does accurately depict the frustration I experienced the absolute first time I tried to write a Trigger.  (Bonus points if you have seen Bloodsport…)

The purpose of this article is to provide a declarative Admin (a.k.a “ButtonClickAdmin“) a decent primer to writing their first Trigger.  I do need to however go through the “declarative before programmatic” tenet – meaning that you always try to make something work through the Salesforce UI before going to a code / programmatic route.  A lot of triggers I’ve seen out there were written before a lot of the new cool features of Salesforce have been released – keep in mind these things:

  • Formulas
    • Salesforce provides you a rich relational pathing ability to grab fields of a Parent or Lookup simply by building it through a formula
  • Workflows
    • You can do Field Updates, Tasks, Emails, and Outbound Messages using Workflow
    • As of Spring ’12, you can now do “cross-object” Field Updates – before Spring ’12 a LOT of Triggers I saw existed just to do this (page 152 of the Spring ’12 Release Notes)
  • Validation Rules
    • Apart from the cross-object stuff, this is the other area where a lot of Triggers are written
      • Which can be OK if you have CRAZY complex computations to perform that you just can’t do with a V-Rule formula…
    • Use V-Rules to do your traditional data validation on fields

Salesforce does have some great documentation to get you started:

I’m going to pick and pull apart the documentation to give you an example of how I wrote a trigger just a while back to automatically add a Chatter post to a parent record when a child record was created.  You could really take this example and apply it to creating a record in any business case however.

First however, let’s dive into how a Trigger is structured…

Structure of a Trigger

trigger AddChatterPostToParent on ChildObject__c (after insert, after update) {

This is defining your trigger.  It’s stating that this is:

  1. a Trigger.
  2. “AddChatterPostToParent” is the name of this trigger
  3. “ChildObject__c” is the object that this trigger will be firing against
  4. The database operations that this trigger will fire on – your choices are “insert, update, delete, and undelete”
    • “before” = you have the ability to CHANGE values of fields
    • “after” = you do NOT have the ability to change values of fields
    • Great post from Salesforce on the pros vs. cons on before/after HERE

When I’m typically writing triggers, I like to put some comments at the beginning to describe what I’m trying to accomplish:

trigger AddChatterPostToParent on ChildObject__c (after insert, after update) {

//////////////////////////////////////
// This trigger creates a Chatter Feed item for the parent record
// when a child record is created
// Created 20120718 Andy Boettcher
// Modified 20120718
//////////////////////////////////////

/* TRIGGER LOGIC WILL GO HERE */

}

Resources Available to You

When writing a trigger, you have a few objects already ready for you to use:

Collections

  • “trigger.new” – this is a collection of the new records you are working with.
  • “trigger.newMap” – this is an indexed collection (map) of the new records you are working with.
  • “trigger.old” – this is a collection of the OLD values of the records you are working with, such as in the case of an update.
  • “trigger.oldMap” – this is an indexed collection (map) of the old records you are working with.

True/False Variables

  • “What kind of action am I working with?”
    • Trigger.isInsert
    • Trigger.isUpdate
    • Trigger.isDelete
    • Trigger.isUnDelete
  • “Is this a before or after action?”
    • Trigger.isBefore
    • Trigger.isAfter

// Run this code if we’re dealing with an Insert only
if(Trigger.isInsert) {
blah blah blah
}

// Run this code if we’re dealing with an Update only
if(Trigger.isUpdate) {
blah blah blah
}

// Run this code if we’re dealing with either an Insert or Update only
if(Trigger.isInsert || Trigger.isUpdate) {
blah blah blah
}

** GOTCHA ALERT! **

Here’s one of the biggest “gotchas” you’ll encounter working with APEX and Triggers – you are already definitely aware that Salesforce has “limits” on just about everything; Limits on objects, fields, data size, etc.  The same goes for APEX, but you have to account for it yourself in your code vs. having Salesforce nicely remind you when you’re near the threshold.  The official term is “bulkification” – meaning that our code has to be able to handle anywhere from a single record up to thousands without hitting a limit.  I will absolutely show and describe how we are dealing with this in the examples that follow.

Trigger Logic

The best way I can suggest bridging the concept of writing a formula / workflow in Salesforce and writing a Trigger is to “speak” what you want to do.  As you’re writing the Trigger, it’s very easy to get stuck on a tangent and over-code your solution.  Speak it, write it down, and then go through your code when you’re done to make sure you didn’t get off track.

  • “On all records coming through my trigger, I want to create a Chatter Post on the parent object.” (this is our example)
  • “On only the records with a value of “Tuesday” on the “Day Of Week” field, I want to create a new record in the “X” object.”

Putting the Trigger Together

trigger AddChatterPostToParent on ChildObject__c (after insert, after update) {

//////////////////////////////////////
// This trigger creates a Chatter Feed item for the parent record
// when a child record is created
// Created 20120718 Andy Boettcher
// Modified 20120718
//////////////////////////////////////

// Create Empty List to hold new items (bulkification)
List<FeedItem> lstFeeds = new List<FeedItem>();

// Loop through Comments and create Feeds
for(ChildObject__c c : trigger.new) {

FeedItem fi = new FeedItem();
fi.Type = ‘TextPost’;
fi.ParentId = c.ParentField__c;
fi.Body = ((Trigger.isInsert) ? ‘created’ : ‘updated’) + ‘ a Child Object on this Parent.’;

lstFeeds.add(fi);

}

// Insert List if there are records contained within
if(lstFeeds.size() > 0) { insert lstFeeds; }

}

Those Pesky Unit Tests

With any APEX code, you need to write a Unit Test before you can deploy this new trigger to a Production environment.  Your Unit Test is meant to basically emulate how your code would be executed, and is structured to test if your desired result is what happens to come out of it.

To create a Unit Test for this Trigger, we need to create a Class that creates a Parent Object first, then creates a Child Object related to the Parent.  To be 100% kosher, we need to then update the new Child Object to cover both sides of the “if” condition for the Chatter Post body.

@isTest
private class AddChatterPostToParent_UnitTest {

static testMethod void testTrigger() {

// Create Parent Object
ParentObject__c p = new ParentObject__c();
p.Name = ‘Test Parent’;

insert p;

// Tell Salesforce that we are starting our test now
test.startTest();

ChildObject__c c = new ChildObject__c();

// Relate this Child to its Parent from the inserted record above
c.ParentId = p.Id;

c.Name = ‘Test Child’;

// Insert Child Record
insert c;

// Update Child Record
update c;

// Tell Salesforce we’re done with our test
test.stopTest();

}
}

Writing your first Trigger is kind of like jumping into the deep end of the pool with a lead weight belt, but that’s what your Sandbox is for.  Tinker, learn, ask questions…leverage the community.  You’ll get it.  =)