Turn your manual testers into automation experts Request a DemoStart testRigor Free

OpenMRS Testing

What is OpenMRS?

OpenMRS is the world’s leading open-source electronic medical records platform. Initially designed to support HIV care, it later expanded to cover the needs of HIV patients suffering from other health conditions, such as malaria, tuberculosis, maternal health, and primary care needs, among other medical issues. For more details about the system, refer here.

OpenMRS technical aspects

OpenMRS is a Java-based software and a web-based electronic medical record. It features a robust and flexible data model with an API layer, enabling developers to understand Java objects and read, update, or save them. This layer itself can be used as a standalone application.

Some of the technologies used in the system include:
  • Apache Maven and Tomcat
  • Bamboo
  • Concept dictionary
  • Core (OpenMRS API and core modules)
  • Eclipse/IntelliJ
  • GitHub
  • Hibernate
  • Spring framework

OpenMRS testing

Here're the primary types of testing you can perform for your OpenMRS applications:

Unit testing

Unit testing is performed to validate that individual code units - such as a single class, function, or method - are working as expected.

To conduct unit-level testing, consider the following:
  • Each test should validate a single piece of logical code.
  • The names of methods should be self-explanatory.
  • Methods should have assertions to validate the expected outcome.
Sample unit test code:
package org.openmrs.module.sampletest;

import org.junit.Assert;
import org.junit.Test;
import org.openmrs.module.samplemodule.SampleModuleObject;

public class SampleModuleObjectTest {

  @Test
  public void shouldExamineFeatureXofSampleObject() throws Exception {
    // Create a new instance of SampleModuleObject
    SampleModuleObject sampleObject = new SampleModuleObject("SampleValue");

    // Get the value of the object
    String objectValue = sampleObject.getValue();

    // Assert that the value is as expected
    Assert.assertEquals("SampleValue", objectValue);
  }
}

In this example, the test is checking if the SampleModuleObject is storing and returning the correct value. The test creates an instance of SampleModuleObject with a sample value, retrieves the value, and asserts that it is equal to the expected value.

Integration testing

Integration testing is a type of software testing that focuses on evaluating the combined functionality of individual modules or components within an application. Its main objective is to identify defects and issues that may arise when different modules interact, ensuring that data flows correctly between them and their combined functionality performs as expected. This testing level helps confirm that the application's various parts work together seamlessly, improving the overall system's reliability and stability.

  • Integration testing can be performed at the database layer
  • Integration testing can be performed at the user interface level (which can also be part of E2E testing)
Sample code of integration test at database layer:
package org.openmrs.module.sampletest;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openmrs.api.context.Context;
import org.openmrs.module.samplemodule.api.SampleModuleService;
import org.openmrs.module.samplemodule.SampleModuleObject;
import org.openmrs.test.BaseModuleContextSensitiveTest;

public class SampleModuleObjectDatabaseIntegrationTest extends BaseModuleContextSensitiveTest {

  private SampleModuleService sampleModuleService;

  @Before
  public void setup() {
    sampleModuleService = Context.getService(SampleModuleService.class);
  }

  @Test
  public void shouldSaveAndRetrieveSampleModuleObject() throws Exception {
    // Create a new instance of SampleModuleObject
    SampleModuleObject sampleObject = new SampleModuleObject("SampleValue");

    // Save the object to the database
    SampleModuleObject savedObject = sampleModuleService.saveSampleModuleObject(sampleObject);

    // Retrieve the object from the database using its ID
    SampleModuleObject retrievedObject = sampleModuleService.getSampleModuleObject(savedObject.getId());

    // Assert that the saved and retrieved objects are the same
    Assert.assertEquals(savedObject, retrievedObject);
  }
}

In this example, the test extends BaseModuleContextSensitiveTest, which provides the necessary setup for integration testing with the OpenMRS database. The test checks whether the SampleModuleObject can be saved and retrieved from the database using the SampleModuleService. It creates a new instance of SampleModuleObject, saves it to the database, retrieves it using its ID, and asserts that the saved and retrieved objects are the same.

End-to-end testing

End-to-end (E2E) or system testing is a comprehensive testing approach that evaluates the entire application, including its integrated modules, components, dependencies, and interfaces, to ensure seamless functionality and interaction from start to finish. The primary objective of E2E testing is to validate that the application performs as expected from the user's perspective, considering various real-world scenarios and conditions. This type of testing helps identify any issues that may arise during user interaction, ensuring that the application meets its requirements, delivers a positive user experience, and functions reliably in a production environment.

You can create automated end-to-end tests using the following ways:

Cypress

