Issues with JBehave Tests - muymoo/openmrs-core GitHub Wiki

Issue #1: Tests are dependent on one another

Details/Example: The story EditUserPassword depends on having a user 'John' that already exists, which I don't have until I run the story CreateAUser. There is also no story to delete a user.

Potential Solution(s): Isolation. Have each story be self-sufficient, or in other words, create the data it needs. This could result in BDD tests that are very large, when the 'real' part of them is actually fairly small. To keep stories small and to the point, would require having test data that already exists in the database.

Issue #2: Tests run in alphabetical order

Details: The tests are run in alphabetical order, thus if the tests are dependent on other stories running first (which they should not be reliant, but be isolated in nature), but won't execute that way due to this problem, then you need to apply some naming scheme or name the story in a way that it is run after the stories it depends on.

Potential Solution(s): The JBehave website talks about using scenario meta parameters to specify which stories need to be executed and which to ignore; this was not investigated further.

Issue #N: Create An Encounter can't be run

Details: The story throws a database exception because of a database constraint violation. Because we are not the original developers of OpenMRS, to investigate and resolve this issue just to get this one story running does not provide high ROI in terms of learning about BDD.

Story:

    Scenario: Create an encounter

    GivenStories: org/openmrs/stories/go_to_admin_page.story

    When I click on the Manage Providers link
    And I click on the Add Provider link
    And I enter identifier, Attending Nurse
    And I click on the button Save
    Then the provider should be saved
    
    When I click on the Administration link
    And I click on the Manage Encounters link
    And I click on the Add Encounter link
    And I enter Robert Clive, Attending Nurse, Unknown Location, 10/20/2014 00:00, Unknown
    And I save the encounter
    Then the encounter should be saved
    
    When I click on the Admin link
    And I click on the Manage Providers link
    And I enter Attending Nurse as provider name
    When I select identifier from provider search results
    And I enter retiring the provider as retired reason
    And I click on the button Retire
    Then the provider should be retired

CreateEncounterSteps.java When step was modified to comment out some code and replace it with simpler code to perform the action:

@When("I enter $name, $provider, $location, $date, $providerRole")
	public void enterDetails(String name, String provider, String location, String date, String providerRole) throws InterruptedException {
		Thread.sleep(2000);
        type(name, into(textbox().with(attribute("id", equalTo("patientId_id_selection")))));
        //String autoCompleteXPath = "//ul[@class='ui-autocomplete ui-menu ui-widget ui-widget-content ui-menu-item ui-corner-all']";
        //waitFor(finderByXpath(autoCompleteXPath));
        //clickOn(finderByXpath(autoCompleteXPath));
        WebElement patientSelection = driver.findElement(By.id("patientId_id_selection"));
        patientSelection.sendKeys(Keys.TAB);
        
        selectFrom(location, "location");
        type(date, into(textbox().with(attribute("name", equalTo("encounterDatetime")))));
        clickOn(textbox().with(attribute("name", equalTo("encounterDatetime"))));
        //getWebDriver().findElement(By.id("addProviderButton")).click();
        selectFrom(providerRole, "roleIds[0]");
        type(provider, into(textbox().with(attribute("id", equalTo("providers[0]")))));
        WebElement providerElement = driver.findElement(By.id("providers[0]"));
        providerElement.sendKeys(Keys.TAB);
	}

Requirements:

  • a Patient named Robert Clive to already exist in the database

Issue:

  • when it reaches the step 'And I save the encounter', an exception is thrown.

      An Internal Error has Occurred
      org.hibernate.exception.ConstraintViolationException
      
      could not insert: [org.openmrs.Encounter]
      
      
      
      Consult the help document.
      Contact your friendly neighborhood administrator if it cannot be resolved.
      
      Hide Stack Trace
      org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
      org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
      org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:64)
      org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2345)
      org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2852)
      org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
      org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
      org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:320)
      org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:203)
      org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:129)
      org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId        (DefaultSaveOrUpdateEventListener.java:210)
      org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
      org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
      org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
      org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:685)
      org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
      org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:673)
      org.openmrs.api.db.hibernate.HibernateEncounterDAO.saveEncounter(HibernateEncounterDAO.java:82)
      org.openmrs.api.impl.EncounterServiceImpl.saveEncounter(EncounterServiceImpl.java:195)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      java.lang.reflect.Method.invoke(Method.java:606)
      org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
      org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint        (ReflectiveMethodInvocation.java:183)
      org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
      org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
      org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
      org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
      org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
      com.sun.proxy.$Proxy55.saveEncounter(Unknown Source)
      sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      java.lang.reflect.Method.invoke(Method.java:606)
      org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
      org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint        (ReflectiveMethodInvocation.java:183)
      org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
      org.openmrs.aop.LoggingAdvice.invoke(LoggingAdvice.java:125)
      org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:51)
      org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:51)
      org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
      org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
      com.sun.proxy.$Proxy56.saveEncounter(Unknown Source)
      org.openmrs.web.controller.encounter.EncounterFormController.onSubmit(EncounterFormController.java:210)
      org.springframework.web.servlet.mvc.SimpleFormController.processFormSubmission(SimpleFormController.java:272)
      org.openmrs.web.controller.encounter.EncounterFormController.processFormSubmission(EncounterFormController.java:171)
      org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:268)
      org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
      org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
      org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
      org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
      org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
      org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:643)
      org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
      javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.openmrs.module.web.filter.ForcePasswordChangeFilter.doFilter(ForcePasswordChangeFilter.java:65)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.openmrs.module.web.filter.ModuleFilterChain.doFilter(ModuleFilterChain.java:76)
      org.openmrs.module.web.filter.ModuleFilter.doFilter(ModuleFilter.java:58)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.openmrs.web.filter.OpenmrsFilter.doFilterInternal(OpenmrsFilter.java:113)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:230)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:109)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:109)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.openmrs.web.filter.StartupFilter.doFilter(StartupFilter.java:109)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
      org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
      org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
      org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
      org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
      org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
      org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
      org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:879)
      org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:617)
      org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1774)
      java.lang.Thread.run(Thread.java:724)
      org.openmrs.api.APIException: A user context must first be passed to setUserContext()...use Context.openSession() (and closeSession() to prevent memory leaks!) before using the API at                 org.openmrs.api.context.Context.getUserContext(Context.java:249) at         org.openmrs.api.context.Context.getAuthenticatedUser(Context.java:648) at         org.openmrs.aop.AuthorizationAdvice.before(AuthorizationAdvice.java:55) at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy62.getGlobalProperty(Unknown Source) at org.apache.jsp.WEB_002dINF.view.uncaughtException_jsp._jspService(uncaughtException_jsp.java:514) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) at javax.servlet.http.HttpServlet.service(HttpServlet.java:723) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260) at javax.servlet.http.HttpServlet.service(HttpServlet.java:723) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:438) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302) at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:238) at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:263) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1208) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:992) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:855) at javax.servlet.http.HttpServlet.service(HttpServlet.java:643) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829) at javax.servlet.http.HttpServlet.service(HttpServlet.java:723) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:230) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:438) at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374) at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302) at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:421) at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:270) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:879) at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:617) at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1774) at java.lang.Thread.run(Thread.java:724) 
    
⚠️ **GitHub.com Fallback** ⚠️