Automated Functional Testing: A Step-by-Step Guide
This article will introduce functional testing and automation to test a web-based application.
Join the DZone community and get the full member experience.
Join For FreeEvery application (desktop, web, or mobile) needs to be tested before releasing to the market. Functional testing is considered the most important type of testing because, first of all, an application must do WHAT it is required to do.
Functional testing verifies that each software function operates in conformance with the requirements specifications. If an application doesn’t meet its functional requirements, it might not survive for long.
This type of testing is a critical and costly activity in the lifecycle of any application. For this reason, functional testing automation represents an effective solution to improve software quality and reduce testing costs.
This work will introduce functional testing and automation to test a web-based application. I will explore how to design functional test cases and automate them using a well known testing tool.
What is Functional Testing?
Functional testing is a type of testing in which the software is tested against its functional requirements specifications to find failures. Functional testing allows finding "discrepancies" between the software and its specification. Moreover, it verifies that all functions behave according to their requirements. In simple terms, functional testing ensures your software is working as expected (it does what it is supposed to do!).
Functional testing uses black-box techniques in which the test cases are derived solely from the specifications, and testers don't know the internal software logic and details (fig.1).
This type of testing is done by:
1. Providing test inputs to the system under test
2. Capturing resulting outputs from the system under test
3. Verifying that the actual outputs are equal (==) to the expected ones derived from the specification
Functional testing includes several testing types, such as (fig.2):
- Unit
- Smoke
- Sanity
- Integration
- System
- Regression tests
- And more
Here I will focus on system testing.
System testing is a functional testing method that tests the complete and fully integrated application functionality (testing the whole system).
Automated Functional Testing
It is possible to execute functional (system) testing manually or automatically.
Manual testing is when a tester performs functional testing by directly interacting with the application.
Automated testing is when a tester uses an automation tool like Maveryx to test the software's functionality. It can be achieved programmatically, in script-based automation, or without coding in no-code automation (e.g., keyword-driven approach).
Scripted testing means writing test scripts in a programming language such as Java, C#, and Python. Hence, good programming knowledge becomes a necessity in this case, but it takes almost all benefits of coding.
No-code testing does not require programming knowledge as the construction of the test scripts is done by choosing test actions, for example, from dropdown menus, or visually through drag-and-drop of test components.
The Example
A fundamental feature of many web applications is the login function.
In this article, I will test the login system of the OrangeHRM demo software at https://opensource-demo.orangehrmlive.com/.
I can summarize the specification as follows:
- A user can access the OrangeHRM demo system from the login page using the username and password credentials indicated on the login screen (fig. 3).
- When the user enters a valid username and password and clicks the Login button, the user logs in to the application and gets access to the Dashboard (fig. 4).
- When the user enters an invalid name and/or password and clicks the Login button, the system displays an error message: "Invalid credentials" (fig. 5).
- If either username or password is left blank, clicking the Login button, the system displays an error message: "Username cannot be empty" or "Password cannot be empty" (fig. 6).
Designing the following functional test cases is possible, starting from the presented specification.
Test Case Name |
Test Case Description |
Expected Output |
TC_001 |
Enter a valid Username and valid Password, then click the Login button.
|
The user logs into the application and reaches the Dashboard page at https://opensource-demo.orangehrmlive.com/index.php/dashboard |
TC_002 |
Enter an invalid Username and valid Password, then click the Login button.
|
Error: "Invalid credentials." The user remains on the login page at https://opensource-demo.orangehrmlive.com/index.php/auth/validateCredentials |
TC_003 |
Enter a valid Username and invalid Password, then click the Login button.
|
Error: "Invalid credentials." The user remains on the login page at https://opensource-demo.orangehrmlive.com/index.php/auth/validateCredentials
|
TC_004 |
Enter an invalid Username and invalid Password, then click the Login button.
|
Error: "Invalid credentials." The user remains on the login page at https://opensource-demo.orangehrmlive.com/index.php/auth/validateCredentials |
TC_005 |
Leave a blank Username and blank Password, then click the Login button.
|
Error: "Username cannot be empty." The user remains on the login page at https://opensource-demo.orangehrmlive.com/ |
TC_006 |
Leave a blank Username and enter a valid Password, then click the Login button.
|
Error: "Username cannot be empty." The user remains on the login page at https://opensource-demo.orangehrmlive.com/ |
TC_007 |
Enter a valid Username and leave a blank Password, then click the Login button.
|
Error: "Password cannot be empty." The user remains on the login page at https://opensource-demo.orangehrmlive.com/ |
Let’s consider the first test case (TC_001). In more detail, it will result in the following steps:
Test Step (/input) |
Expected Output |
|
|
|
The OrangeHRM demo website opens at the URL https://opensource-demo.orangehrmlive.com/
|
|
The username field is filled with the value "Admin." |
|
The password field is filled |
|
The Dashboard page is displayed at https://opensource-demo.orangehrmlive.com/index.php/dashboard |
Automate Functional Test Scripts
It's possible to execute this test case manually ("as is") or automatically.
To automate it, I will use Maveryx and Java.
Maveryx is automated functional and regression testing tool. This software provides automated testing capabilities for functional, regression, UI, codeless and data-driven testing. It supports a range of applications, including web-based, .Net, Java, and so on.
Java does not require a great deal of introduction.
Here is a step-by-step guide to implementing the test case TC_001. The code is well commented on to understand what each line does.
1. Start the browser.//launch Chrome browser
Bootstrap.startApplication(chrome);
//new browser instance
GuiBrowser browser = new GuiBrowser();
2. Navigate to the OrangeHRM demo website. The OrangeHRM demo website is opened at this URL: https://opensource-demo.orangehrmlive.com/.
//OrangeHRM demo website page URL
String pageURL = "https://opensource-demo.orangehrmlive.com/";
//navigate to the OrangeHRM demo website
browser.navigateTo(pageURL);
//check the landing page URL
assertEquals(pageURL, browser.getCurrentPageUrl());
I recommend using assertions to validate the results against the expected ones (fig. 7). Assertions compare the expected results to the actual results. If they match, the test case passes. If not, then the test case fails.
3. Enter valid Username = "Admin" -> the username field is filled with the value "Admin".
//the username
String username = "Admin";
//the Username text field
GuiText usrName = new GuiText("Username");
//set the username
usrName.setText(username);
//check that the username has been correctly inserted
assertEquals(username, usrName.getText());
Unlike Selenium, Maveryx does not use "Locators" (including XPath) to identify the elements that the test script will interact with to replicate the user actions.
Using Maveryx, you can describe the UI elements to test as they appear in the application. In my example, I used the username text field placeholder "Username" to identify the object (fig. 8).
The test objects are identified directly at runtime, without using any pre-recorded UI Maps (or Test Objects/Images Repository).
4. Enter a valid Password = "admin123" -> the password field is filled.
//the password
String pwd = "admin123";
//the Passoword text field
GuiPasswordText password = new GuiPasswordText("Password");
//set the password
password.setText(pwd);
//check that the password has been correctly inserted
assertEquals(pwd, password.getText());
The password text field is identified by its placeholder "Password" (fig. 9).
5. Click The Login button -> (the user is logged in) the Dashboard page loads at https://opensource-demo.orangehrmlive.com/index.php/dashboard.
//click The Login button
new GuiButton("LOGIN").click();
//check that the header "Dashboard" is present (fig.10)
new GuiHtmlElement("Dashboard", AccessibleRoleMaveryx.WEB_H1).waitForObject(5, 1);
//the Dashboard page URL
String dashboardURL = "https://opensource-demo.orangehrmlive.com/index.php/dashboard";
//check the Dashboard page URL
assertEquals(dashboardURL, new GuiBrowser().getCurrentPageUrl());
The test script is now ready to be executed.
Maveryx will launch the Chrome browser and open the OrangeHRM login page on executing the code. Then, it will log in using the relevant credentials. It will also check the expected and actual outcomes through assertions.
Similarly, the test case #2 (TC_002) will result in a Maveryx test script like this:
//invalid username
String username = "Admi";
//the Username text field
GuiText usrName = new GuiText("Username");
//set the invalid username
usrName.setText(username);
//check that the username has been correctly inserted
assertEquals(username, usrName.getText());
//the password (valid)
String pwd = "admin123";
//the Passoword text field
GuiPasswordText password = new GuiPasswordText("Password");
//set the password
password.setText(pwd);
//check that the password has been correctly inserted
assertEquals(pwd, password.getText());
//click The Login button
new GuiButton("LOGIN").click();
//check that the message "Invalid credentials" is present (fig.5)
new GuiHtmlElement("Invalid credentials").waitForObject(5, 1);
The same approach applies to all other test cases.
Conclusion
Functional testing is probably the most important, known, and practiced form of testing in the software world. It is also the type of testing that catches most of the defects.
In this article, I explored various aspects of functional testing, focusing on how to create functional test cases from specifications and how to automate them, with a practical example.
Opinions expressed by DZone contributors are their own.
Comments