Software testing is an important activity in software development that is performed to make sure that the software works as expected and meets the specifications and requirements. Testing helps to reduce the number of bugs in the software and ensure high reliability and quality. In our project, we try to apply as many and different tests as possible. We have successfully implemented Unit tests, Load tests, Manual tests, Mobile application tests and automated testing.
In this article we will tell more about the whole process of automated testing.
Automated testing is a process where we use software tools to run tests using software product instead of running them manually. This allows us to speed up the testing process, increase its efficiency and ensure repeatability of results. Our tests are written entirely in C# using Selenium, NUnit and SpecFlow.
Using SpecFlow, we have the ability to use Behavior Driven Development (BDD) methodology, which focuses on communication between developers, testers, and customers using specifications that are expressed in human language to describe the behavior of the system. Gherkin syntax is used to define specifications. Here is an example of a scenario that successfully logs into the system and one that fails to log in:
Feature: User Login
 In order to use the web application
 As a user
 I want to be able to log in with valid username and password
Â
Scenario: Login with valid credentials
   Given the user is on the home page of the web application
   When the user enters valid username "john_doe" and password "password123"
   And the user clicks on the login button
   Then the user should be redirected to their user profile
Â
 Scenario: Login with invalid credentials
   Given the user is on the home page of the web application
   When the user enters invalid username "invalid_user" and password "invalid_password"
   And the user clicks on the login button
   Then the user should see an error message "Invalid credentials. Please try again."
The interesting thing here is how this text, knows what test code to execute. And here's how it happens. A separate Steps.cs class is created that has a special Binding. This is how the mapping from text to a specific method happens. Here's a quick example:
[Binding]
public class LoginSteps
{
   private readonly IWebDriver _driver;
   public LoginSteps(IWebDriver driver)
   {
       _driver = driver;
   }
   [Given(@"the user is on the home page of the web application")]
   public void GivenTheUserIsOnTheHomePage()
   {
       _driver.Navigate().GoToUrl("https://example.com");
   }
   [When(@"the user enters valid username (.*) and pasword (.*)")]
   public void WhenTheUserEntersUsernameAndPasswordFields(string username, string password)
   {
   }
   [When(@"the user clicks on the login button")]
   public void WhenTheUserClicksLoginButton()
   {
   }
Â
   [Then(@"the user should be redirected to their user profile")]
   public void ThenTheUserShouldBeRedirectedToTheitUserProfile()
   {
       Assert.IsTrue(_driver.FindElements(By.CssSelector(".login-page")).Any());
   }
}
Our scenarios are divided into categories. Usually these are different modules of the system. Let's take the user creation module as an example. In this category we again have a division of scenarios for example - create user, edit existing user, view and delete. We aim for a scenario to test exactly a specific functionality. For example, if we were to test editing or deleting a user, our test would not first create the user and then edit it. The test will prepare data for that user in advance, creating it directly in the database. This strategy allows us to directly test the edit/delete functionality without having to go through the process of creating the user through the system. If for some reason the create functionality doesn't work, we won't get to the edit at all and so the edit test won't run either, so we aim to split the responsibilities.
As mentioned before, our tests can pour the data directly into the database. And here we want to talk a little bit about the environment in which the tests are run and how it's organized, because this is a very important role in order to run the tests successfully every time. We have a separate site whose role is only to run tests there. This means a separate Back End, Front End and Database. Many software engineers run tests against production environments, which is a very bad practice. By having a separate environment, we have the freedom to test at any time without worrying about the data in the database. Every time we start the testing process, we start with a new database into which we pour data that is specially prepared for the tests. This keeps the data up to date with the business logic of the application.
An important part of testing is also producing good documentation to show us results whether positive or negative. For this purpose we use LivingDoc's documentation, part of SpecFlow. This is also the document that can be used not only by software engineers but also by business customers as everything is in plain language.
We have combined all these processes that we mentioned into one Pipeline that runs in TeamCity (CI/CD). Most of our builds are there as well. We have the ability to run the tests before the application deploys, as well as standalone.
TeamCity provides us with handy tools, through which we have created a whole separate build just for tests - these are steps that are executed sequentially. Here are some of our steps:
preparing the database
building and running the tests
retrying failed tests
generating documentation with results.
After executing the build, we get the results which are hosted in AWS S3 as a static site so we can monitor the tests at any time. Testing is essential to ensure the high quality of the software product and to ensure that it meets user requirements and expectations. Neglecting testing can lead to a number of problems, so it is essential to devote sufficient attention and resources to the implementation of software product testing. Testing not only ensures the quality of the product but also helps in its successful implementation and meeting the needs of the users.
Amexis Team
Comments