API Testing: Best Practices
This comprehensive guide to API testing touches on aspects like getting started, functional testing, and mapping and execution.
Join the DZone community and get the full member experience.Join For Free
In 2002, software bugs cost the United States economy approximately $59.5 billion. In 2016, that number jumped to $1.1 trillion.
The longer a software bug exists throughout the product life-cycle, the more it costs. If the bug is caught during the development process, it costs next to nothing to get it fixed as part of the implementation.
When a bug is discovered in a finished version of the product before the release, the cost grows, as locating the source and finding a solution in a now "finished" code may be more complicated. A bug is found post-release, likely due to surging in costs, either due to SLA violation penalties, possible complicated patches onto a released product, or even the loss of potential customers assessing several products serving the same purpose.
The Fastest Tests to Integrate Into Online Product Development Processes Are API Tests
The advantage of API testing is the speed with which they can provide a picture of the product status in the development process. They also give the developer the ability to perform self-tests at a low cost, eg: for younger startups that can't devote a large number of resources (time/people) to create wider coverage.
API testing can also help you find breaches that would most likely be missed in any other sort of tests because you can quickly flood your server with parameterized requests. It's not just that you can flood the server, but you can also perform actions that aren't exposed in the UI (even if your backend supports it.) Once you have an API, your users may have access to it, which can open you up to security breaches. It allows you to test your software beyond its usual UI capabilities.
In order to successfully run API tests, it is recommended to uphold the same principles for testing as you would do for any software development.
Here Are 4 of the Best Practices That Make Your Testing Process Quicker, Smoother, and More Collaborative
1. DRY (Don't Repeat Yourself)
Create a client for your SUT (System Under Test) before adding tests.
You want to avoid repeating your code, but many tests require you to address the same components or similar actions. In these cases, you can create a common library to wrap your test requests and make the usage shorter and the process simpler.
Write clear tests that easily enable debugging.
When tests are running successfully, they require no attention or time. When they start failing, resources need to be allocated to find the cause of failure. This process may be very time consuming during the product development and go as far as pushing deadlines or cutting new features from your product.
Why might your tests fail?
- Flawed automated test
- Unstable test (race condition in the test)
- Environment failure or limitation
- Changes to the product without changes to test
- Flawed functionality
- Unstable functionality (race condition in the product)
In order to save resources and optimize the process, debugging should be made a priority when you are creating the test.
- Each SUT component should be tested separately for each possible configuration.
- The failure clause of the test should be clear and shown in the report.
- All the additional information (descriptors, ids etc..) should be included in the report.
- If possible — the results of the failure should be saved and accessible in the system so that data can be tracked back.
3. Mapping and Execution
Design the tests to run under different SUT configuration options.
This test should be designed so that you are not limited by the system. They should be configurable to run in any of your working environments under different configurations and provide a clear picture for each of them with a split report.
The more flexible the tests are, the less effort is required when they are version split based on different customer requests or when there is a major change in the product behavior under different configurations/conditions.
4. Prerequisites and Cleanup
To focus on the components currently under test, split the test into three sections:
Setup creates all the conditions and resources required for testing the component under test. Failures in setup should not indicate the test as failed but as "Not Executed" because that means that the failure we encountered is in a different component and not the component currently under test.
Execute the test that uses/relies on the prepared components, and verifies/asserts that the outcome matches the expected result.
Teardown is the post-test stage in which we delete or reset system resources that were created or modified as part of the test. The exception to this is data that may be required for the debugging process in case of a test failure.
A pytest framework example of setup and teardown using a yield fixture
Getting Started With API Testing
There are 4 key stages for successfully getting started with API testing.
1. Mapping the System Into Representative Components
Before you start writing tests, you need to get a clear picture of what different test suites you will need and how are they are going to look. In order to do that, you need to understand your system from a holistic view so you can break it into concrete components, which you can start planning tests for.
2. Choosing the Test Type and Parameters for Each SUT
Once we have a clear picture of the system components and the integration between them, we can plan the tests in a way that cover all the possible iterations and usages of those components. This is where the different types of functional testing come into the picture.
3. Combining the Results From Each SUT Into One Big Picture
At the end of the testing cycle, we want to be able to have a clear picture of what works, what doesn't work, when it stopped working, and ideally, why it didn't work.
4. Continuous Testing
Once the tests and reporting mechanisms are in place, the next stage is to create a continuous process that runs alongside the product development and provides a look into the product status at minimal cost.
This should provide the tools for testing existing features as well as new ones, and in case something does not function properly, provide alerts during the development stages when the cost of fixing it is lowest.
Published at DZone with permission of Naomi Goldberg. See the original article here.
Opinions expressed by DZone contributors are their own.