Joomla Testing
What is Joomla?
Joomla is a popular open-source content management system (CMS) for creating and managing websites and online applications. It is written in PHP and uses MySQL or PostgreSQL as its database management system. Joomla allows users to create and manage websites with little to no technical knowledge, thanks to its user-friendly interface, rich set of features, and extensive library of templates and extensions.
Joomla Unit Testing
Unit tests are designed to check various functions, methods, and classes in isolation. This preliminary testing is crucial in complex Content Management System (CMS) platforms like Joomla. Although the focus is strictly on obtaining the correct output from the code unit, it is an excellent way to determine whether any breaking changes have been introduced into the system. As the emphasis is on isolated and lightweight testing, unit tests often employ mocking to minimize external dependencies.
Joomla uses the PHPUnit framework for unit testing. Here is an example of a test case for a JArrayHelper class in Joomla. The goal of this test is to verify that the getColumn method of the JArrayHelper class returns the correct data. The test case extends the PHPUnit\Framework\TestCase class, which provides methods for setting up and tearing down test fixtures. In this case, the setUp and tearDown methods are left empty.
The test case includes one test method named testGetColumn(). This method creates an array of arrays called $test_array, where each sub-array represents a row of data with values for three columns: 'sport', 'teams', and 'country'. The test method then calls the getColumn method of the JArrayHelper class and passes in the $test_array and the name of the column ('country') to retrieve. The result is stored in $result_array.
Finally, the test method uses the PHPUnit assertion method assertEquals() to compare the $result_array with an expected array of values for the 'country' column. If the two arrays are equal, the test passes. If not, the test fails with an error message.
require_once JPATH_BASE.'/libraries/joomla/utilities/arrayhelper.php'; class JArrayHelperTest extends PHPUnit\Framework\TestCase { /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. * * @access protected */ protected function setUp(): void { } /** * Tears down the fixture, for example, closes a network connection. * This method is called after a test is executed. * * @access protected */ protected function tearDown(): void { } /** * Simple Test for getColumn method. */ public function testGetColumn(): void { $test_array = [ [ 'sport' => 'football', 'teams' => '10', 'country' => 'United States' ], [ 'sport' => 'badminton', 'teams' => '8', 'country' => 'Germany' ], [ 'sport' => 'basketball', 'teams' => '12', 'country' => 'Canada' ] ]; $result_array = JArrayHelper::getColumn($test_array, 'country'); $this->assertEquals( ['United States', 'Germany', 'Canada'], $result_array, 'We did not get the proper column data back' ); } }
Joomla is also compatible with Codeception which uses PHPUnit under the hood.The syntax is quite similar to PHPUnit. However, Codeception offers some helpful utilities to make testing more straightforward. You can install Codeception in your project using Composer.
namespace Tests\Unit; use Tests\Support\UnitTester; use App\User; class UserTest extends \Codeception\Test\Unit { /** * @var UnitTester */ protected $tester; public function testValidation(): void { $user = new User(); $user->setName(null); $this->assertFalse($user->validate(['username'])); $user->setName('toolooooongnaaaaaaameeee'); $this->assertFalse($user->validate(['username'])); $user->setName('davert'); $this->assertTrue($user->validate(['username'])); } }
The example demonstrates a simple test case for validating a user's username using the User class. The test case checks if the username is valid in three different scenarios: when it's null, when it's too long, and when it's an acceptable length.
You can find in-depth documentation on how to write and run these test cases here.
Joomla Integration Testing
Integration testing is the process of evaluating how different components of a system work together. This is applicable to APIs, forms, and database interactions. Some examples include integration with a third-party system or an API. Let’s take a look at some more scenarios that are specific to applications built using Joomla and where integration testing will come in handy.
- When a Joomla site uses third-party extensions like plugins, modules, or components, it's important to ensure that these extensions work well together and do not conflict with each other.
- Joomla has a powerful access control list system that allows administrators to set granular permissions for different user groups. Integration testing can help ensure that these settings work as intended and that users can access only the content they are authorized to view.
- Joomla sites often use different templates for different pages or sections of the site. Integration testing can help ensure that templates work well with other extensions, and that content is displayed correctly across all templates.
- Joomla has a caching system that can help speed up page load times. Integration testing can ensure that caching works correctly and that cached content is refreshed when necessary.
- Joomla has a multi-language feature that allows sites to be translated into different languages. Integration testing can ensure that all content is correctly translated and that language settings do not conflict with other extensions.
- Some Joomla sites use custom code or scripts to add functionality or integrate with other systems. Integration testing can help ensure that custom code works well with other extensions and does not introduce bugs or conflicts.
- Joomla sites often integrate with third-party services like payment gateways, social media platforms, or analytics tools. Integration testing can ensure that these integrations work as intended and that data is properly transmitted and processed.
Integration testing can be performed using automated testing tools, such as Codeception or PHPUnit, or through manual testing. The choice of testing method depends on the complexity of the application, the level of interaction between components, and the resources available for testing.
Joomla End-to-End Testing
End-to-end testing is a comprehensive approach that evaluates an entire system or application from the user's perspective to ensure that it functions as expected. In the context of Joomla applications, end-to-end testing involves testing the complete functionality of the website or application, including the frontend, backend, and all the integrated components, to confirm that they work together seamlessly and meet the desired requirements.
The primary goal of end-to-end testing is to simulate real-world user scenarios and validate that the system behaves correctly under various conditions. This testing type can help uncover issues that might not be detected during unit or integration testing, such as problems with user interfaces, workflows, data handling, or system configurations.
- Testing the user interface (UI) and user experience (UX) to ensure that the site is easy to navigate, responsive, and visually appealing across different devices and browsers.
- Verifying that the frontend and backend components of the application interact properly, including forms, user authentication, content management, and data processing.
- Checking the functionality of any custom or third-party extensions, modules, and plugins, and ensuring that they integrate seamlessly with the Joomla application.
- Assessing the performance, security, and reliability of the application, including load times, data protection, and error handling.
- Selenium with PHPUnit
- Codeception
- testRigor
Using Selenium
Joomla offers support for performing system testing using Selenium. When writing these test cases, you need to think from the user's perspective. Joomla supports using Selenium IDE to record tests which can be converted into PHP code.
PHPUnit also has an extension called Selenium2TestCase which allows QA to write functional tests for web applications using the Selenium WebDriver API. It provides a set of methods for interacting with web pages and simulating user actions. When using PHPUnit_Extensions_Selenium2TestCase, you can define tests that launch a web browser, navigate to a page, and interact with it to test various aspects of the page's behavior. For example, you can test whether certain elements are present on the page, whether form submissions result in the expected behavior, and whether specific interactions trigger expected changes to the page. Unlike the older versions, the latest versions of PHPUnit do not document this class; it is still widely used for automated testing.
The main downside is that this method is not as versatile and does not cover many common use cases that are likely to occur in CMS websites.
Using Codeception
You can use Codeception to write end-to-end tests for your application. This tool also supports the BDD approach for testing. Codeception's BDD support is based on the Gherkin language, which is used to describe the behavior of a system in a structured, human-readable way. Gherkin uses a set of keywords, such as Given, When, Then, And, and But, to describe the steps of a scenario.
Codeception's BDD support allows developers to write Gherkin feature files that describe the system's behavior, and then generate PHP code based on those feature files that can be executed as tests. Let's take a look at the below example.
First, a story is defined using the Gherkin language. Here's an example:
- In order to buy products
- As a customer
- I want to be able to purchase several products at the same time
-
Scenario:
- Given I have a product with a $600 price in my cart And I have a product with a $1000 price When I go to checkout process Then I should see that total number of products is 2 And my order amount is $1600
<?php namespace Step\Acceptance; use AcceptanceTester; class CheckoutProcessSteps extends AcceptanceTester { /** * @Given I have a product with a :price price in my cart */ public function iHaveAProductWithAPriceInMyCart($price) { $I = $this; $I->amOnPage('/product_page_url'); $I->fillField('price', $price); $I->click('Add to cart'); } /** * @And I have a product with :price price */ public function iHaveAProductWithPrice($price) { $I = $this; $I->amOnPage('/product_page_url'); $I->fillField('price', $price); $I->click('Add to cart'); } /** * @When I go to checkout process */ public function iGoToCheckoutProcess() { $I = $this; $I->amOnPage('/checkout'); } /** * @Then I should see that total number of products is :numProducts */ public function iShouldSeeThatTotalNumberOfProductsIs($numProducts) { $I = $this; $I->seeNumberOfElements('.product', $numProducts); } /** * @And my order amount is :orderAmount */ public function myOrderAmountIs($orderAmount) { $I = $this; $I->see($orderAmount, '.order-total'); } }
This step definition file defines a class called CheckoutProcessSteps that extends the AcceptanceTester class, which provides methods for interacting with the application. The methods in this class correspond to the steps in the Gherkin feature file and use Codeception's built-in methods to navigate through the application and perform the necessary actions.
<?php use Step\Acceptance\CheckoutProcessSteps; class CheckoutProcessCest { public function checkoutProcessTest(CheckoutProcessSteps $I) { $I->iHaveAProductWithAPriceInMyCart(600); $I->iHaveAProductWithPrice(1000); $I->iGoToCheckoutProcess(); $I->iShouldSeeThatTotalNumberOfProductsIs(2); $I->myOrderAmountIs(1600); } }
Using testRigor
The primary advantages of testRigor include its simplicity, ease of maintenance, and scalability. Often, the end user's perspective on interacting with a system, which is crucial for creating end-to-end test cases, comes from non-technical individuals such as product owners, experienced manual testers, business analysts, or client-facing teams. However, if test cases must be coded, this perspective may not be accurately translated due to limited engagement from a diverse audience. testRigor addresses this issue by enabling test cases to be written in plain English, facilitating easy collaboration, review, and editing of test scenarios. Additionally, testRigor supports Behavior-Driven Development (BDD) right out of the box - also without the need for coding.
With its stability, low test maintenance, and straightforward test case creation, testRigor is well-equipped to ensure the quality of your website. Content Management Systems (CMSs) often require testing use cases that involve sending emails or SMS alerts, which testRigor can accommodate. As a cloud-based application, testRigor allows users to begin automating without the need to install and configure software, unlike many other automation tools. The tool supports cross-platform testing across web, mobile, and desktop environments, covering a wide range of testing needs. You can explore more benefits of using testRigor here.
Below is the same test case as above. Notice how clean and concise it is. There are no step definitions or test files needed. This can give you an idea of how manual testers are able to author tests up to 15x faster with testRigor, compared to other tools.
login click on "Cart" grab value from "Item 1 price" and save it as "Price 1" grab value from "Item 2 price" and save it as "Price 2" click on "Check Out" check that page contains "2" to the right of "Total number of items" check that page contains expression "$(Price 1) + $(Price 2)" below "Total Amount"
Conclusion
In conclusion, testing is an essential aspect of developing and maintaining high-quality Joomla applications. By incorporating various testing approaches, such as unit, integration, and end-to-end testing, you can ensure that your applications function correctly and meet the desired requirements. Utilizing tools like PHPUnit, Codeception, and testRigor, you can create comprehensive test suites, collaborate effectively, and reduce the time spent on manual testing. Embracing these testing practices not only leads to a more reliable and efficient development process but also guarantees a better user experience for the audience, ultimately contributing to the project's success.