Unit testing is an important programming skill but often times underestimated by programmers. David Reed shares what unit tests are and how to create good unit tests in Apex to guarantee production code quality.
Main Points
- 75% code coverage in Salesforce Apex
- Unit testing definition
- Unit test v.s. Integration test
- Mocking in unit test
- 5 Unit test scenarios to create good unit tests: 1) positive 2) single record 3) bulkified records 4) negative 5) no action
- Unit tests as the documentation
- Lines of unit test should be more than production code
- How to create good unit tests in Salesforce
- Test Driven Development (TDD)
Links
Contact Me
If you enjoy this podcast, please reach me out to let me know your thoughts or simply say Hello. My (Xi’s) contact info:
Take care, until next time :)!
Transcript
AI-generated, unedited.
[00:00] Episode fourteen: The Unit Test. Thanks for tuning into the Salesforce Way podcast.
[00:22] Salesforce Way is the podcast meant for Salesforce developers. In each episode, I invite a guest to share the inside of a topic. Our goal is to at least slightly help you, not only in the Salesforce world, but in general, become a better software engineer. If you like our content, consider to follow us by the RSS feed or in the iTunes, so you won't miss any updates. In addition to the podcast, there is a newsletter where we share more useful information, such as other chats with the guests, good developer videos, learning courses, mistakes to avoid, and so on and so on. If you are in the journey to become a good software engineer, just like me, I'm confident that you will find it home after subscribing to the newsletter. So the RSS feed, the iTunes link, my Twitter, the newsletter can be all found at our website SalesforceWay.com. Now let's start the show, shall we?
[01:31] I
[01:45] always consider unit tests the bubbles surrounding your production code functionalities. They're small, running fast, and make sure your production code runs as expected. It's fantastic, right? We all agree that every developer should write unit tests. But it's not easy at all to write goddamn good unit tests. Of course, there are multiple reasons. In this episode, David rejoins me to share his experience in creating unit tests in the Salesforce platform. So, what is unit test? How to create good unit tests? And what are the unique challenges we have in this platform? So, stay tuned and we're diving in.
[02:29] Hello, everybody. This is Xi Xiao. This is yet another episode of Salesforce Way podcast. Today, I'm sitting with David Reed. Hello, David. Hello, Xi. So, would you introduce yourself? Sure. Hi, everyone. My name is David Reed. I'm a Salesforce developer, administrator, architect, etc. I'm based in Philadelphia. She and I are here to talk about unit testing, which is one of my my key interests. I'm especially into things like automated testing on the Salesforce platform and deployment and lifecycle operations. Yeah, excellent to have you on the show. You know, back in my college time, which was like many years ago, the first time I was impressed by the unit tests was that I need to let's say return assignments. To the remote system, so it was a really interesting and small functions that I need to encrypt the stream and then speed out that stream. So basically a simple function, and then I upload it to the remote system, and automatically the remote system would judge my assignment and then make a score. For my assignment, then I was wondering how he did it, and then turned out it has like tens of those unit tests surrounding the functions. So it covers all different scenarios, and then according to how many of the
[03:59] tests has passed from your assignments, then it will score your final. You know, was like three out of five or four out of five. So that was the first time I was really amazed about the the testing. So I didn't know it was like unit test or system test or whatever. But it definitely was like an eye opening. Event for me back in the days, so that was the first experience. I wondered, okay, so we don't really need an external tester to help us as a software engineer to test our application. We can do these things by ourselves. And then in Salesforce, as I understand, we have to cover the code to seventy five percent, right? That's a limit for us. That's a threshold we need to pass. That's right. That's right. So, but I have seen a lot of project in Salesforce. They have done a lot of tests surrounding the code, but I still don't quite get what does it mean unit test? Because I see there are different. Uh, terminologies. There are integration tests, system tests, to service tests. Could you tell us what what are they and what is unit test? Absolutely. So maybe we can start with with that 75% code coverage metric that that you mentioned, for sure, for sure, and and explore what that's. Doing for us, or what it's trying to do for us, and see how that leads us into kind of the world of different suites of tests that we
[05:29] can run. So as we as we all know, if you're trying to do a deployment on Salesforce into a production org, you have to have this 75% code coverage metric met. What that means succinctly is that when you run the automated tests that are part of your Salesforce development, if you're writing Apex, 75% of the executable lines of code in your classes, including your triggers, your trigger handlers, your Apex batches, and everything else you've built, has to be touched during the course of the test execution. They have to run within the scope of your of your test. And if you don't hit that metric, you're not going to be able to deploy to production. This is in a lot of ways both a blessing and a curse, I think, for Salesforce. It's a blessing because it forces us to test our code, and I think we all have kind of a, at least a general appreciation of how important testing is. No one wants to be that person who accidentally caused damage to your production Salesforce instance and maybe cost your company a lot of money. And testing, again, we have this kind of general understanding that testing is a way that we can help guarantee the efficacy of our code and the correctness of our code to avoid that. But I think what you're getting at with your question, Xi, is that there's a lot of there's a lot of undefined space there in terms of how does code coverage actually relate to testing? How do the tests that we're running Meaningfully guarantee that our code's going to work, that it does what it's supposed to do,
[06:59] and what are all of these these complex distinctions that get brought in, especially from folks who have experience building software on other platforms, like a unit test versus an integration test versus a system test. So again, if we lead in with that seventy-five percent metric, right? The way I like to think about it is. The 75% code coverage metric is a proxy. It's an attempt to measure how effectively and how thoroughly we're testing our code. It's not a great proxy metric, but it's the only one that we have. And because it's the only one that we have, it can it can sometimes distort the way that we think about unit tests. We we start aiming for writing tests that cover code rather than tests that test code. That's it's a temptation. It's a temptation that I hope we all try to avoid. And one of the ways that we can reframe that problem is by going to this distinction of terminology that you're talking about, Xi, where we distinguish between different kinds of tests and start to think about what they're actually doing for us. Okay, so sounds good. Yeah, so so if we dive in there, the the the top level thing that I always like to say to to frame how I think about unit tests and to try to help other developers think about them beyond code coverage is that your testing program as a whole is meant to be a promise. It's a promise you're making to yourself
[08:30] as you continue to work on this Salesforce org, and to your employer or to your client as you're delivering them code, and also to the other people who will work on this Salesforce instance potentially five or ten years down the line. And the content of that promise is: so long as my tests work, my code also works. And conversely, when my code is going to fail. My tests will also fail. In that way, I think of tests as also being a proxy. So your code coverage is almost like a proxy measurement of a proxy measurement. But the critical thing that you're trying to to measure and that you're trying to make a commitment about is that you have a way of saying in a fully automated way. My code is currently working, or my code is currently not working, based on the totality of what's going on in your Salesforce org, including declarative changes and Apex and everything that you have. That's the top level. That's the most important thing that guides every choice made in unit testing, as far as I am concerned. The next, the next layer is when we start talking about these different kinds of tests, and and to me, those distinctions are pragmatic. Decisions. They're tools that we use to help us make better guarantees about the performance of our code. And the the biggest distinction there is between a unit test and an integration test. And it's also a distinction that's kind of hard to make on Salesforce for reasons that we'll get into here.
[10:00] At at its core, what what the distinction means is that a unit test is a small test. It's testing the smallest, isolatable piece of your code. By itself, and validating that that small building block does what it's supposed to do, and doesn't do what it's not supposed to do. The theory being that when you test each of those little building blocks in isolation as a unit, and they're all valid. That it lets you catch bugs early at the lowest level level of your code. So when you start assembling those building blocks, you have a lot fewer bugs to catch as you move up to the the next and more complex layer of testing, which is called integration testing. And integration testing refers to those those tests which bring those units or building blocks of code together and operate them as a larger scale unit, a connected. A connected system of code and teases out bugs that happen when one class talks to another. So I can give just a quick concrete example before we turn, you know, to the next topic. I would say that an example of a of a unit could be one. Utility class in Salesforce. You you factor out some common code that you use in many different places. You put it in a utility class, and that can form a great unit. You test it in isolation. And find that it works, and then you also want to write some integration tests where you bring that utility class together with its consumers, like
[11:30] a trigger handler class and a batch class, and you test the operation of those classes as a combined unit or system of code with an integration test that validates not only that each one works by itself, but that they also work in combination.
[11:47] So, because I try to visualize the examples and the things you just explained to me, so to me, we're building the the solution. It's like we're putting Lego pieces, like construct them into a final block, and instead of testing the final block, we. In the unit test, we test each Lego pieces. That's the like smallest pieces that we can test, right? That's what you mean, like test the color, test the size, test if it's pluggable to the other applications, other part of the applications or not. So that's kind of like a unit test we we we define here. But the once we construct the Lego into, for for example, a building. And then we test whether the building has four floors, has how many windows, and how many stairs. Those things are coming from the combination of those Lego pieces. And of course, if some of the Lego pieces failed, the building function some of the building function would fail as well. So that's somehow what I understand. I don't know. Does it match to what you just said? Yeah, I think that's a really good analogy. And if I can kind of extend the analogy. A way that we can see the pragmatic benefit of talking about testing this way and and distinguishing between unit and and integration testing is,
[13:17] if you put those building blocks together and construct a building. And the building teeters or falls down. You can very easily see that you have a problem at the top level, right? There's something wrong with the building. But what you can't necessarily see from that top level result is what led to what led to the problem, where's the root cause? In many cases, unit tests will help guide you to the root cause. It's not a perfect solution. A unit test is not always going to identify the root cause of a problem. But they are pragmatically a very useful tool to be able to say when my top-level system fails, I have a guide in the form of unit tests to point me to what specific entity within my large and complex code system has an issue with it that could be leading to this larger-scale problem. Okay, but given that we are writing good unit tests, right? Of course.
[14:16] All right. Um. Okay. So you just tell us what's the difference between the integration and the unit test. Are we now moving on to the good unit test? So we just talk about it. So what are the good unit tests? Yes. Ah. So that's that's a big and complicated question. And if you ask many different engineers, you'll probably get a lot of commonality, but also some differences in how they like to structure those unit tests. And there are many books about the unit tests, right? In different languages, even there are absolutely. And one of the challenges that we particularly face in the Salesforce platform is that is that our platform and our our Development environment doesn't look the same as many other environments and doesn't provide the same capabilities. So, for example, when I'm writing unit tests in Python. I have the freedom to use a really large and sophisticated mocking library. A mock in a unit test context means that you're you're replacing some piece of code in your system or a web service that you're talking to with a test implementation that does something very predictable, so you can control the conditions of your test. We do that in Salesforce too, and I'll talk about it more in it in a while. But in Python and in other languages like that, you have the freedom to mock or replace in a test context almost everything that's part of the environment. So you can really narrow down your unit tests and say, I've controlled
[15:47] all of the inputs. I've controlled all of the environment around this piece of code. So I know for sure. That there aren't any external skews that change the results of my testing, I can't really do that in Apex. I've got some ability to do mocking. We've got we've got great mocking capabilities for web services, for example, in Apex. But what I can't do is say, I want to. I want to replace the system database class with a mock database class that returns the same results every time. That's not available to me. So when I'm thinking about the distinction between unit tests and and integration tests in Salesforce. Sometimes that distinction gets a little bit blurred. We can invest in our infrastructure to try to maintain the brightness of that line and the purity of our unit tests, but it does take some infrastructure work. And there's points that we'll get to where we can't really be as rigorous about it as we might like. I think my my sense though is that even even in that case we can still write good tests on Salesforce and we'll let's let's get into what that looks like. But just just before you dive into this, I just want to make sure our listeners understand. So you mentioned the unit tests and you mentioned the mocking. So I understand. Why do we need mock? Is that The the functions that we want to do the unit test against may have some dependencies. For example, it might it might fetch the data from the remote, for example, REST API. But in the unit
[17:17] test, we don't want to really call out to that REST API and fetch the data, right? So because of that, we use the soap and mocking, which you create a A fake or a dummy data, and return to the function so that the function can really start execution. Absolutely. So one of the key hallmarks of Making a unit test or any kind of test useful to you, meaning that its results are are this meaningful promise about the behavior of your code, is that it is repeatable and it's reliable. Every single time you run the unit test, provided that nothing in your code has changed or its environment has changed, it should return the same results. In order to be able to make that guarantee. You need to be able to control the environment within which the code is executing. a great A great feature in Salesforce that that illustrates this is that that annotations see all data. That most of us have probably been taught you shouldn't be using on your unit tests. It allows your unit tests to see the actual data in your Salesforce org. Well, the the key reason why you don't want to do that is because it it violates that tenet of guaranteeing the environment, making it repeatable when you run your unit tests. If you use see all data equals true to annotate that unit test. And expose the contents of your org's data. You're no longer running your tests repeatedly because the data in your org is going to be changing. And that means that the
[18:47] results of your unit tests have this external dependency, that may result in them not being a guarantor of your code's behavior for you. That's why we don't use that annotation. And that that same. That same desire to control the environment guides a lot of the decisions that we make in structuring our unit and integration tests. I see. So we don't want to run the unit test today; it passes, and tomorrow it failed because of the external data it depends on. Right? Exactly. That's the last thing we want to see. Exactly. Okay. Okay. Thanks for explanation. So, so you you asked what makes a good unit test, and you're right.
[19:31] Again, I like to go back to the sort of the core guarantee that we're making—that our code continues to work when the unit test passes, and when our code is not working, we should see a failure in the unit test to advise us of that failure. What makes a good unit test to me is the suite of practices that most contributes to achieving that objective, and. What that breaks down to for me is I'm usually looking for four or five specific cases to be tested in a unit test. the The basic distinction that we that we often talk about is between a positive case and a negative case. A positive case in a unit test is is. The code does what it says it does. It works at some at some fundamental level. You run a unit test where you supply data to your code. That's the kind of data that you expect it to receive in real world usage, and you run the code, and then you validate when the code is finished that the results were as expected. That's a positive test. Now, on Salesforce, because we practice bulkification in most of the kinds of Apex code that we write, we have to run a couple of different kinds of positive tests in in many situations. One would be a single record test, and one would be a multiple record or a bulkified test. Particularly if you're writing something like a trigger or a batch process, it's critical to be able to say both that
[21:01] my trigger will work just fine if a user updates one account in my Salesforce org, but you also need to be able to say if someone does a data load. And pushes up a couple of hundred accounts that my my trigger will still behave correctly and produce the correct results for all of those records. So that's a that's the first couple of cases that I look for in a good unit test. Okay. The other side is one that that sometimes gets neglected, and that's negative or failure cases. In addition to validating that we that our that our code's working correctly, we also want to validate a couple of different aspects for negative paths. One would be what happens when your code receives data other than what it expects, something that doesn't look the way that it should. How does it fail? Does it degrade gracefully and provide clean error reporting, or does it throw an exception? If there's cases where it should throw an exception, we want to validate that that exception really does get thrown and for the right reason, and we want to be able to guarantee the performance of our code if it's passed something like a null parameter. Those are different species of of negative tests. One other, one last thing that I like to test and I like to see. Being run in a unit test is a, I'm not sure what the canonical name for it is. I often call it a no action test or something like that. And what I mean by that is when a when code operates on data based on criteria, like a batch class
[22:32] that runs a query or a trigger that looks for specific field values before it takes action, I want my unit tests to also guarantee that if a record doesn't meet those criteria, it's not being affected. So in my trigger unit tests, I'll often put in as part of my positive case, I'll pass my trigger three records that do match its criteria and one record that does not match its criteria, and I want to be able to validate that that non-matching record doesn't get affected. So that again, my users don't see that aberrant behavior when I go to production. So that's that's five things that I look for in a good unit test. Five promises that I think need to be made as part of that as part of that testing process.
[23:17] Hey, it's she here, your host. I really appreciate you listening to the show. If you enjoy our content, don't forget to go to our website, check the show notes of the episode, which contains the links to the points we just discussed in the show. Those are the things we consider important, but don't have time to cover in the talk. Oh by the way, I do also suggest that you subscribe to our newsletter, where more information is shared constantly. So after listening to this episode, do head out to our website SalesforceWay dot com and find more useful information over there. Now let's get back to the show.
[24:04] Okay, I think these things are good categories for for us to start to, you know, thinking about what scenarios we should touch when we write the unit test. At least one thing you mentioned is this: what is untouched? So the code does remains after the logic is executed. So that's something I rarely do. I think that's definitely something I should bring in in my unit tests. Well, I'll tell you, Xi. The reason why I make a point of testing that is because I have failed that test before, and what I mean by that is I've deployed code or I've come close to deploying code where my criteria weren't being applied correctly, and I was running on data that I shouldn't be touching. So it's a. I try to make that mistake only once. You know, so I've added I've added that to my my list of things that my unit tests need to check before I can go to production. Okay, you mentioned five points, right? I. I think I will forget them after the show. Would you send me over? Then I can put it in the show notes. Sure, sure. Okay, okay. Thanks. I don't know. Do you know this? Also, a podcast show called the Handsome Minutes. It's a a guy who called Scott Hanselman, so he has a lot of experience in the software engineering world. So what he said once is that when he looked back in those old applications he
[25:34] created like ten years ago, the thing he usually regrets is he didn't write good enough unit tests. So that's always something he tries to improve. Now, when he writes a new application, he tries to cover more scenarios in the unit tests to surrounding those blocks, those functionalities in his, in his application, and to try to do more scenarios like you just mentioned. Those five points that really makes your application like more healthy and stronger. So that's what he mentioned. I think it it matches what you just mentioned here as well. I definitely agree. I I think in in that way, unit tests can really be part of the documentation of your code. And one one of the biggest challenges I think for developers coming in and taking over a large and complex code base that they didn't write originally, but if you if you're in that position and you're trying to work on an existing system, having a suite of unit tests available to you that validate but also document how the code behaves and how it's structured is a huge aid to you as you try to continue to build that code. Uh huh. But does that mean usually the the line of unit test code is is longer than the production code? Almost always. That be almost always. Okay. But that's really hard for me and for the junior software engineers
[27:04] because we always thinking okay we need push the production code out fast and then and the unit test usually is much smaller than the production code. It can be really challenging. Yeah. Okay. And I see. I see. And I've I've definitely experienced the same thing that that you're referring to. You know, as a as a developer, you're working with a client or you're working with the business, and you want to deliver for them. You want to deliver for them as fast as possible and give them what they need to do their work. If unit testing is something that slows that process down, you can feel those. You know, you've got you being pulled in two different directions at the same time. For I, I really try hard when I'm. Working with clients or working with business users to to set expectations to include testing. Like when they're when those when those folks are doing their UAT, for example, I am often building the unit tests alongside that process before we go out to production. Because I I know that that both of those sides of the testing process need to happen, or they're going to come back to me in a week and say, Hey David, this tool you gave us is great, but it doesn't work, and I I really don't want to be in that situation. And that was the decision you made, right? Because you know how important the unit test is. It's not the business, or or you go to the business, ask them, should I write better unit test? Because business don't understand what you're talking about, right? So it's the the developers
[28:35] who write the code to decide how to write the good unit test and. Do that. Yeah, I think it's very much on the developers and the development team to to make that part of their process and commit to using testing effectively. Okay, I got that. So, then, since we are in the context of Salesforce, how should we do unit testing Salesforce? Is there some tips from you? Yeah, well, I think we we touched a little bit earlier on the the the inherent difficulties and challenges in Salesforce around dividing out a unit test from a from an integration test. And that some of those difficulties are things like needing to perform DML to persist data. Right. That some people would say that that means you're already not in a unit test because you're touching the database at all. You're not just generating your data in memory. So that's one one place where it's hard to break out a unit by itself. What what I what I find myself usually willing to do is say. There are there are these unique limitations in Salesforce relative to another platform like Python, but I can still write my tests to to make those guarantees about my code, even though. I might not be getting quite the level of unit isolation that I'd expect in a language like Python, and the way that I do that really is is
[30:05] I I think about the code that I'm deploying, and I I need as a developer I need to understand what are the different pathways through that code, some of which are going to be more unitary, and some of which are going to be a little more integrated, and I need to make sure that each of those pathways. Is is validated effectively? So this is this is kind of where I start. I I start writing my code with the tests in mind. I'm not really a TDD practitioner exactly, but I I do write my code with an eye towards how am I going to make this testable? And a a big way that that I end up doing that is trying to keep logic as flat as possible. There's this, there's this metric that I I couldn't really explain to you in any great detail called cyclomatic complexity. PMD will measure it for you if you use static analysis, and it has to do with with how complex the logic is of your code, how deeply it nests. That's one thing. That's one simple thing that you can look out for in your code that helps to ease the testing process. Keep that logic flat. Break out units of logic into separate methods wherever possible. Factor it out so that you have your code broken into more bite-sized chunks that are connected to one another linearly rather than nested. That makes it a lot easier to to test that code. Take an example, right? If you're building a trigger.
[31:36] And you get a pretty simple business requirement where you need to make a small data modification based on some input values. You write a trigger. It's a small trigger. You write a small unit test that just saves an opportunity to the database and then validates that the changes were made as expected. And you put it to production and it's all great. That's good. You keep getting these business requests in over the next six months, and you keep extending that trigger. You're building in more logic, and you get to a position in six months or so where you've got you've got ifs or switch statements that are nested three or four or five levels deep, trying to make sure that you handle all of those different possible situations that could be coming in. Suddenly, you've gotten yourself to a position where it's very, very hard to write a good unit test because your logic is so complex and so deeply nested that designing your data to get to each of those logical pathways is really hard. In fact, it's really hard for you even to look at that code and and figure out how many logical pathways you have in that code. That's where you start to get into a problem, and it's also a situation where it's hard for you to get that code coverage you need because you don't you don't fully understand the complexity of your code pathways. So that that's a place where I like to keep I like to keep testing in my mind as I'm as I'm building up as I'm accreting more logic into those classes. And try to do a little bit of refactoring each step along the way. I'm trying to pull out common elements
[33:07] of my code and factor those into separate methods, and try to flatten my logical tree. Because it's so easy to get yourself into that position where you've got spaghetti code that's really hard to test, really hard to validate. Again, I guess it's a a place again where I'm I like with working with the business. I'm I've got in the back of my mind how do I test this? Similarly, as I'm as I'm building my code and adding on to existing code, I've got in the back of my mind. Am I making my life difficult down the line by establishing a code structure that's very difficult for me to get into with my test code? Because I'm thinking about those levers I can pull on the Salesforce platform to get into that code, to get into those complicated logical paths, and I know that the tools I have available to me that are easy are things like doing DML, creating records that have specific values on them. So I need to build my code to be amenable to being tested with those levers, or else I'm setting myself up for a very difficult position. I see, so let's let's step back a little bit because you what you just mentioned covered a lot of information. I understand. That now, when you create the application, you extend your logic all the time. You are thinking about the design. Was was my code good enough? Was it having too many responsibilities from one single functionality, or should I break it down into
[34:37] smaller pieces so that's easier to test and and easy to read? So that's something at the moment when you write your code, you start to thinking about the design, the object-oriented design, right? And that definitely helped you, as you mentioned, to write the unit test. Because if the function is small and has only single responsibility, the unit test should be also easy to write. And also the other way around, if you cannot really easily write a unit test for your code, it means your design has red flags. That's a really good way to put it. Okay, and also you mentioned a PMD. That's a tool which was one of our our podcast show guests, Robert Sussman, who open sourced before, right? That's a tool can help you automatically to analyze your code to see where they have complex logic in your single functionalities that you might want to break down. PMD is a great tool.
[35:43] And you also mentioned TDD, right? Which is the test driven, uh, was the development? What it was like? Okay, uh, yeah. I also studied the TDD, and I also try to use it in my life, but it doesn't go that easy. Still, especially in the Salesforce world, it since I obviously need to compile in the cloud and it slows down a little bit. It just doesn't flow that naturally in my way. So, what what's your experience about TDD? Yeah, I'm not a big TDD practitioner, especially on Salesforce, largely because of the reasons that you mentioned the the feedback loop. On the Salesforce platform is not as fast as when you're working locally in an interpreted language like Python or something with really fast compilation like Go. Right, you can get your test results almost instantaneously. Salesforce has definitely gotten better in terms of of responsiveness and the developer tooling has gotten a lot better over the last couple of years, but it's it's still a little slower. I don't always like to commit to that kind of stricture around how I do development. I tend to move back and forth between my unit tests and my and my production code pretty fluidly, rather than being strict about saying I want to write my tests first and then develop to that spec. I flip back and forth between the two pretty frequently. And that's just what works for me. Different
[37:13] developers, you know, pursue different methodologies. But I think the the end goal is really the critical piece is are are you able using whatever methodology works for you to deliver good code and to deliver code that is testable and that is effectively validated, right? Excellent. All right, thank you, David. I think this is an excellent point that we round out in this session. So thank you, David, for joining the show. Thank you very much for having me, Xi. It was a real pleasure.
[37:48] Hi, I'd like to thank you very much as you have reached the end of the show. If you find our content useful, please let me know and connect with me. If you are using Twitter, don't forget to let me know the number one point you have learned in this episode. All the information about the show, about me, the RSS, the iTunes, my Twitter, the newsletter, and the other episodes can be all found at our website SalesforceWay.com. So thank you again, and see you next time.