Comparing unit testing and integration testing

Much of the difference between unit and integration testing relates to the scope of the code being tested and the goals of the test. Chances are you have been mixing a combination of the two on the Lightning Platform without realizing it. Before we go deeper into these differences, let's consider some characteristics of integration testing:

  • Integration tests test your key application features and related code paths under different scenarios, which can span multiple classes, including frontend code. Thus, the term "integration" refers to all code executing end to end together for a given set of inputs (including database rows) to assert a given output at the end.
  • This type of testing occurs after unit testing, but also eventually forms a key part of what is sometimes referred to as your regression (or system) test suite.
  • Regression tests are simply a type of integration test that can be even more broad, involving several modules representing key end-to-end critical scenarios in your application, which, if failed, would cause business standstill for your customers. You should regularly review and update regression test coverage as features are added.

For Apex code, most of the published guidance on writing Apex tests falls into this integration testing category. Indeed, the only way to cover Apex Trigger code is to physically write to the database. There is also the need to test declarative aspects of your solution (a unit test only tests code) and how they affect broader application processes. In respect of your application's user experience, you may also have been using tools such as Selenium (https://www.seleniumhq.org/) or Puppeteer (https://dev.to/endtest/puppeteer-vs-selenium-1938).

When I think about the preceding description, it described the Apex tests I had been writing before discovering how to write true unit tests on this platform (more on this in the Introducing unit testing section later). Visually, my tests used to look like the following:

Historically, I would write Apex test code to set up my records or execute my controller code or service layer code (to test the API). This code would update or query the database accordingly. Then, I would write test code to query the result records to ascertain that the behavior was what I was expecting. This approach, as per the preceding diagram, would ensure that all the classes involved in the functionality, such as Service, Domain, Unit Of Work, and Selector, got executed. It also ensured that they did just what they needed to in the scenario I was testing to result in the overall goal of completing the end user or API process being tested. Essentially, I had been writing integration tests and that, of course, is better than nothing!

Integration tests are still necessary to test your key processes, and, in the case of Apex, to obtain code coverage on the Apex Triggers required to package your solution. However, regardless of its Apex code or your user experience code, integration tests do have some downsides:

  • Execution time: Since each test method needs to set up, update, and query the database executing it, all or individual test methods can start to take increasingly longer to execute, slowing the developer's productivity.
  • Scenario coverage: Introducing more varied scenarios can become less practical due to the preceding performance concern. This discourages developers from doing thorough testing (we hate waiting!). This, in turn, reduces code coverage and the value of the tests. And this ultimately increases the risk of bugs being left undiscovered by the developer.
  • Code coverage challenges: Obtaining 100% code coverage is the desirable goal, but it can be impossible to achieve in certain scenarios. For example, error handling for some system events cannot be emulated in an integration test.
  • Ensuring future-proofing and reliability for other developers: Methodologies such as Scrum teach us to write code incrementally and just in time for market needs. However, developers are often aware of future needs and wish to build frameworks, engines, or libraries to support both current and future needs. It may not be possible to write integration tests that ensure that, when that time comes, such code is robust and reliable for other developers.

As client development is now more component-driven, when considering testing the user experience directly through browser automation tools such as Selenium, the preceding considerations are equally valid. This means that it is also important to think about integration versus unit testing at the client tier, specifically, unit testing Lightning Web Components.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.14.245