Structural (White Box) Testing - aapowers/BroadleafCommerce GitHub Wiki
Structural testing, also known as white box testing, glass box testing, or code-based testing, refers to a method of testing where we look not just at the requirements, but also at the code that was written to satisfy the requirements.
While functional testing allowed us to cover aspects of the written requirements for the application, structural testing lets us improve our tests further by covering aspects of the implementation as well.
Our functional tests might not end up running every line of code, which means that there might be a fault in the code that cannot be exposed by our functional tests. However, with structural testing, we can ensure that our tests run every line of code (or every node or edge in a control flow graph).
It is important that we do both functional testing and structural testing on our application. Structural testing can find faults that are never executed with functional testing alone, and functional testing can find unimplemented requirements that are not found by structural testing alone.
Code coverge, which represents the percentage of code that the tests cover, can be measured different ways. It can be measured by statement, the number of statements executed divided by the total number of statements in the code, or it can be by branch, method, or class.
While 100% coverage can be unattainable for various reasons, measuring code coverage allows us to see our current coverage, set a goal for the coverage that we want to reach, and write tests until we reach that goal.
To understand the unit of measurement in each column and how JaCoCo calculates it, please see the JaCoCo Documentation.
From looking at the coverage, it is clear that while many developers use line coverage for their measurement, focusing on instruction or branch coverage could result in more thorough testing. The current line coverage for the profile core service is 21%, whereas the more detailed instruction coverage is 9% and branch coverage is 11%.
Certain classes, like the CustomerServiceImpl class, are not covered at all by the existing testing suite. Some of the methods in the CustomerServiceImpl class handle critical features, such as resetting a customer's password, so it is important that we add tests for these features.
I wrote unit tests for the following classes and functionality:
AddressServiceImpl
- creating, deleting, copying, saving, reading, and verifying addresses
ChallengeQuestionServiceImpl
- reading challenge questions
CountryServiceImplTest
- saving and finding countries
CountrySubdivisionServiceImpl
- saving and finding subdivisions
CustomerAddressServiceImpl
- creating, deleting, saving, finding, and reading customer addresses
- updating default customer addresses
CustomerPaymentServiceImpl
- creating, deleting, saving, finding, and reading customer payments
- updating default customer payments and statuses
CustomerPhoneServiceImpl
- creating, deleting, saving, finding, and reading customer phones
- updating default customer phones
CustomerServiceImpl
- creating, deleting, saving, reading, and registering customers
- generating secure passwords
- changing and resetting a password for a customer
- verifying validity of a password, a password reset, and a customer
- getting and setting necessary elements
CustomerUserDetails
- initializing and updating a customer's user details ID
PhoneServiceImpl
- creating, saving, copying, and reading a phone
RoleServiceImpl
- finding roles for a customer
This is the new coverage after writing unit tests in the Profile Core Services module.
We have increased the instruction coverage from 9% to 70%, branch coverage from 11% to 52% and line coverage from 21% to 72%, covering a total of 276 additional lines of code.
The tests were all added under the core/broadleaf-profile/src/test/java/org/broadleafcommerce/profile/core/service/
directory and can be found on GitHub.