Tests check that the code does what it is expected to do. It also gives confidence to the software engineer that the code works as intended. This equates to less or no bugs in the software. You must have heard about lots of types of automated software tests. There is unit testing, integration testing, functional testing, acceptance testing, smoke testing etc. As per Guru99’s post there are more than 100 types of software testing. In this post, I am going to categorize automated software tests into two, the fast ones and not fast ones.
How do you distinguish between slow and fast tests?
Generally, if your whole tests suite runs in seconds it is fast. If your whole test suite runs in minutes/hour it is slow. To make your tests small you need to make your application small. As faster tests running on your Continuous Integration (CI) service will give you faster feedback. Maybe it is time to go micro-services?
Let's discuss the more about fast and not fast (slow) automated software tests.
The fast tests
Fast tests are code that tests one unit of code generally a method. A unit test is a type of fast test. They don’t depend on any external dependencies. External dependencies include a file system, database, web server, network or any third party API or service. Unit tests even mock the other code elements they need like other classes and its methods. This makes the test focused on one unit and they run in milliseconds/seconds not minutes. A simple example is below:
<?php
namespace DataProvider\Example\Test;
use DataProvider\Example\Checkout;
use PHPUnit_Framework_TestCase;
/**
* Checkout test for Cash and Credit card.
*/
class CheckoutTest extends PHPUnit_Framework_TestCase
{
/**
* @var Checkout
*/
protected $checkout;
public function setup()
{
$this->checkout = new Checkout();
}
/**
* Data provider for testCalculateTotal
* variables are in the order of
* $paymentMethod, $expectedTotal.
*
* @return type
*/
public function paymentMethodProvider()
{
return [
['Cash', 100.00],
['Credit Card', 95.00],
];
}
/**
* Test to check if the order total is calculated correctly
* for given payment method.
*
* @param string $paymentMethod
* @param float $expectedTotal
*
* @dataProvider paymentMethodProvider
*/
public function testCalculateTotal($paymentMethod, $expectedTotal)
{
$this->checkout->calculateTotal($paymentMethod);
$this->assertEquals(
$this->checkout->getTotal(),
$expectedTotal,
sprintf('Testing total calculation for %s.', $paymentMethod)
);
}
}
You can view the full code here, yes it is a simple class with no code or external dependency.
Some integration tests can also be fast tests. These integration tests can test many classes. They should not depend on any external dependencies mentioned above to obtain speed. So these tests will still run in seconds and not take minutes to finish.
The not fast tests (slow ones)
Any test that takes longer to run is not fast tests (slow tests). Generally, these type of tests needs to load the whole application to test it. These types of tests depend on external dependencies. External dependencies include a file system, database, web server, network, third-party API or service.
Acceptance tests that need to load a full web application on a browser is a type of slow tests. Even smoke tests if it needs to load the whole application and takes a long time to execute fall in this category.
@checkout
Feature: Checkout with offline payment
In order to pay with cash or by external means
As a Customer
I want to be able to complete checkout process without paying
Background:
Given the store operates on a single channel in "France"
And the store has a product "PHP T-Shirt" priced at "$19.99"
And the store ships everywhere for free
And the store allows paying offline
@ui
Scenario: Successfully placing an order
Given I am logged in customer
And I have product "PHP T-Shirt" in the cart
When I proceed selecting "Offline" payment method
And I confirm my order
Then I should see the thank you page
The above example is taken from Sylius project, to test checkout with an offline payment method on the browser.
Conclusion
Testing is super important for a robust software application. Automated testing + CI is one of the four pillars of any solid software application. Happy testing, hope your tests run in seconds not minutes.
Originally published at geshan.com.np.
Top comments (8)
It seems Rust has better compile and need less tests. Right?
Don't fall in the trap that a strongly typed language doesn't need tests. Yes, you won't write tests for types but you still need to verify that your function does what it's supposed to do and that your app does as well.
I said less, :)
ahhahaha sorry :D
A well-designed type system can replace micro-scale "fast tests" that are basically intended to check that a unit work correctly on all of the data types that it's specified to work on.
The slow tests, that run the entire application, aren't affected. Look at the incredible amount of test cases that the Rust compiler and Servo have that don't even use the normal unit testing framework, because they want to be able to launch the entire user interface and check its inputs and outputs (or, in Servo's case, because the test harness is supposed to work with software that isn't even written in Rust). In my (admittedly limited) experience, those are the tests that eat most of your time, because they end up hitting race conditions and bugs in the test code itself, even if you write less of them and more of the decent unit tests. But they do catch actual bugs that unit tests wouldn't catch.
No idea, never tried Rust.
Geshan, thank you for the article. I am a lover of tests as well (and esp. enjoy the PHP code :)). Thank you as well for the Guru99 link.
Thanks for the comment.