This page is little related with the wiki page https://wiki.openmrs.org/display/docs/Testing+Releases which explains about how to have a safety check during releases. 

What is BDD

            Behavior Driven Design is an agile software development technique, which uses the terminology focused on behavioral aspects of the system in a profound Domain Specific Language rather than cryptic technical language which will be only understood by developers. BDD aims to bridge the gap between the different views of computer systems held by Business users and Technologists. It is deeply rooted in the success of TDD and is influenced by ideas like Domain Driven Design

            BDD relies on the use of a very specific vocabulary to minimize miscommunication and ensure that everyone – the business, developers,  testers, analysts, and managers – are not only on the same page but using the same words.

You can find more details on BDD in the following links

Wikipedia - http://en.wikipedia.org/wiki/Behavior_Driven_Development

Why do we need BDD

            BDD itself enforces us to write scripted browser tests where the functionality can be tested as a feature. Running the scripted browser tests on regular basis will help us in finding defects on functional flow of the web application.

More details around why we need BDD can be found in the following links

Dan North blog - http://dannorth.net/introducing-bdd/

Infoq presentation - http://www.infoq.com/presentations/bdd-dan-north

How to write BDD tests

            Irrespective of any language/framework, BDD tests will follow similar pattern.  We will have set of stories which are written in the format of [Given, When, Then]. These stories are mapped to appropriate steps(original test code is written in steps).

GivenStories: org/openmrs/stories/go_to_admin_page.story

Given I am on Admin page
When I click on the Advanced Settings link
Then take me to Advanced Settings Page with Advanced Settings as heading

When I type Test1 as name
When I type Test2 as value

And I click on Save button
Then display message Global properties saved

   How to write BDD tests in the context of OpenMRS

             OpenMRS uses a  Jbehave as the BDD tool to write Behavior driven tests. All the BDD tests are written under the module by name release-tests.
  Writing and executing a story

            All the OpenMRS releases post 1.9  can use Jbehave tests. Lets start with a simple example of writing a story to login to the OpenMRS website.  You can see the below code in OpenMRS core at “trunk/release-test/src/main/resources/org/openmrs/stories/login_to_website.story”

You need to write a story, which is nothing but some textual representation of the functional feature you are about to test. So, in the example of login_to_website.story, we are testing whether user is able to login into the website.

Given I am on the login page of OpenMRS with url http://localhost:8080/openmrs

When I enter username and password as stored in system properties as openmrs_username and openmrs_password and click the 'Log In' button

Then take me to the Home screen and display welcome message for user Super

Jbehave automatically matches the textual story filename to the appropriate java class. In this context name of the java class Jbehave auto matches is LoginToWebsite.java . This java file in turn calls another java file with name LoginSteps.java. This steps file have functions with annotation of @Given, @And/@When , @Then.  Jbehave uses a regex pattern to auto match .story file features to one of the annotations in Steps file.

Ex: The feature “Given I am on the login page of OpenMRS with url http://localhost:8080/openmrs” is matched with method onLoginPage(String url) which have the annotation “@Given("I am on the login page of OpenMRS with url $url")” . We can see that “$url”  is parameterized and sent as an argument to the  onLoginPage(String url).

 Assuming we are already running an OpenMRS webserver at 8080 port, when  running the above test, Jbehave will by default launch the firefox browser and hits the specified url and do the required operations specified in the .story file.

Jbehave uses Webdriver in the background to launch the browser and run the scripted tests.  Webdriver provides lots of hooks to interact with browser using java api. Ex: Interacting with HTML DOM, interacting with specific element on the browser using xpath, using the ajax elements on the browser.

How to execute BDD tests in OpenMRS Core

                                     From here onwards I will be using the term release-test for BDD tests. In the context of OpenMRS, release tests can be run in four different ways under four different maven profiles. Each of these profiles have there own importance.

Maven Profile “integration-test”:

                   It is always better to separate release test database with the development database.  Though we can run Jbheave tests over the development database, I strongly suggest running them on the release test database, so that you’ll not lose any of your dev specific data.

For the first time when you are running release-tests you can run release-tests.sh by editing the credentials as required in the file ‘release-tests.sh’ or  use the below maven command which will create the release-test database and execute the release tests. This entire process will take 10 to 15 minutes for the first time as it creates and populates the database with demo data.

mvn integration-test -P integration-test -q -DskipTests -Dmysql_username=<mysql_username> -Dmysql_password=<mysql_password> -Dmysql_port=<mysql_port> -Dtest=* -Ddatabase_name=<database_name>

