We are in the process of evolving our unit testing conventions, please read this section carefully so you do not get confused when writing tests yourself.
The transition is currently discussed here https://talk.openmrs.org/t/rethink-unit-test-style-to-remove-duplication/10200
Our unit tests are written using the testing framework JUnit
We have been changing the way we write our tests twice in the past which you can see in the code of the OpenMRS core and maybe also some OpenMRS modules.
It started with tests looking like this
with the org.openmrs.test.Verifies annotation
And moved on to
where verifies was an annotation in the javadoc stating what was tested.
Both styles had in common that you where writing a sentence about what case you where trying to test using the should annotation in an interface or above a concrete method
and then use the IDE plugin - Generate Test Case Plugin to generate the test boilerplate (javadoc, test annotation and test method with no test implemented) in a test class.
The reason why these styles came into existence were, back then
So what is the new style?
We encourage you to use Test Driven Development but you are free to use the development methodology you want to use.
The only thing we do not negotiate is tests. We want to write code to save lives. It is out of question that new contributions come without tests.
These are the basic requirements:
public int add(int a, int b): you pass in two values and expect the method to return you the sum, assert (check) that the return value is as you expected
null, an empty
First start by importing the code templates we provide with the OpenMRS core repository (Eclipse or IntelliJ) which will make it easy for you to insert tests according to our conventions and save you from typing a lot.
Then read on the next sections on how to name test methods, what to test and have a look at the example code.
We want to help newcomers with simple rules with good explanations as to why we think these rules (be it naming or testing) are good. These rules also help a community of many to write code in a similar way which helps when reading code someone else wrote. However, the conventions should only be seen as a guideline not as a law and they will also evolve, what we think of as a good approach today might not be so good tomorrow. Please speak up, give us your input, help us to improve the way we work
We follow a naming approach described by Dan North as Behavior Driven Development, he states: "What to call your test is easy – it’s a sentence describing the next behaviour in which you are interested."
We name our test methods in this scheme:
where the keyword
should is followed by a camel cased sentence of what you expect the method you are testing to do or return.
Lets say you want to write a test that asserts that
public Patient savePatient(Patient patient)
NullPointerException when called with
public User authenticate(String username, String password)
authenticates a user if the given user and password are correct.
These are the test method names testing
see how this reads nicely about what behavior is expected and the case of failure is simply shown by
Not and the parameter that caused the failure highlighted with
Assertions are checks that what you expect to happen is happening. At least one has to be present in every one of your tests. The testing framework JUnit already comes with a set of assertions which we extend with the assertion library hamcrest. It helps make these checks read more natural and gives better outputs in case the tests fail.
The getters and setters do not have to be tested unless they are doing something more than getting/setting an internal variable
Like for example
All methods in the ___Service classes should be testing with proper input, improper input, and improper data in between.
Most database methods are testing in the process of testing the aforementioned Service Layer Testing. However, some database layer methods are not exposed through Service layer methods. These methods need to be tested.
All set and get methods in the editor require testing.
See DrugEditorTest.java http:--dev.openmrs.org-browser-openmrs-trunk-test-api-org-openmrs-test-propertyeditor-DrugEditorTest.java
Make use of JUnits
@Before to setup variables (like for example
encounter) that you need in multiple tests so that your tests ideally only contain a few changes to the variables that make this test special. Also assert the exceptions you throw using JUnits