• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
Sheriffs:
  • Knute Snortum
  • Junilu Lacar
  • paul wheaton
Saloon Keepers:
  • Ganesh Patekar
  • Frits Walraven
  • Tim Moores
  • Ron McLeod
  • Carey Brown
Bartenders:
  • Stephan van Hulst
  • salvin francis
  • Tim Holloway

Testing Databases using Cucumber  RSS feed

 
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am currently creating automated tests using Cucumber, and REST Assured to test REST Services in Java.

The project I am working on has multiple micro-services. Some of these API's return an XML Response, so I can use REST Assured to test these.

But, some of these services do not send back a response, instead they perform actions such as Write to a Database, Update a Database, etc.

Is it possible to write Cucumber tests to query a database, and then PASS / FAIL the Cucumber test based on that query result (i.e. If a row is returned from the SELECT statement, then the test PASSES. Else, the test FAILS).


Thanks a lot for any help!
 
Sheriff
Posts: 4573
286
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cucumber tests usually have a slightly larger scope when it comes to defining your unit of test. What you describe there would be more like a unit test that you might have written within that module, whereas what you're describing is a behaviour test observed from outside the module.

Consider writing your test to interact with the service only through the API and identify a desired observed behaviour. For example: You make a service call that returns a response that is based on some state value within the service. You then make a service call that alters that state (writes to the database). Then make a second call to the first service and verify that the response has changed according to the change in state. That way you are verifying the behaviour of the service through its published API without having to depend on its implementation details such as the database.

Make sense?
 
Mark D Anthony
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Cooke wrote:Cucumber tests usually have a slightly larger scope when it comes to defining your unit of test. What you describe there would be more like a unit test that you might have written within that module, whereas what you're describing is a behaviour test observed from outside the module.

Consider writing your test to interact with the service only through the API and identify a desired observed behaviour. For example: You make a service call that returns a response that is based on some state value within the service. You then make a service call that alters that state (writes to the database). Then make a second call to the first service and verify that the response has changed according to the change in state. That way you are verifying the behaviour of the service through its published API without having to depend on its implementation details such as the database.

Make sense?



When you say a

desired observed behaviour

, where would this behaviour occur?
Is it to do with the response? If so, the only behaviour returned is a Status 200 if the post is successful.

We want to test service-by-service, and one of the services only posts to the database. I'm not sure how else to test it besides querying the DB.
 
Tim Cooke
Sheriff
Posts: 4573
286
Clojure IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Do you have another service that reads from that database in order to do its job? Does that service provide a response with data who's values are dependant on the database state? If the answer is no, then your database serves no purpose at all, so I'm going to assume the answer is yes and it's just a case of finding it.
 
Sheriff
Posts: 12748
210
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Refer to the Testing Pyramid -- what you're testing would be in the integration or UI level. Unit tests should cover what happens between the service and the persistence layer. There's no need to cover that again in end-to-end tests, in my opinion.

Here's what I would do:

1. Determine all the possible responses the service would give back to client.  For example, maybe you have 200 for success, 201 for new item created, 404 for item not found, whatever.

2. Create mocks for the persistence layer such that each mock will mimic the behavior for one of the response cases.

3. You would have scenarios like this:

In the step definitions, I would just wire the appropriate persistence layer mock object to the service under test, then call the service with correspondingly appropriate request parameters.

To me, this tests the real behavior of the service object without having to be concerned about whether or not something was actually written to the database. You're testing the service, not the persistence layer, right?
   
 
Junilu Lacar
Sheriff
Posts: 12748
210
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you can't do what I described above, then some refactoring to separate concerns is probably in order. Tight coupling between layers makes having a proper test pyramid difficult. In extreme cases, the pyramid is inverted, with the bulk of the tests being UI and end-to-end integration tests rather and very few unit tests. This is because the tight coupling makes it difficult to write many unit tests.

I have seen my fair share of extreme cases and the only way to make things better is to spend a lot of time refactoring to break dependencies and loosen coupling between layers.
 
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cucumber does not know anything about databases testing, the implementation is up to you. The solution is to add a JDBC driver  for your database to your project CLASSPATH and develop the code which will check presence (or absence) of values in the database using Java SQL API.

Pass/fail criteria could be set using Assert class of underlying xUnit library like JUnit or TestNG like:



This will cause the relevant step and feature failures in case of mismatch.

You might also want to reconsider your toolchain as there is a solution which supports both APIs and Databases testing: check out APIs testing
  • [url=https://en.wikipedia.org/wiki/Load_testing]Load testing of both tiers either separately or at the same time so you will be able to check your application performance

  •  
    Junilu Lacar
    Sheriff
    Posts: 12748
    210
    Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ah... I see that I had my bias blinders on again.

    I wouldn't test the database using Cucumber. I guess my brain couldn't process that idea as a valid one so it went for the thing that made more sense.

    Cucumber is a tool that's meant to support Behavior-Driven Development. Testing the persistence layer is something I'd do as fast-running unit tests or slow-running integration tests as a second phase of the build, depending on which part of the persistence layer I'm testing.

    Here's a useful article by Scott Ambler: http://www.agiledata.org/essays/databaseTesting.html

    Also search for how to test the database
     
    With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!