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.
- Apache Maven and Tomcat
- Bamboo
- Concept dictionary
- Core (OpenMRS API and core modules)
- Eclipse/IntelliJ
- GitHub
- Hibernate
- Spring framework
OpenMRS testing
Unit testing
Unit testing is performed to validate that individual code units - such as a single class, function, or method - are working as expected.
- 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.
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)
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".
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
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.