Cypress is a NodeJS-based front-end Test Automation Framework for automating modern web applications. Unlike other automation tools, the Cypress engine directly interacts with the browser, and there is no proxy server between the code and the client. Basically, in Cypress, the browser itself executes the code, and there is a direct interaction between Cypress and the DOM where the browser behavior can be modified at runtime. Refer here.

Selenium

To conduct end-to-end testing for OpenMRS, a Behavior-Driven Development (BDD) framework called QAFramework is employed, which is accessible on GitHub. This framework incorporates Cucumber, which utilizes Gherkin for BDD implementation. For a comprehensive overview of Cucumber and BDD, you can refer to the provided resources.

To access the source code and contribute to automating features, it is necessary to first clone the QAFramework repository to your local machine using Git Bash.

After successful cloning, we can perform test automation of end-to-end features. We will take an example: "Login to OpenMRS web application and validate login successfully by checking all modules available in the location page Inpatient Ward".

The sample feature file will be as below:
Feature: User Login
Background:
  Given user visits openMRS login page
Scenario: validate successful login
  When user enters "admin" username
  And user enters "Admin123" Password
  And user selects "Inpatient ward" Login location
  And user logs in
  And user verifies modules available on home page after login as Admin
  And user verifies modules available on home page after login as Clerk
  And user verifies modules available on home page after login as Doctor
  And user verifies modules available on home page after login as Nurse
  And user Closes browser
The sample step definition file would be as below:
public class loginandvalidate extends Steps {
  @When("user enters {string} username")
  public void userEntersUsername(String username) {
    driver.findElement(By.id("username")).sendKeys(username);
  }
  @And("user enters {string} Password")
  public void userEntersPassword(String passwd) {
    driver.findElement(By.id("passwd")).sendKeys(passwd);
  }
  @And("user selects {string} Login location")
  public void userSelectsLoginLocation(String location) {
    driver.findElement(By.cssSelector("#sessionloaction li")).click();
  }
  @And("user logs in")
  public void userLogsIn() {
    driver.findElement(By.id("loginButton")).click();
  }
  @And("user verifies modules available on home page after login as Admin")
  public void userVerifiesModulesAvailableOnHomePageAfterLoginAsAdmin() {
    assertTrue(homePage.isFindAPatientAppPresent());
    assertTrue(homePage.isActiveVisitAppPresent());
    assertTrue(homePage.isAppointmentSchedulingAppPresent());
    assertTrue(homePage.isCaptureVitalAppsPresent());
    assertTrue(homePage.isRegisterPatientCustomizedForRefAppPresent());
    assertTrue(homePage.isDataManagementAppPresent());
    assertTrue(homePage.isConfigureMetadataAppPresent());
    assertTrue(homePage.isSytemAdministrationAppPresent());
  }
}

And there would be a sample test runner Java file that helps to run the test case. The above is a basic sample example of an end-to-end test that uses Selenium.

testRigor

An innovative no-code tool that is extremely easy to implement, writing tests takes about 15x faster than with Selenium, and the test maintenance issue is virtually eliminated. Yes, that is testRigor - an AI-driven tool that makes end-to-end testing a breeze.

Unlike other tools on the market, there are no step definition files or other underlying code in testRigor. The tests you write in plain English commands are the tests that get executed by the system. This makes it extremely straightforward for the entire team to comprehend and collaborate.

Below is the sample test of testRigor with the same example "Login to OpenMRS web application and validate login is successful by checking all modules available in the location page Inpatient Ward".

//login into location-Inpatient Ward
enter "admin" into "Enter your username"
enter "******" into "Enter your password"
click on "Inpatient ward"
press "Log In"
check that page contains "Logged in as super user (admin) at Inpatient Ward."

//check modules
check that page contains "Find Patient Record"
check that page contains "Active Visits"
check that page contains "Register a patient"
check that page contains "Capture vitals"
check that page contains "Appointment scheduling"
check that page contains "Reports"
check that page contains "Data management"
check that page contains "Configure Metadata"
check that page contains "System Administration"

Impressive, right? This is just a sneak peek into what testRigor is capable of. We encourage you to look into the documentation page to get a better idea of all the features that your team can test. And the best part is that tests are so stable that some companies use testRigor for monitoring!

Conclusion

In conclusion, OpenMRS testing is crucial to ensure the platform's reliability, stability, and overall quality. By employing different testing levels - unit, integration, and end-to-end testing - developers can identify and address issues at various stages of the application's development. Utilizing the right tools enables efficient and effective testing, ultimately resulting in a robust and user-friendly electronic medical records system that caters to the diverse needs of healthcare providers and patients worldwide.