The above maven command or release-tests.sh will setup a release test database with the name of the variable “openMRSVersion” configured in your pom.xml under release-tests module and then runs the tests. You can find more details in your  .OpenMRS folder under root/app data folders.                     

Maven Profile “smoke-test”:

                             This maven profile runs the specified tests on the release-test database, provided that you’ve already created the release-test database using the profile “integration-test”.  When you use this profile to run a test, it start the server by connecting it to the release-test database and executes the specified tests. Make sure you've ran integration-test profile before you ran smoke-test because the integration-test profile will help in establishing the database and corresponding properties file.

Maven command for the same is as follows.

mvn integration-test -P smoke-test -Dtest=LoginToWebsite  -DskipTests
mvn integration-test -P smoke-test -Dtest=*  -DskipTests

Maven Profile “start-test-server”:

                                  Profile “smoke-test” will start the server every time you run the tests. It takes couple of minutes to start the server.  To make the development of the test stories fast, we can use the profile “start-test-server”.  This profile will start the application on port 8080 by connecting to release-test database.

Use the following command under release-tests folder.

mvn -P start-test-server jetty:run-exploded -DskipTests

One other major advantage of running the test server is, when we have any new migrations to be run on the release tests database, current automation framework will not execute these migrations by default. You need to manually execute the migrations by starting the test server and login into the OpenMRS website.

Maven Profile “smoke-test-without-server”:

                                     This maven profile comes very handy when you are  developing the test stories. This profile will run the jbehave tests assuming that server is already started. So, the prerequisite to use this command is, OpenMRS application is running at the port 8080.  So it is always advisable during the development of the stories to run the test server using the profile “start-test-server” and leave it running. Later we can use the profile “smoke-test-without-server” during the development of the stories.

mvn integration-test -P smoke-test-without-server -Dtest=*  -DskipTests

How to write and Execute BDD tests in OpenMRS modules

                                         To write release tests (jbehave) in modules, you need to create a module by name release-tests.  Currently there is no automated way to create the release-test pom.xml with correct dependencies. For now, we can use the base version of htmlformentry modules pom.xml file and make the necessary changes. In the near future we should be able to create a maven archetype, which will create the appropriate pom.xml for release tests.

Two main properties, which we need to configure appropriately in the release-test pom.xml, are “openMRSVersion” and “openMRSReleaseTestVersion”. 

“openMRSVersion” will help to download the appropriate version of OpenMRS, on top of which the module will be deployed. “openMRSReleaseTestVersion” will help to download the appropriate version of release-tests jar to reuse most of the release test infrastructure.

Create appropriate package structure, which will comply with the OpenMRS core release-tests.

 


 

For more examples on how to write release tests in OpenMRS modules please look at htmlformentry module in github.

Three main maven profiles under release test maven module are

Maven Profile “integration-test”:

                                          This is very similar to the “integration-test” profile of OpenMRS core.  Using this profile in the OpenMRS module will download the appropriate version of OpenMRS, creates the release test database, install the current module and starts the jetty web server.  You can specify the OpenMRS version you want to use with this module using the parameter “openMRSVersion”.  Command will look as follows.

mvn integration-test  -p integration-test -DskipTests  -Dtest=* -DopenMRSVersion=<OpenMRS_Version_you_want_to_install_the_current_module>   -Ddatabase_user_name=<mysql_username> -Ddatabase_root_password=<mysql_password> -Dmysql_port=<mysqlport>

You can also run the release-test.sh script , under release-tests module by updating the details as required.

If you have already created the release-test database for some specific openmrs version using OpenMRS core, you need not run the profile integration-test again under openmrs-module.

Ex:  If you have run the integration-test profile under OpenMRS core for openmrs version 1.10.0-SNAPSHOT, you need not run the integration-test again under the openmrs module release tests.  Any ways it will not create/update/destroy the database if it is already existing.

Maven Profile “smoke-test”:

                                          This profile is very similar to “somke-test” profile of OpenMRS core.  Provided that the release-test database is already created, it will start the OpenMRS core web application by installing the current module. Later all the Jbehave tests will be executed. Command for the same looks as follows.

mvn integration-test -DskipTests -P smoke-test -Dtest='*'

Maven Profile “start-test-server”:

                                           This profile starts the openmrs application, installs the current module into the server and connects to release test database. This profile comes very handy during the development of the stories (release tests), as you need not start the server each and every time you want to test your story changes.  As the current implementation doesn’t support auto run of the migrations, when ever you have new set of migrations, you need to run them manually on the release test database using this profile. 

mvn integration-test -DskipTests -P start-test-server

Next Steps

There’s huge room for improvement in many areas of release-test infrastructure. Below are some of the areas which needs immediate concentration.